bristol-0.60.11/0000755000175000017500000000000012100257366010340 500000000000000bristol-0.60.11/config.guess0000755000175000017500000012743212073601233012604 00000000000000#! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # 2011, 2012 Free Software Foundation, Inc. timestamp='2012-02-10' # 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 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, 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. # Originally written by Per Bothner. Please send patches (context # diff format) to and include a ChangeLog # entry. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -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 (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 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 trap 'exit 1' 1 2 15 # 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. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { 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) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; 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 ; set_cc_for_build= ;' # 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) >/dev/null 2>&1 ; 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 # 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". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-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. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $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 # 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/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; *:SolidBSD:*:*) echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; alpha:OSF1:*:*) 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. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm:riscos:*:*|arm:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) echo i386-pc-auroraux${UNAME_RELEASE} exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval $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 [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH="x86_64" fi fi echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; 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. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; 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'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; 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) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # 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:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $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; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $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 echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *: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 [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 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 [ -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 [ "${HP_ARCH}" = "" ]; then eval $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 [ ${HP_ARCH} = "hppa2.0w" ] then eval $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 echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $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; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; 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*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; 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:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; 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/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 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/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case ${UNAME_PROCESSOR} in amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; i*:MSYS*:*) echo ${UNAME_MACHINE}-pc-msys exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; *:Interix*:*) case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; authenticamd | genuineintel | EM64T) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; IA64) echo ia64-unknown-interix${UNAME_RELEASE} exit ;; esac ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; 8664:Windows_NT:*) echo x86_64-pc-mks exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; aarch64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` 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="libc1" ; else LIBC="" ; fi echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then echo ${UNAME_MACHINE}-unknown-linux-gnu else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then echo ${UNAME_MACHINE}-unknown-linux-gnueabi else echo ${UNAME_MACHINE}-unknown-linux-gnueabihf fi fi exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; cris:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-gnu exit ;; crisv32:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-gnu exit ;; frv:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; hexagon:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; i*86:Linux:*:*) LIBC=gnu eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __dietlibc__ LIBC=dietlibc #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` echo "${UNAME_MACHINE}-pc-linux-${LIBC}" exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=${UNAME_MACHINE}el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=${UNAME_MACHINE} #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; or32:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; padre:Linux:*:*) echo sparc-unknown-linux-gnu exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-gnu exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-gnu ;; PA8*) echo hppa2.0-unknown-linux-gnu ;; *) echo hppa-unknown-linux-gnu ;; esac exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-gnu exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-gnu exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; tile*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-gnu exit ;; x86_64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; 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. echo i386-sequent-sysv4 exit ;; 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. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; 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 echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; 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 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; 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 configury will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; 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*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; SX-7:SUPER-UX:*:*) echo sx7-nec-superux${UNAME_RELEASE} exit ;; SX-8:SUPER-UX:*:*) echo sx8-nec-superux${UNAME_RELEASE} exit ;; SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown case $UNAME_PROCESSOR in i386) eval $set_cc_for_build if [ "$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 UNAME_PROCESSOR="x86_64" fi fi ;; unknown) UNAME_PROCESSOR=powerpc ;; esac echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NEO-?:NONSTOP_KERNEL:*:*) echo neo-tandem-nsk${UNAME_RELEASE} exit ;; NSE-?:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *: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 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; i*86:AROS:*:*) echo ${UNAME_MACHINE}-pc-aros exit ;; x86_64:VMkernel:*:*) echo ${UNAME_MACHINE}-unknown-esx exit ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 eval $set_cc_for_build cat >$dummy.c < # include #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 (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix\n"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #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 printf ("vax-dec-ultrix\n"); exit (0); # 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; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; c34*) echo c34-convex-bsd exit ;; c38*) echo c38-convex-bsd exit ;; c4*) echo c4-convex-bsd exit ;; esac fi cat >&2 < in order to provide the needed information to handle your system. config.guess timestamp = $timestamp uname -m = `(uname -m) 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 exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: bristol-0.60.11/ChangeLog0000755000175000017500000050617312100170025012033 00000000000000 0.60.11 23 Jan 2013 Maintenance release This release incorporates changes to the build process submittedd to the project by Philippe Didier and the Mageia packers team. It has no new features, it is intended to improve compatability with different build processes. 0.60.10 27 Apr 2012 Maintenance release Voices are given a small random detune. Pitchbend would lose this delta which put the voices back in tune as soon as the pitchwheel moved. That altered the width of the sound so added in the code necessary to maintain the delta values. audiothread.c Added in 'hi-res' skins for some of the emulators. This changes the rendering to include a vector graphic stage where text and some line are rendered. It makes the images far more scalable, ie, you can fullscreen them now without getting pixel smashing. Retuned the Mini filters. Fixed fastest attack rate to 0.5ms, the envelopes were getting very 'ticky'. Increased the default Mini release stage to similar values as note off were ticky unless Release was selected. Jack MIDI configurations would only respond correctly on channel #1. Any other channel would have the synth respond to the Jack MIDI messages but lose tracking from the GUI, lose CC into the GUI as the channel identifiers could be lost in the internal messaging. 0.60.9 25 Oct 2011 Maintenance release, fanning linear potentiometers Reworked the envelope to default linear attack and with gentler control of the decay/release times. The linear attack was a Moog thing but was not universally appreciated - it does not work very well for long attack times. Several synth manufacturers preferred the use of exponential for this and other reasons. The actual envelope code does not have linear or exponential attack as a fixed value, it can be configured by the emulator although at the moment they all just take the default setting, now linear. There is a ./configure option to have them default to exponential rather than linear: --enable-exp-attack It is now also possible to build with an alternative ADSR max ramp duration, the following will give you a maximum ramp of 30 seconds, default is 10. ./configure BRISTOL_RAMP_RATE=30 These changes were to correct an anomaly in the previous design where the actual ramp was a function of the sampling rate, hence if you step up to 96KHz or even 192KHz for the improved sound quality then the ramp times would change (now fixed). If you want to use very long attack times then exponential attack will give arguably better results, that is admittedly opinion. NOTE that these envelope changes will affect existing patches to some extent. Added code to have fanning linear pots. The further the mouse is from the axis of the pot the finer the value changes become. Resolved a error in midinote.c that broke the scala file support. A patch was posted to SFDN a long while ago now, this just rolls it into a release. MIDI Program Change events were not being filtered by channel - they were being tracked as OMNI. Applied same change to Bank Select. Have not tested all the multilayered synths, they have exceptions since some use separate memory indeces and some use combined settings. Reconfiguring the continuous controllers as things like inverse mappings were failing. The issue was that both the engine and GUI might be using the same mapping file, dual inversion negated the effect. Corrected this with only doing the mapping in the GUI but added a token called modWheel for the 'mcm' file to allow the engine to have alternative curves for the modulation wheel. The request to have an inverted modWheel requires the following: Start the engine with -tracking to prevent the GUI tracking some events. Edit mini.mcm and add in modWheel: 127 0.001 modWheel: 0 127.0 This file is emulator global, ie, to have different settings with the same synth then a user would have to configure different bristol cache variables. A better way to do this might be to have an ALSA event manager in front of the bristol emulators. Ported over some note loss fixes from the 0.70 (smartphone) stream where with excessive system load there were lost notes. This was never actually reproduced on Linux so will discuss the fix with end users. The original change resolved the issue when seen on a 600MHz ARM A8 on Maemo/N900 from Nokia and which were also tested/confirmed on Android. It concerned signalling between the note allocation code and the ADSR envelope states. The multilayered synths would lose tracking of the PitchWheel - the pitch was correctly calculated but only applied to the first bristolAudio structure in the chain. The Polysix gives click/tick at high frequencies and mods. The cause was the change from the precached buffers to recalculated buffers. The code was changed to have the buffers always calculated/cached on note events as a fix to the existing band limited oscillator code. The code change was only the prophetdco but it could be pushed into the other oscillators. The BME noise mix was all but silent, readjusted the gain settings for the mix. The Pro1 and Prophet10 saved sequencer memory was not reloaded on restart. Had to apply changes to a few different parts of the arpeggiator/sequencer code. Gain levels seemed low on the ARP 2600 and the Direct Out final stage gain left a signal that was almost inaudible. Added the option to use a memory barrier over the jack ringbuffer. The issue is that the JRB can be demonstrated to fail on ARM CPU due to them having weak memory ordering. Intel should not be affected. AMD is a marginal case. The config option is --enable-memory-barrier which defaults to no barrier since most of the installs will probably be on Intel. 0.60.8 23 Dec 2010 Maintenance release, Hammond optimisations. Made some changes to the way bristolrc is handled. If the file exists then a seach is made for two tokens, PREARGS and POSTARGS. If they don't exist then the same default behaviour takes place: all the contents are concatenated into a set of options that are inserted before all the user parameters. If either of these tokens are found then PREARGS are inserted before the user parameters and POSTARGS are appended to the whole net commandline to the GUI and engine. This gives a lot more flexibility to override default behaviour, for example: PREARGS=-count 1024 -rate 48000 POSTARGS=-jackstats -jack -multi 0 Using such contents then the command 'startBristol -mini' would be expanded to startBristol -count 1024 -rate 48000 -mini -jackstats -jack -multi 0 A part of the reason for the above change was that there were reports of issues with the ARP 2600 and period sizes less than 1024. The culprit appeared to be the -multi option, this defaulted to 4 for the 2600. Changed it to default to zero with a need to then explicitly reconfigure it. The reconfigure can now be automated in POSTARGS. The diverse Bristol front end appliations such as monoBristol provide user arguments to the startup script, the current bristolrc definitions can provide capabilities to extend how they operate as there are now pre and post arguments that encapsulate the frontend parameters. This release is noted as including hammond optimisations, these are not with respect to CPU load, rather with respect to accuracy of the emulation: Adjusted the B3 Preacher Compression code to provide a more pronounced non- linear amplification. The results are interesting/different. It mixes well with the new gearbox generated for a clean tonewheel (mostly sinewaves with no crosstalk) and a mild crosstalk gearbox with some sliced tonewheel harmonics. The control is not continuous, there are 3 stages which are selected as the rotary changes position, this would normally be represented with radiobuttons however the GUI previously only had a rotary control so this was used to prevent a big reordering of the options panel layout. The new tonewheel gearbox are in the factory shadow profiles, per default as below. To test them then copy the target gearbox to your private memories (these are the defaults, your installation may be different): source: /usr/local/share/bristol/memory/profiles/tonewheel* dest: ~/.bristol/memory/profiles/tonewheel Also made few alterations to the B3 VC algorithm changing the tap gains and LC filter values, altered the tap selections for the different 1/2/3 settings and adjusted the selector mode to reconfigure LC and phase (which work in combination) rather than the actual tapping points. More work could be done but these do now give some different characteristics where previously VC3 was the only useful setting. [Note: it would actually be quite easy to make even further improvements here by using an alternative filter algorithm into the different taps. The current one is a rooney which has weak phase modification, it is similar to the original in as much as that could only introduce about 1ms of phase change however bristol has other algorithms that would give better phase changes by frequency which would be closer to the Hammond vibra. The current code overcomes the rooney limitation by taking the phase changed filter signal (which has a phase change that is dependent on frequency) with an additional phase change that is time constant. The issue is efficiency, the rooneys are single pole and come almost for free. ffs] Reintroduced some B3 code to give contact delays for each drawbar. The delay is configured in the tonewheel file and is then a function of velocity. The tonewheel file defines the maximum sample delay before any given harmonic is activated and this delay is reduced depending on velocity. It is also possible to configure a click sample per bus out of 4 available however the author will state that none of the samples is accurate: click, thump, shelf, etc, is not an accurate emulation. Depending on which source is considered authoritative then the Hammond click may be a pure function of tonewheel position and its activation point. This code emulates that effect with the option of adding in extra effect as a combination of the tonewheel file samples and the overall click setting. Note that the 'click' level does not affect the cut in points of the harmonics, reducing the 'click' level will not affect the tick sound when a drawbar contact is finally made. The harmonics do not have a constant phase as per the original however the tonewheel file can override that to emulate the L and M series spinets. With the current code, pressing a key very slowly should result in the delays between the different busses being almost audible, an effect that reduces with velocity. The configured Click is reduced when the vibrachorus is on as is also heard on the originals. This click code has actually been available for a few years, it was removed as it affected other developments for gearbox optimisation. This optimisation was to 'post generate' the tonewheels: if a harmonic was not needed then it would never be generated. This was not condusive to busbar delays so now the decision has been taken to drop the CPU optimisation in preference of a more accurate rendition. At the same time the tonewheel damping was corrected so that, under control of the Damp option, the summed levels of any given wheel is not linear but is a function of the number of times it is tapped. It is noted here that if no click is desired, at all, then the 'preacher' algorithm should be disabled at which point notes are generated from zero point as per many of the commercial emulators. Several of the later Hammond models reduced/eliminated key click using various techniques, disabling the Preacher would give results closer to the B2XX series organs. Disabling the preacher removes the damping, busbar offsets, and all the other features of the tonewheel file. Adjusted the click code to introduce changes to the bus offset delays by key as well as velocity. The existing code used a single profile per gearbox but no two keys would have had the same contact profile as this was based on aging of the springs: the code now has semi-random delay selection. The 'semi' refers to code that will select the same offsets if the same key is sounded sequentially, this is how Jimmy Smith used to play key click with the same key - now the delays for that sequential key do not change (they will if intermediate notes are sounded which he also did and potentially the delay offsets may be prebuilt for the whole keyboard rather than calculated, ffs). The different bus delays only affect timing not the actual effect so if 'Click' is non-zero then the sample selection per bus will be constant even though the delay changes. Now, another affect of the bus delays is that if playing quickly it is possible that a note will start and stop before even all the harmonics have sounded, this is another trick of Smith when he played notes to not traverse the complete travel of the key: not all harmonics would actually make contact and this is also possible with bristol (depending on velocity, buffer size and configured bus delays). Added a -keytoggle flag, it affects GUI behaviour where a key is released when the mouse button is released. Previously the key state latched which was useful for polyphonic emulators but not necessarily for the monophonic ones. The default operation is now not to latch the keys, this option overrides the new default behaviour to give latching keys again. There were some sticky keys and note 'ticks' when using the monophonic synths with -nnp (no note preference). The polyphonic note logic could completely kill notes when overvoice and if a keyoff event occurs for a voice on the new list then some of the flags would get damaged. None of this happens with monophonic note preference or with polyphonic synths (well, the ticks may still happen if the polyphony is exceeded but get burried in the mix of multiple voices, ffs). Bug report on some emulators defaulting to only one semitone of pitchwheel depth. This turns out to be emulator aliases: the interface recognises some alias names but it could not set defaults except on exact names. Incorporated some changes to accept the known emulator aliases too. Feature request that the SID should acknowledge pitchbend wheel as well as or instead of pitchbend on the modwheel. Not a big change and the issue with the MOD wheel is that it was difficult to tune having no notch. Currently both controls can affect pitch but the modwheel can be turned on/off selectively. There was a window when the global configuration options would not be sent to the engine, a race condition. The result would be no output signal. There was another race condition in the GUI library which for now has been patched. The actual fix is a little larger but it will be left for future research. Found a bug in the MIDI handling code for NOTE_ON velocity zero being mapped to NOTE_OFF velocity 64. When the ringbuffer was introduced the check moved to the wrong side of the ringbuffer causing an endless loop at 100% CPU, for some emulators quite a lot of nasty random noise and potential system 'hang' for certain CPU configurations with RT scheduling. This had not been reported which means either people did not bother or the use of NOTE_ON velocity zero is not widely used. Release 0.60.7 had an undocumented feature, undocumented because it was not that big but it did go into the manual page. The option -jackstats will prevent bristol from attempting to find out the current jack server settings, these parameters would instead be defined with -count and -rate. This change fixes some issues with jack connections, with LADI, and makes the GUI start a bit faster as it does not have to poll the server from the script then reconnect to the server from the audio thread. The BME-700 Glide on/off switch was not active. Roadrunner Vibrato was too deep, by a long way. Scaled back the tremelo at the same time. Gentle vibrato was still possible but not under mouse control, it had to be done with keyboard accel/deccel. 0.60.7 22 Oct 2010 Maintenance release, minor features Added in an option called -memdump which will copy all memories for a given synth (specified with -emulate) to a target location. That location is then used as the session cache so further changes will be made to the dumped memories. That is intentional: this can be used with Session Management using a target location in the session directory so that the session will include all of the synth memories. The copy operation of the user memories only happens once when the directory is created. Added in an option call -neutral, this will initialise the emulator with the value zero for all parameters. This provides a clean sheet from which to start sound generation. The code is generic and there are some exceptions to where it is applied: the organs and pianos do not implement the option, some of the synths are exceptions too (P800, BitOne, DX) as they have a non-intuitive interface that does not lend itself to being zeroed. For testing the few that do not implement the option then '-load -1' can be used as a potential alternative. Added a runcom file "bristolrc" located in ${BRISTOL_CACHE}/bristolrc which may contain the parameters that are always provided on the command line. The parameters will be placed before the command line arguments so that they can be overridded but they provide the possibility to simplify the command line that needs to be specified when bristol is invoked. The variable BRISTOL_RC can override the default location and the -rc option will circumvent it. The size of the voice table is now a configure time parameter. There were some requests for optimisation and reducing the size of these tables is a small one. ./configure BRISTOL_VOICECOUNT=32 is the default. This is not the max table size which continues to be 128 voices: the -voices option is a runtime parameter that can be used to increase the size of the table above the VOICECOUNT limit, this ./configure option is just the default. Resolved an issue with the filter tuning of a few of the emulators, they were using an incorrect keyboard tracking value which meant that with the filter at high emphasis there was discordance in the oscillator vs filter waveform frequencies. Reworked the summary text for small changes to some of the synth names: they are sometimes different from the switches used to start them however the actual name is required to be able to use emulate correctly. The -summary list will list the emulators that have been finished, --summary will list all of them even though a selection do not actually operate yet. Removed the empty pop-up menus. The code is still there however it is no longer called by either GUI or library. There were diverse requests to stop posting them as they had no purpose. Added an initialisation watchdog timer. If the audio thread does not activate in this period then the engine will gracefully exit rather than just hang around waiting for somebody to talk to him. The default timer is 30 seconds but can be changed with the '-watchdog ' parameter. The ARP Axxe was about a semitone out of tune. The cause was the logic behind the pitch buttons which was broken. Glide parameter settings could be lost on restart, the 'glidemax' parameter was not being correctly initialised so remained as zero. Remedied a test failure for the jackd binary. If jack is requested as the audio interface then we need to connect to it to find the correct sampling rates and period sizes. The check for failure of this request was broken. Fixed a very arbitrary race condition between the audio and midi threads causing segfaults which only happens during initialisation with heavily loaded CPU. Doubt if this will have been seen outside of development as the window was extremely small. There was a spurious 'newline' debug message when active sense was detected from a keyboard. Bristol does not support active sensing (except from the GUI) and whilst these messages did not cause any issue with the synth operation they were a great annoyance for the command line interface users. The print statement was put under a debug flag. 0.60.6 11 Aug 2010 Geometry configuration options, maintenance release Was requested to implement a -geom option which would minimally allow for window placement onto the screen. This seemed very reasonable so incorporated it. The option will also take width and height parameters such as 500x200+100+100 and where necessary break aspect ratio and configure antialiasing. If only one of width/height is given then aspect ratio is maintained, and options such as +100+100 will just affect window positioning. Options like -geom 640 will just set the pixel width, maintain aspect ratio and take default placement, possibly invoking antialiasing as well. Randomised the TCP port numbers used to link the GUI to the bristol engine. There remained an issue with the Jack Session Manager and configurations that used multiple invocations of bristol: the TCP port identifiers would conflict causing one of them to fail on reload. I think the option '-host unix:1234' is a work around the issue as long as '1234' was always unique per bristol but this only works on localhost as it uses unix domain sockets rather than TCP domain. The longer term solution was to randomise the port numbers in the range 1024 to 16383, the transient service ports since otherwise there is still a window for error if the TCP ports are not closed down cleanly (although that is now finally a rare occurence). The port identifier can still be overridden and will be inherrited by the JSM interface. Resolved a few issues with different device drivers. OSS was actually broken for a while due to incorrect flags and buffers and there were a few ALSA anomalies although they were inadvertently correct. Was requested to add a manual page for bristoljackstats for part of the debian hurdles. Took the chance to also remove two ancillary binaries which generated notes but were only for QA testing, not general distribution. Added an option called -sleep which stalls the init process for seconds. This was too easy not to implement and may help to overcome what looks like a race conditition when using a session manager to restart multiple Bristol clients. Corrected some ./configure options so that they correctly check for jack and alsa header files rather than just the packages and libraries before including them in the build. This change included adjusting the default drivers so that OSS is configured when jack and alsa are not available. 0.60.5 08 Jun 2010 Maintenance release Fixed an issue with the SID where double clicking on the memory Load button would turn on the soft chip debug code. This was a development feature that was not intended to be distributed. The -mono noise mod was originally just the literal noise source, this is not a great mod and does not mimic the original which I think used a S&H circuit on the noise source clocked by Osc3. Reworked this into the emulator anyway, the sonic qualities are better. This should actually also be put into a few of the other emulators (Prophets too for example). The monophonic note logic no longer respected -nnp due to incorrect flag management. This needed to be corrected as it was backing off to HNP which implied that the engine ran constantly. Discarded a check in the ShmImage code so that the check for support in the server was dropped. Most servers which apparantly support the SHM structures seemed to be responding negatively to the capabilities request which caused backoff to the Pixmap interface. The current situation is that when compiled with SHM support brighton will attempt to use it. If the server really has issues with that then the -pixmap options will have to be requested manually. Resolved a timing issue that can occur at startup, the event manager needed to wait for positive status on the control interface before proceeding. Only affected single core systems due to threading, and was naturally intermittent. Failure to initialise the operating gain of the envelope when in some monophonic note conditions could result in apparant loss of signal until the note states were fully completed. This would manifest itself as either no output, low output or even as lost notes over MIDI channels. Midi debug flags were not being parsed correctly in the engine. Should not have affected runtime as it was only a debug which is not usually active. Changed the startBristol shell to request /bin/sh in place of /bin/bash. 0.60.4 23 May 2010 Maintenance release Coded an interface into the X11 SHM extensions under the configure switch --enable-shmimage, some that was needed since the latest X11 servers have dropped their support for XImage interfaces. This left only Pixmap which works but is rather slow. Added an option to restrict the rotary controller tracking to pure mouse up/down rather than geometric positioning. This was on request and is -rud or -rotaryUD, the value will be a fraction of the current window height. The code will respect notched controls and similar stepped rotary types. There was a bug in the event forwarding code that would damage intermittent messages. The issue was masked for a few reasons: the key events did not use this code path, controller events would be generated in such high volumes that the loss was not visible. Program change was affected, also tacked on code to address bank change events which were previously not distributed to the engine although the way MIDI does bank management is not really consistent with bristol memory management: bristol tends to work with banks of 8 or 10 memories as per the old synths. MIDI runs with banks of 128 memories and the result will be some overlap. It works as long as a single access method is used. Added -stop as a method to reap any existing bristol processes. It will kill the audio process if running which will result in any GUI dying due to the active sensing. All processes will be terminated which may not be the target action if multiple engine are being used, the options 'startBristol -kill -mini' will then only terminate the engine and GUI associated with the mini emulator. This is also not infallible as one engine could be running multiple emulators however the goal was really just to terminate a daemonified engine rather than do any really intelligent process management. Added -cache as a runtime option to allow specification of the cache path for memories and profiles. 0.60.3 12 May 2010 Maintenance release Reincorporated code for channel pressure recognition. It had been dropped from an earlier release due to dumping core when applying the channel change to all the voices associated with that channel. Also fixed up some issues with the poly pressure handling, I think it was want to hit 100% CPU. This was also ported back to 0.50.8. Fixed a bug that had been reported a while ago against the MG1/Realistic of corruption of the GUI image and loss of sound. The GUI corruption was due to incorrect bounds checking on some bitmap manipulations which were corrected, a fix that is applicable to all the emulators. There were a couple of other specific issues with the MG1 and RhodesBass that had other consequences, also fixed. This was ported back to 0.50.8. Added in another velocity map: no velocity sensitivity. That should have been there from the first implementation of maps but I think I got carried away with the ability to add hundreds of different curves that this got swept aside. It can now be requested with '-curve 0' to give something like a -3dB constant velocity level for all struck keys. Ported back. Put the autozoom feature under a configure time option --disable-autozoom, some issues were reported where it would be apparantly get activated unexpectedly, ie, the windows would constantly flip in size even though the -autozoom was not given as a run time option. The ./configure option also removes the Enter/Leave tracking which was the more probable cause of the error. There may still be some issues with KDE4.4 that were reported. This code was tested against 4.3 and it does deliver a lot of seemingly superfluous ConfigureNotify which were giving the window a Postage Stamp effect. Filtered out the ludicrously small window sizes that were being proposed. Added a preinstalled version check to the build scripts to exit configure early if bristol is already on the system. The issue is that library directories may be different between the two, most notably when the system package manager has been used to installed as a part of the OS. It can be overridden with the flag --disable-version-check although I did consider hiding this under an obfuscated parameter name as the issue has come up several times now. Fixed a core dump that could happen without the X11 libraries and a window request that failed. This would always happen unless the -window option was given. The Explorer and Voyager mod bus ramp was actually coded as a square wave. It's S&H was also very low. This also lead to more changes in the filter cutoff vs. keyboard tracking, it is now a bit less bipolar. This version includes a manual page, a common one for bristol, brighton and startBristol. 0.50.8 05 May 2010 Maintenance updates Reincorporated code for channel pressure recognition. It had been dropped from an earlier release due to dumping core when applying the channel change to all the voices associated with that channel. Also fixed up some issues with the poly pressure handling, I think it was want to hit 100% CPU. This was ported back from 0.60. Fixed a bug that had been reported a while ago against the MG1/Realistic of corruption of the GUI image and loss of sound. The GUI corruption was due to incorrect bounds checking on some bitmap manipulations which were corrected, a fix that is applicable to all the emulators. There were a couple of other specific issues with the MG1 and RhodesBass that had other consequences, also fixed. This was ported back from 0.60. Added in another velocity map: no velocity sensitivity. That should have been there from the first implementation of maps but I think I got carried away with the ability to add hundreds of different curves that this got swept aside. It can now be requested with '-curve 0' to give something like a -3dB constant velocity level for all struck keys. Also back ported. 0.60.2 28 Apr 2010 Command Line Interface Changes, maintenance release Added a play mode to the CLI. It can be activated with ':set play' and provides an alternative key path directly to the frontend to send midi note events. The code is only monophonic due to the way the raw interface works - there are no qwerty key 'off' events so they have to be interpreted. It does allow for quick testing of patches without having to resort to having a keyboard attached to the engine. Exit from 'play' mode is as with the others, either escape or ':' which at the moment cannot be remapped, something that might be an issue for internationalisation. Andrew requested monophonic sustain pedal support. This does not really fit into a monophonic instrument: if all notes sustain then with note precedence the only note heard will be at the outer one. Using sustain with a polyphonic assignment algorithm over one voice works. For the HNP and LNP another algorithm was added that holds the other extreme note - the lowest with HNP or the highest with LNP - this is the note that will fall back when no other keys are held during sustaining notes. When a more extreme note is played it then becomes the 'extreme' note. Julien reported some lost note events which was a bit disconcerting. Reproduced an issue where the events were not lost but their triggers could be: if a noteOn event arrived it would set the trigger flags. If a noteOff occured in the same sample period it would clear these flags which is incorrect for the monophonic note logic. (to be confirmed). This required a couple more patches for glide errata reported separately and largely related to inversion of the glide rate when the pitch wheel was moved causing Inf to be generated. Colin Fletcher requested that something be done about the device names in jack and eventually ALSA midi. The fix is not straightforward as the engine does not know a priori what it has to emulate when it opens the MIDI interface. The current feature is that the engine recognise the -emulate and use the synth name here for all registrations. Added to this another alias called -register which will set both audio and MIDI devices names to the given name and can be used to override other settings. Extended the CLI midi command set to include 'set midi controller ' to give access to the MIDI controller interface. May be of limited operational use but as a debuging tool it is very helpful - with alias supported it can be used to generate NRP, RP and the rest. This was implemented to debug Andrews issues with CC #64 (sustain) and used it to also debug Juliens issue by the same manipulation of the sustain flags. Cleaned up the build processes so that they really do not need X11-dev to be installed. The previous releases did require the X11 headers due to some stray ifdef in the brighton header files, even if --disable-x11 was requested. Now, for the correct build process it is necessary to define --disable-ximage too although the ximage is really informational only, ie, it would not be compiled anyway without X11 being enabled. It was left in as it gives an error message regarding the missing X11-dev headers. May remove that in the future. Cleaned the code up to remove the size warnings. They were almost uniquely on printf statements. The only remaining warnings should be for some unused variables which can be cleaned up later, and my explicit warnings for some potential issues that may need to be taken care of (again, at a later date). 0.60.1 23 Apr 2010 Command Line Interface Changes This release is primarily a cleanup to the CLI, first released in 0.60.0. There were a few bugs that became evident, some incorrect cursor positioning and hence occasional garbled output. A couple of CLI features were also added which include extensions to the completion and the ability to add commands to the accelarated keycodes in ESC mode. Finalised the CLI command completion code such that it can pretty much complete the whole tree with reasonable help information available. Changed the CLI alias variable replacement such that variable $i is the param of that index from the alias command line, the previous syntax was a little bit unusual where a $ would just take the current variable index and % would make the variable increment. set alias trans Osc1 Transpose=$2; Osc2 Transpose=$1 set alias trans: Osc1 Transpose=$2; Osc2 Transpose=$1 transpose 1.0 0.2 This will set Osc to 1-Octave transpose and Osc2 to 5-Octaves Added the capability to set CLI key codes in ESC mode to call any :insert mode command. The interesting feature is to be able to configure aliases in the CLI and then give then single key accelerator codes: 1. set cli q quit 2. set alias panic set midi panic 2. set cli p panic 3. set alias clidata set cli 3. set cli ? clidata The first will allow the use of 'q' to exit the emulator, trivial example but the point is that the CLI :insert mode command 'quit' is now available in ESC mode. The second one is potentially more useful, it links the ESC mode char p into a MIDI panic event which causes alls- notes-off. The third one adds a help function to escape mode: if you now type '?' it will list the CLI accelerator keys and their functions. This cli/alias feature can also be used to provide seach accelerators for selected synth parameters: set alias vol Volume set cli v vol Now when in ESC mode the single key 'v' will take the Cursor to the Volume control rather than having to /search for it or use the Cursor left/right motion. Several of these can be constructed to allow fast navigation through the parameters, one to jump to filter parameters, another to envelope, etc. Added some options for changing parameters from the :insert mode in addition to the = that was implemented in 0.60.0. The new modes are '+' to increment by 1%, ++ to increment by the 'set accel' value, and += to increment in given steps. Decrement have similar actions too: mini mem 0 chan 1 # Tune=0.5 00 Tune : 500 mini mem 0 chan 1 # Tune+ 00 Tune : 510 mini mem 0 chan 1 # Tune++ 00 Tune : 610 mini mem 0 chan 1 # Tune+=0.09 00 Tune : 700 mini mem 0 chan 1 # Tune- 00 Tune : 690 mini mem 0 chan 1 # Tune-- 00 Tune : 590 mini mem 0 chan 1 # Tune-=0.09 00 Tune : 500 Some of the same syntax was added into the 'set brighton device

' such that where previously value was an exact value it can now take += and -= to give relative changes to variables. This has some value for a few of the synths (poly800, bit series) where different panels may be required for data entry and parameter selection. The Poly800 has now been populated with text names for its panel parameters however to make it useful please contact the author to get hold of a suitable set of aliases for changing the data entry controls. The ARP Odyssey emulator now has a 'Dual' option on one of the VCO. This will make one VCO assign itself HNP and the other LNP to get two note logic. This is not really dual voice as there is still only one set of filters and amps. It is not a feature of the original, it kind of emulates another emulator. To prevent unexpected results the code is not applied when in polyphonic operation as it relies on the monophonic note logic to decide which are the highest and lowest notes being held down. The feature is gimpy but more fun could probably be had by starting two independent Odyssey on the same engine and midi channel then applying HNP to one, LNP to the other. Several changes were again added to the log file processes to remove a race condition on file open status. This only showed up on multicore configurations. Patched up some compilation directive errors for FreeBSD distributions, also removing a stray ALSA header that should have been placed under a compilation ifdef for removing its support. This was primarily for debian support. 0.60.0 19 Apr 2010 Command Line Interface Bristol now has a command line interface available from '-cli'. If the code is built with --disable-x11 then it can be compiled without any X11 dependencies. When built with X11 then specifying '-cli' will open both the CLI and the GUI. The CLI is based on a VI type interface and will respond to the arrow cursor keys: each parameter is available with Left/Right, and it's value can be changed with Up/Down for accelerated control. When started it is in escape mode and will also respond to the following keys: CLI: h left CLI: l right CLI: ^k incmin CLI: k inc CLI: K incmax CLI: ^j decmin CLI: j dec CLI: J decmax CLI: M memUp CLI: m memDown CLI: r read CLI: w write CLI: x toggle CLI: / search CLI: u up CLI: d down CLI: U fineup CLI: D finedown CLI: : insert These mappings are saved in the synth profile and can be edited to change the them: '~/.bristol/memory/profiles/'. These mappings are additional which means the above values represent the default mappings that always exist. There is a keyword 'none' which will disable any key operations that you do not want. They call also be configured from the command line with 'set cli '. Typing ':' goes the the VI style command line in insert mode and will accept the following commands: GUI commands: find: [free|load] synth memory search read: load synth memory at the configured index write: save current synth settings to memory import: [path [mem]] read a file and save to memory export: [path [mem]] save synth memory to external file help: this screen set: [line|debug] midi: command set to engine (X) debug: [on|off] CLI and engine debug settings (CLI only) bristol: [cont/op/value|register] - operator commands brighton: [panel|p/d/v] - GUI management commands cli: [list| action] navigation key management alias: command aliases, %/$ signs will be remapped parameters quit: exit application, terminate the emulator The command line has a history buffer of the most recent 50 commands and any consequtive duplicates are supressed. When in ':insert' mode then the cursor motion keys will nagivate this history and give command line editing. The keys '^p' and '^n' are also history forward and history backwards respectively. There is a variable called 'set history ' which will limit the number of history lines that are ever displayed, either with the 'history' or the 'set history' command, this is for small displays. The command line can be edited with ^W (kill-word), ^U (Kill-Line), ^A (start-of-line) and ^E (end-of- line). The shell command line history can be re-executed with :!, : will complete the line from the history buffer and leave it available for editing. When in ':insert' mode the key will list available commands and complete them where possible. Commands strings do not have to be complete to be executed, they only need to be unique. If a command cannot be found from the above list with the key then the current line is used as a lookup into the synth parameter list with the following syntax: : LFO : Osc 3 LFO : Osc 3 LFO=0.5 The tabbed search here is for the given string anywhere in the synth parameter name, not at the start of the name. If the string is not unique then the matches are listed. When in Escape mode it is possible to search the emulator parameters with the VI '/search' key and TAB is also available. /lfo - find all parameters that contain the word lfo, complete if only one /^lfo - find all parameters that start with lfo, complete if only one To toggle from ':insert' mode to ESC mode either type ^C (Control-C) or . The CLI is available for the following emulators: Mini Explorer Voyager Odyssey Axxe B3 BME700 Realistic Juno Jupiter PolySix MonoPoly OB-X OB-Xa Pro1 Prophet5 Prophet52 Prophet10 Sonic-6 Stratus Trilogy Sidney Solina Vox VoxM2 RoadRunner Rhodes Rhodesbass The arp2600, bm, bit1, bit99, bit100, dx and poly800 have not been converted and are for future study. The bit and Poly need a separate interface due to their input methods. The 2600 needs some method of representing the patch cable configuration. Now the CLI can still be requested for all of the emulators but only those listed above have (almost) descriptive text for each parameter. There are a few CLI variables that can be set: set history set savehistory on set line [CLI line width] set accel [Controller acceleration for Cursor motion] The savehistory option will overwrite the emulator profile file with every 'quit' commands. The 'line' option defaults to 80 columns but is configurable for small Braille displays. The CLI supports alias definitions: set alias trans Osc1-Transpose=% The command 'trans 0.5' will cause a transpose request to be made to the engine. Multiple commands can be aliased together using ';' between them. Multiple parameters can be set such as set alias trans Osc1-Transpose=%; osc2-transpose=% trans 0.2 0.5 Here, the '%' is replaced with the alias options on the second line, each % will move the argument list forward. The command will send two different transpose events to the engine. Conversely: set alias trans Osc1-Transpose=$; osc2-transpose=$ trans 0.2 Here the '$' does not move the variable forward so the same value is taken. This will cause the same transpose value to different oscillators. Any defined aliases will be added to the list of available commands and shown in the help menu, as will the list of mode keyboard shortcuts. Aliases can be deleted with 'set noalias '. The CLI prompt can be configured. Typical values could be plain text for the emulator type but there are also variables available: set prompt mini set prompt %algo%: or more usefully set prompt "mini %memory%: " will give mini 99: The tokens 'channel', 'algo' and 'panelid' are also recognised. It is also possible to give the name of any of the synth variables in the prompt too in which case they are evaluated: set prompt "%algo% mem %memory% chan %channel% # " mini mem 23 channel 2 # set prompt "%algo% layer %PanelSwitch%: " obxa layer 0: Fixed an aged issue with the Explorer/Voyager that they produce no sound by default and even then they are very, very noisy. Not sure why it never got reported. The noise was originally due to injection to make the filters self oscillate but become noise after one of the many normalisation rounds. After integration of the CV IO for the ARP it was time to change the diverse Keyboard Tracking inputs for the oscillators and filter. Up to now they had been inactive, the tracking was integral to the operators. Now they can be remapped from any of the other outputs which gave some facilities to get modwheel to frequency mapping and improve the filter keybaord tracking. Change the MIDI device selection such that '-midi alsa' configures a SEQ interface rather than ALSA raw. This has caused a few error reports from people who have not got the expected result. Selecting a raw ALSA interface is now done with '-midi rawalsa' or '-midi alsaraw'. 0.50.7 22 Apr 2010 CV Keyboard Tracking Frequency Control for ARP After integration of the CV IO for the ARP it was time to change the diverse Keyboard Tracking inputs for the oscillators and filter. Up to now they had been inactive, the tracking was integral to the operators. Now they can be remapped from any of the other outputs which gave some facilities to get modwheel to frequency mapping and improve the filter keybaord tracking. Several changes were again added to the log file processes to remove a race condition on file open status. This only showed up on multicore configurations. This was a 0.60 backported fix. Backported the 0.60 fix for an aged issue with the Explorer/Voyager that they produce no sound by default and even then they are very, very noisy. Not sure why it never got reported. The noise was originally due to injection to make the filters self oscillate but become noise after one of the many normalisation rounds. Patched up some compilation directive errors for FreeBSD distributions, also removing a stray ALSA header that should have been placed under a compilation ifdef for removing its support. Since the release of 0.60 this stream is now in maintenance only. 0.50.6 08 Apr 2010 Multiple IO Channels for audio/CV, more NRP Controller Support, Jack Session Manager maintenance Made the audio engine allow for registration of multiple ports into Jack. This gives the stereo in/out that always existed plus up to 16 additional ports which will be used according to the emulator requirements. In the short term this will only be the ARP 2600 which will register 4 extra IO for CV inputs. Future code will probably be the mixer that has been kind of waiting around for a while now. The option '-multi ' specifies the number of channels that will be opened to the jack daemon. The input and output signal levels can have a correction applied to them, -migc and -mogc each take a floating point which will adjust the gain on the signal, applying it to all channels. The default gains are 1.0. The signals for this IO are normalised to +/-1.0f although the ARP shouldn't have issues with a wider signal range. The tests executed in house used two ARP both connected up to Jack, one driving CV into the other such that the Envelope from the first was applied to the filter of the second for example. The signal levels were within the range 0..1.0f from the envelope however AC signal will have a negative range too. That may be an issue for some other targets that do not want their CV to go negative so outputs 3 and 4 have a DC normalised signal with clipping below zero. Extensions to the CV configurations for the other emulators is for future study. The issue is not how to get the signals into or out of the emulators but a question of how the routing should be defined. For the ARP 2600 the signals can be patched as required. A part of the IO functionality testing was done with session built by the Jack Session Manager so that two ARP 2600 could be loaded and signals passed between them. This lead to a number of fixes to parts of the naming structures, not really bugs, just things that would only really have come to light when running multiple instances of bristol with jack and jsm. The fixes included removing any auto-connection options if there were any jsm options present, renaming the windows so that the title includes the device name from the Jack interface to help identify windows in duplicated setups, more small adjustments to the parameters parsed to the JSM command line, some changes to the import and export routines used to load the JSM saved memories. Recoded the GUI NRP support so that it can track NRP parameters. It requires the GUI be started with the -gnrp option. The code does not support ganging: tying multiple GUI devices to the same NRP however that may change presently. The existing CC control registration can be used for that purpose. The NRP support is naturally affected by all the usual limitations of NRP: they are assigned to MIDI channels not device targets (which SYSEX does do). This means if two devices are on the same MIDI channel it is up to the user to ensure that the NRP they use do not have conflicting actions. The NRP mappings are saved in the same profile as the emulator CC, CM and keyboard mappings. Per default the mapping table size has 128 entries which matches the CC counts and should be enough for any of the current emulators. A parameter -nrpcc can be used to change the table size. The emulator settings will now be taken from the emulator header files rather than pure runtime switches. This imposes the use of the '-emulate' option which previously had this function. The choice was based on a discussion with Andrew Coughlan: if we are emulating then consider defaulting the closest match to the original, users can override options afterwards. This means a Hammond will start with the maximum voice count available, for example, but a Mini Moog will start with just one voice, highnote precedence. Changing the number of voices after definition of the emulator can make the Mini run as a polyphonic instrument if desired. The algorithm search is strict, ie, only the emulator names from 'startBristol -summary' are recognised. This is in contrast to the remaining parameters that do take some aliases (-arp is the same as -arp2600 for example). Needed to suppress a few more options from the command line presented by bristol to the Jack session manager. These were port, rate and count which are all dynamic parameters anyway. Not supressing them lead to their duplication and some undesirable side effects of that. Renormalised the trilogy output signal after some advice on their levels. Changed the configure flags to include options for separate default audio and MIDI drivers - Jack audio and ALSA MIDI was quite popular. Fixes some repainting issues with the vertical sliding controls, they left a trace of noise on the way down. 0.50.5 03 Apr 2010 Jack Session Manager Immediate fixes The code now can actually save and reload sessions on request of the jack session manager API. 0.50.4 will be delisted. Added a -import flag which will take a file and load it into the synth at init time. This may fail if the memory was for another emulator however it can ease file/memory interchange. The memory is not directly saved into the bristol cache but still needs to be saved to some (free) memory location in the emulator. The flag is actually an alias for -jsmfile which was required to do the same for the jack session manager. Added in runtime options to support keyboard splits. Not sure why this took so long as it is a base requirement but as it is also possible from a master controller it never made it yet. The two options are -highkey and -lowkey and apply to single emulators. Error checking is minimal: values outside of the 7-bit MIDI note range are not checked, low > high is not checked, ie, it is possible to build configurations that will not work. They will not break the emulator but no response will be heard. 0.50.4 02 Apr 2010 Jack Session Manager Support Installed the svn jackd version with session management support to start work on coding the interface. It required a few changes, not just to the way that the jack interface had to work but also to the bristol message passing to allow for arbitrary strings to be exchanged rather then just control and operator data. Similar to the LADI code, the session requests come into the engine, it then has to take care of redistribution to the GUI where save operations are actually executed. The interface is perhaps not quite what JSM expects but that is purely a bristol internal working issue: Jack session requests come into the engine only, they are translated into bristol session requests and then distributed as required - to the GUI. Bristol session management includes the capabilities to both save and recall setup however the save and recall source can only be the bristol cached content, not from an arbitrary file. to overcome this, when a save request is sent from the engine to the GUI, it extracts the file path. Memory is saved to a private entry in the cache and then this private file is moved (exported) from the cache to the target location. The load request works similarly although Load requests do not come from JSM which does not have this feature. The engine command line parses the -jsmfile option and sends a session message to the GUI to import and then open it. There is the -jsmuuid option which is used by the session manager to direct the aplication to register with the given ID. There is one additional option which is -session which will disable all session management, including LADI. Removed the incorrectly remaining 1/2 sample phase correction from the reworked Huovilainen filters for the non-resampling algorithms. These are called when the samplerate exceeds 80KHz as the point where the filter quality starts to degrade is far above the audible operating range of the filter. These have not been widely tested and an override could make sense. The OB-X filter code needed some corrections for the performance changes, the code was there by the command line options were different matches. Also added some more frequency corrections for keyboard tracking of the filter. Resolved an error in the jack ringbuffer management. The buffer would fill up and give 'ringbuffer exhausted' messages under specific circumstances: running as a headless server with last GUI detached whilst still receiving MIDI events. The fix was belts and braces, the buffer is reset in the audio thread if it is idling without emulators and the ringbuffer is also stopped with the last of the emulator to exit, restarted when new ones are created. The GUI still had some legacy support for controller registration against things like RP, NRP, DE. This is supposed to be disabled if -nrp is given however the flag was not being honoured. This is a kind of workaround, a bigger fix would be to correctly register them however that leads to some issues with table sizes that will be left for future study. This whole area is a grizzly part of MIDI and should really be resolved with an alternative protocol. The default build is now without the semaphores, they can be re-enabled on request at configure time. Also added a config option for the default drivers, the can default to alsa or take an option to use Jack as the default. The mini emulator GUI would show key motion for midi channel and channel+1, this was caused by an incorrect key panel flag. The engine did not respond on both channels, just the frontend. The Rhodes emulators stopped working due to some code that looks for the skins not functioning on their internal contructions. 0.50.3 17 Mar 2010 Band limited oscillator corrections, filter optimisation, GUI enhancements. Corrected (most) of the previous restrictions on band limited oscillators, namely that they were precomputed tables rather than dynamically limited. They did give different signals than the mathematically built infinite bandwidth waves (-blo 0) however they did not really prevent aliasing at the highest frequencies. The code now does cut in bandwidth limits depending on a few run time parameters: -blo n - maximum number of harmonics to map, defaults to 31 -blofraction f - upper frequency limit as fraction of samplerate (0.8) The code will attempt to stuff as many harmonics up to 'n' such that the fractional limit is not broken. Using values > 1.0 will lead to pretty wild aliasing, lower values will thin out the sound but exhibit fewer artifacts at the higher frequencies. The default value is admittedly above nyquist, this is a tradeoff between distortions and waveform content. The code uses precomputed tables for all frequencies where freq*n does not exceeded f. Reworked the Huovilainen filters to move the expensive maths into the feedback loop only. This reduces filter CPU requirements by about 90%, naturally at the cost of some quality. The net results of the changes do not degrade quality that excessively and due to the amount of reports of CPU exhaustion there are new filter options: -lwf are the chamberlains, -hwf are the original heavyweight Huovilainen and the default are the optimised ones. These are all run time parameters per emulator. There is still the overriding -glwf option to enforce all the emulators to use the lwf option globally. There is further filter option which is -wwf, these use about half the CPU of the -hwf filters, they use the same overall architecture however use a different but also more efficient non- linearity giving a 50% lower CPU footprint. The default filters may also be requested with the option -nwf, normalweight fiters. Added some new corrections for the filter frequency tracking and especially keyboard tracking changed considerably. It can now be played in tune when at full resonance and can self oscillate at some settings. The window now has a zoom accelerator under ' Enter'. This will toggle between native window size and full screen. The native size the the one at which it was created including applying any scaling parameters. The code will introduce some image antialiasing when it scales to full screen, this remains after returning to native size. Used the same code to have window scaling accelerators: ' +' will make the window about 10% bigger, ' -' will make it similarly smaller. With the zoom accelerators coded it was then possible to add in the -autozoom feature such that when the mouse enters the synth window it is maximized and when the mouse leaves it is minimised. Both windows remain active however they can reduce screen clutter. Width and scale will define the minimum and maximum window sizes. Added an option -width to speficy the minimum starting window size. This works in conjuction with -autozoom and -scale so that between them they set the min and max resize limits. There is no corresponding 'height' option, the height of the window will follow the aspect ratio for the emulator. The option only works with autozoom, if that feature is not required then the -scale option should be used to set the actual window size. Fixed the responses to FocusIn and FocusOut, they were silently dropped in the earlier code releases but were now needed for the autozoom capability. With these in place the opaque resize aspect ratio management was changed such that the resize results in the window getting morphed to fit the window and then aspect ratio being enforced after the resize has finished. Glide and pitch bend did not work together: glide was cut as soon as pitch was altered. The fix was a one line change to the frequency assignments, previously target and current were set by the pitchwheel, the change was only to adjust the current. There was an issue with logging to the user home directory, in most cases the log file would be opened truncated and never used as destination for output messages. 0.50.2 06 Feb 2010 Real time processing enhancements Added code for Jack Sample Accurate replay. This was a compromise for a useful if awkward feature to implement in bristol: it is only implemented in the bristol envelope code such that note_on events will be sample synchronised to the offsets reported by Jack MIDI events. All other events will be period synchronised as the Jack MIDI events are handled in the audio stream so are at least guaranteed to occur within the given period even running at double speed, etc. There is no intention to synchronise all the audio generation code and as this is working as an emulator that is not considered relevant - the original instruments all had free running oscillators and as such were did not have any kind of synchronisation to note changes. We are not going to attempt to have the exact same sound come out at the exact same point however the major state transition at note on will happen at the desired timepoint. Some of the emulators already had trigger synchronised LFO, these are now also sync to note offsets from Jack although the net effect will probably not be much due to these being low frequency hence low rate of change over the Jack frame offset reported in the note event. Placed the use of sem_init under a complation flag, preferring sem_open instead, improves portability except that sem_open requires root privileges and PAM does not seem to support any security permissions for this. To use the sem_open call then './configure --enable-sem-open'. This last change was probably superfluous as code was also added to remove the necessity for the semaphores in the first place. They cause issues with the RT threads and so incorporated a ringbuffer for note events from the MIDI thread to the audio thread. This adds a little extra processing but not excessive. This is a compilation time option, './configure --disable-semaphore', it will eventually become the default sequence or potentially put under run time options. The code was not completely trivial as the system needed to be able to distinguish between where events came from, and if jack then checks were needed to see if it was from a single registration or multiple registrations - the former actually ends up with two threads that can recieve messages, the MIDI thread fielding events from the GUI (including note events) and the audio thread itself - the sample ringbuffer code only supports singular TX/RX of the ring. Added some flags to the messages buffers to indicate source and make the choice of direct handling from audio thread messages or indirect handling via the ringbuffer under other circumstances. Coded a second ringbuffer for event forwarding. To ensure low latency then it was not advisable that the RT threads did event forwarding to TCP however this is needed to get event tracking from engine to GUI. The second ring buffer is for the path from the audio and MIDI threads to the otherwise idle parent thread who then does the forwarding from the ring buffer. Fixed an issue where inability to find the bristol profile files would result in total loss of output signal. The cause was failure to default the velocity and frequency tables when the configuration files were not found. Removed some compilation flags that were specific to my system ready for distribution. Version 0.50.1 probably had compatibility issues due to these. 0.50.1 22 Jan 2010 Usability enhancments, LADI level 1 compliance, process distribution Implemented code for LADI level 1 compliance. This required a few changes, not just to accept SIGUSR1 to save state but also to have this possible in the engine and GUI. For the GUI this meant adding startBristol code to exec the GUI (or engine for that matter) rather than fork it, then have it trap the signal and save a state file. For this to work in the engine, seeing as it does not maintain state, it requires the signal be trapped and later a message sent to the GUI to save the state. This last one caused diverse issues that needed to be resolved to clean up some SYSEX handling. The code will accept options to field LADI only in the engine, only in the GUI, or the both. The default is to field in the engine. There is an option for the state file memory index. At the moment bristol does not keep an arbitrary state file: the call is a tack into the existing memory save routines so that memory, chord and sequence information is also saved, this code section only accepts an integer which is the memory index. If both -ladi memory location and a -load options are given then the LADI state memory will be loaded if it exists, otherwise the -load memory will be activated and then becomes the template for the LADI state file. Reworked part of the Jack audio library on request of Nedko for LADI support so that the client interface is only opened once, in the audio thread. Without this he was seeing both audio and MIDI threads opening an interface and this did not map into his registration routines and PID mapping. Previous releases incorporated separate Jack registration requests in the audio and MIDI threads using different symbolic names. This worked however was a bit cumbersome for LADI support. The MIDI code can now reuse the audio registration from the audio thread, just adding an extra MIDI port to it. This became the default Jack behaviour with a -jdo option to enable Jack Dual Open if still needed later. The operation of the -jack flag also changed to configure Jack drivers for both audio and MIDI. Prior to this the -jack flag only configured the defaults for the audio interface and kept the ALSA (-midi seq) option for the MIDI interface. The previous functionality can still be requested with the flags '-jack -midi seq' or just '-audio jack'. Integrated several keyboard accelerators, these were requested as a set of usability enhancements. The include ^S, save, ^L, reload, ^X, exchange two memories, ^K, print the list of shortcuts, ^H/^?, print help information which is the text writeup for the emulator. The actual readme is now built from this output. Parts of this code (specifically the save routines) were used for the LADI state save routines. Cleaned up some issues with the MIDI interface flags, the readonly input to bristol needed to be configured as an output into ALSA, something that was being mixed up. This may be ported back to 0.40. Affected midithread.c and midiSeqDevMan.c only. There was a bug in the memory file management code that cause a spurious directory 'memory' to be created in the users home directory if the emulator did not have a private memory path. It was also created in $HOME/.bristol as well, correctly, however the code did not return on the first creation. The BRISTOL_LOG_CONSOLE environment variable was changed to be a true/false flag. The run time equivalent option -console should now be honoured under all circumstances which was not the case previously. Cleaned up the closedown procedures for the situation that jack decides the process is 'zombified' (sic) when it is actually under CPU pressure. It used to leave the engine hanging around. The issue was not always obvious due to alternative TCP port selection but it was still wrong. The processes should now exit more gracefully although jack could be a bit more flexible here as the cause of the original hanging processes was libjack blocking disconnects from a process it had flagged as 'zombified' (sic). Added key handlers for left and right arrow to give more controller tracking. The Up/Down keys already moved controllers, with shiftkey accelerators, the Left/Right now give more movement than up/down. Integrated another fix for loss of keyRepeat functionality on exit: there was a window where repeat could be turned back off if the mouse re-entered the GUI window before engine negotiation had completed. The following changes would have been in 0.50.0 had it been released: This is actually a new software stream, the changes required to give correct distributed processing were sufficient to be kept separate from the 0.40 release even though there do not appear to be a great number of features. This release 0.50, is going out first as unstable. Many fixes for bugs found whilst working on this code were put back into the 0.40.7 release which is now considered to be stable. Having said that, this release is the first to include some form of quality assurance. The process of SQA rotates around the distribution capabilities: a single engine is started in one window, and then a scripted procedure runs sequentially through every emulator, starting and stopping every 10 seconds (roughly). During the whole process note events are being sent to the engine and redistributed to the GUI. The SQA test is only considered to have passed if it runs without any form of misbehaviour. Typical cycles are somewhere over 2000 iterations. Failure includes any crash the GUI or engine, loss of audible signal, exhaustion of any of the library resources (handles, devices, etc), memory leakage or any recognisable memory corruption. This is neither the simplest nor the most complex test procedure. The first iteration just restarted a single emulator 1000 times, after that it became starting all of them, and then adding note generation. There are two other scenarios that will be in a final test sequence (at a later date) which will include multiple synth pairing and also program change events. The multiple synth pairings will be interesting, it should involve generating notes to every possible pair of layered synths (about 1200 cycles) including stopping and starting all of them each time on the same engine. Added a -log option that causes output redirect to a file. Will first attempt to log to /var/log/.log if permitted, otherwise it will attempt ~/.bristol/log/.log with file truncation if logging is to the home directory. As a part of this operation the whole logging mode was altered such that a separate thread now takes control of stdin/stdout and stderr, timestamps the output messages before printing them. Finalised this with a -daemon option that detaches the controlling terminal and implies -log and -server. It is noted that -daemon holding open files in a users home directory is potentially not optimal so this mode would best be used as root with open files in /var/log. It is possible to override the use of the log thread by setting an environment variable BRISTOL_LOG_CONSOLE, this prevents the thread creation and continues to output to your TTY. Had to rework the brighton thread management to allow for asynchronous MIDI event distribution. It may need more testing so will go out as unstable - there were quite large alterations required but it lead to better general thread management in the GUI: it no longer exits forcefully on window requests or interrypts, it flags the threads to exit gracefully. The changes all passed through the SQA hurdles discussed above. Finalised the event redistribution code so that only the GUI or the engine need to be aconnected to a real midi interface (or sequencer interface). Events arriving on this interface are redistributed to tcp ports, ensuring that the GUI and engine always track the same events. There is an override of this functionality using -forward (discussed below) and forwarding is on by default. Added an option -sysid to specify the MIDI SYSEX system ID for communication. This needs to be entered as a 32 bit hex value. It will override the default of 0x534C6162. This followed an interesting discussion on LAU regarding controller identifiers. The theoretical collisions that could happen should not have affected bristol since SYSEX is only used over the TCP connection from GUI to engine however the feature was cool enough to get implemented. For those who are interested, the default SYSID is 'SLab' in hex, the bristol MIDI interface extended from the SLab design. An issue was reported with -voices 1 not giving any sound. This turned out to be true and the workaround (now the fix) is to use -hnp or -lnp with either the -mono flags or when voices=1. The code also now configures the note precedence automatically (although it can be overridden). [And the last note precedence code should also now be fixed too. nc.] Fixed a spurrious compilation issue when Jack drivers are not found. Code was still attempting to make a library call that was not compiled into that library. Reworked exit conditions so that the processes can return reasonable status back to the caller. That was not the case with the GUI and even if it was then the startBristol script needed to still consider these exit status. Did a cleanup of the build process to remove some spurious warnings that should not have cause any issues with the code but did make the pedantic compiler churn out messages. The remaining output should primarily be for my own warning statements and a few unused variables/routines in the unfinished emulators. Added an option -window to prevent posting of the GUI window. This is for SQA testing where each emulator is started in turn in a constant cycle of thousands of iterations, this spares a few cycles and allows other work to take place without the sometimes irritating window focus changes. Inserted some exclusion code on the midi signalling not to dispatch callbacks for physical midi events, nor forward them, during some critical code sections, notably starting and stoping emulators. Also had to clean up some deallocation of the voices as there was a 'hole' in the code where a NULL baudio would prevent a voice from being freed up, ever. Added some NRP commands to request remote event forwarding. This is used by the GUI to prevent the engine from duplicating events into two possible TCP pipes (dual manual keyboards), and by the GUI to selectively do the same for its interfaces. This resulted in changing the -forward flag to be a global engine setting, -localforward for the GUI to the engine (local in the sense that the GUI is per definition local, the engine may be remote), and then a -remoteforward option for engine to GUI settings. The latter two will only affect the single emulation which means some GUI can request copies and others decline them. This flag does not affect the existing -tracking option which simply governs whether the GUI keyboard will respond to MIDI note on/off messages. The forwarding of events covers more than just note on/off, most notably program change and modulation events are needed even if tracking is turned off. Fixed an issue of incorrect shadow rendering from resizing withdrawn panels. When they are finally exposed the shadow contained the unsized instance. Fixed two issues with the bassmaker operation, the first step after pressing start was not being sounded and LED status is not cleared on restart. The LED status of the last Stop point was not being cleared. Additionally the shadow rendering was faulty when panel selection changed with resized windows. Cleaned up a compilation flag that could still cause it to fail if Jack was not included in the system or build process. Reworked the audio library so that ALSA devices are just drained and prepared when a read or write error occurs. Previously they were closed and reopened which is a rather ugly overhead, plus there were obvious chances that it used to incur some memory leakage. The new code changes some of the data preload processes which now have to be pushed down into the library. The previous method can still be compiled by giving the --disable-drain option to the configure script for cases that give problems with the new method. A failure in limits checking lead to a potential memory corruption issue in the continuous controller code and NRP handling. This could have been the cause of the original issues reported around NRP causing the engine to fail. Irrespective of this, though, there are too many possible collisions here as the NRP address space is common across a given MIDI channel making its use rather hazardous. A couple of the emulators were exhibiting fairly random segmentation faults, indicative of memory corruption. Ran up valgrind to give some input into the causes and there were diverse issues that had to be taken care of. A part of the cause was the controller ID damages given above, there were diverse changes to the emulator code as there were a few errors in buffer pointer management that resulted in some emulations leaking quite voluminous amounts of memory each time they were invoked, and some small leaks on things like audio device restarts where buffered name space was not being reutilised. There was one case of a bristol audio structure being reused after it had been freed, this was introduced when the emulator destruction code was moved from the MIDI thread to the audio thread for other unrelated problems. Valgrind still reports some minor memory leaks however these are almost uniquely related to the ALSA library interfacing where structure ownership is not really that clear and are typically bits of memory that are not really lost, they are just not freed on exit, and since the audio drain feature was added then the audio device is not longer reopened when xruns occur. These remaining bits can be reviewed later as the loss is still small, it does not appear to increment over time and does not affect functionality yet. In total there were about 15 changes related to corruption rather than leakage although not all of them would have caused segmentation faults as they were not all write operations, some were read. These would have caused intermittent noise (ticks) and potentially wild modulation, especially of the DX FM operators. Removed an issue with the libbristolmidi ALSA SEQ interface handling for the channel identifier, it was not correctly being merged across resulting in all channels converging onto zero. There was a small timing window where GUI failure could result in dangling emulators (headless). Active sense will only start after a sense message is received, so if this first message does not get there then the emulator does not detect GUI failure. The engine now always starts ActiveSense, the GUI has to turn it off if not enabled. There was a ludicrous amount of debug messaging added to track down all of the above problems and rather than remove it all for the release, they were buried under a -debug flag that defaults to 'off'. Values of '-debug 12' or greater are not advised as they will debug every period of samples. The B11 library stops key repeat on window entry and reenables on LeaveNotify, this is use to make sure the QWERTY keyboard tracking functions as expected. With some window managers (reported against fvwm) the window Destroy function only sends a wmDelete request and no LeaveNotify as the window exits which would result in loss of key repeat. The command 'xset r on' fixes that however submitted a fix to turn repeat back on under these circumstances too, and added in some X11 event debuging at -debug 9 or higher. Finally continued to resolve what I would call minor issues although that is subjective. Engine compilation did not include config.h, the Solina had very different gain on its harmonics, some of the bitmaps needs improved drop shadow rendering, the MIDI processing would terminate with the first emulator to exit, ie, the MIDI library was not reactivated, etc. Removed potential segfault in midiNoteOn(). Put the speaker holes back into the ARP 2600, vertically as there was a shortage of realestate but having them puts the gravity back into the image. Fixed an issue with the flagging defaults for the -alsa flag, it was taking ALSA rawmidi rather than the usual target of ALSA SEQ. This would fail the option completely. It could still be made to work with -alsa -midi seq, or by not using any specific driver options as the defaults were correct. Updated diverse parts of the GPL compliance, bringing all the files up to version 3 of the license and including the disclaimer events where necessary. Bristol version 0.50.0 was never distributed, the release was rolled up into 0.50.1. 0.40.8 22 Jan 2010 Maintenance release Fixed an issue with the flagging defaults for the -alsa flag, it was taking ALSA rawmidi rather than the usual target of ALSA SEQ. This would fail the option completely. It could still be made to work with -alsa -midi seq, or by not using any specific driver options as the defaults were correct. Jack MIDI opening sequences had a potential window to fail in which case the interface would not be activated. There are no further fixes from 0.50.1 that will be ported back to 0.40.8 as they are now primarily related to new features in the 0.50 stream. The 0.50 stream will also be created at the same time, as such this download may not be of interest to many people, ie, installing this may duplicate the effort later. 0.40.7 22 Nov 2009 Maintenance release Fixed some compilation flags that could still cause the build to fail if Jack drivers were not included in an installation. This is a backport from 0.50 for compatibility purposes. The sid.c code had as issue with debuging being executed without suitable checks on the handle. Could cause a crash which has now been fixed. The XPM reader had a couple of issues with parameter naming collisions and its file naming for temporary files used for decompression could also fail if more than a single GUI intialised at the same time. Had to implement some extra local memory sanity checks before calling the emulator operate() code. Depending on timing these may still be null as the emulator initialises. The bristol BassMaker would give incorrect panel rendering when panel selections were made on a resized window. This could have affected other emulators as well. The BassMaker would jump the first step of a sequence. The BassMaker did not correctly clear the LED status of the stop position. There was a hole in the voice management code that would prevent a voice from ever being freed up if it had a null baudio. This could happen if a voice is still active as an emulator is terminated. Cleaned up a compilation flag that could still cause compilation to fail if Jack was not included in the system or build process. A failure in limits checking lead to a potential memory corruption issue in the continuous controller code and NRP handling. Removed an issue with the libbristolmidi ALSA SEQ interface handling for the channel identifier, it was not correctly being merged across resulting in all channels converging onto zero. A couple of the emulators were exhibiting fairly random segmentation faults, indicative of memory corruption. Ran up valgrind to clear up a few memory leaks of small amounts of memory on things like audio device restarts and also to track down the corruption. It was partly the controller ID damages given above however the baudio structure was getting freed before its ultimate use which could intermittently lead to further damage. There are still some minor memory leaks however these are related mostly to ALSA library interfacing where structure ownership is not really that clear. This can be reviewed later as the loss is still small and does not affect functionality yet. In total there were about 15 changes, not all of them would have caused segmentation fauls as they were not all write operations, some were read. These would have caused intermittent noise (ticks) and potentially wild modulation, especially of the DX FM operators. The B11 library stops key repeat on window entry and reenables on LeaveNotify, this is use to make sure the QWERTY keyboard tracking functions as expected. With some window managers (reported against fvwm) the window Destroy function only sends a wmDelete request and no LeaveNotify as the window exits which would result in loss of key repeat. The command 'xset r on' fixes that however submitted a fix to turn repeat back on under these circumstances too, and added in some X11 event debuging at -debug 9 or higher. Removed potential segfault in midiNoteOn(). 0.40.6 28 Sep 2009 Maintenance release Resolved a name resolution issue that would cause the split/layer keyboard emulators to fail. The dual manual ones should have worked. The workaround was to default the hostname when null but the actual fix is to request the same destination host in all cases, something that will now only go into 0.50. Included some memory packs for the trilogy and polysix emulators. 0.40.5 23 Jul 2009 Distributed processing maintenance release Added an option to startBristol, -gui, which will prevent the GUI from being started and invoke the engine with all the resolved bristol variables. This will allow for easier distribution of the applications with GUI and engine on different hosts which was always a part of the design but was never really made that accessible. This can be used in conjunction with the -server flag which will leave the engine active even when the last emulator has disconnected. Running as a server lead to a few issues that were anticipated - constantly reconnecting GUIs would exhaust various engine tables that were not being cleaned up correctly as this had never been widely used. The file descriptor table was not being cleaned up, the handle and device tables similarly. There was an issue with SID selection of the EXIT requests not being correctly matched causing the wrong emulators to be disconnected, and with failure to correctly close input file descriptors on active sense failure requiring a small change to the device reading logic. It was finally possible to run a test script to reconnect nearly a thousand times, without failure, all emulators still audible and so moved to released code. Several issues arose whilst building the application without ALSA drivers. This is supported, especially now that Jack MIDI is integrated, however since ALSA turned 1.0 the coding has been a bit lax, assuming that ALSA was available and integrated. The result was that building without ALSA might fail and that even when compiled there were issues with device open() requests. Resolved these and added the flags required to accept note events over the control link so that GUI keyboard events are still tracked even if the ALSA code is not integrated. Was requested to remove all OSS dependencies from the build process as well. This was a little more work than ALSA since that was always intended to be a build option, OSS by contrast was always anticipated to be present. Had to clean up some of the socket toolkit header files and some erroneous definitions in the midi library that was being flagged by some more meticulous compilers. Reworked the TCP addressing code to accept -host where hostname can naturally be a IP address or (non)canonical hostname. The port option can be used with the -engine flag to connect the GUI to a specific host where the engine is running, remotely: it is an alternative to the -port flag however it is still advised to actually use -port for other reasons. There was some general code cleanup from the request to have bristol function on a system that had neither OSS nor ALSA installed. This was never anticipated and making it possible brought other issues to light. The Trilogy had a very unequal mixing section, the organ gain was too quiet and the synth section too loud. These were evened out. The Trilogy also had some rather unusual use of volume controls. To reduce CPU load the synth would not run the organ and string sections unless they had a non-zero gain. This achieved its affect however the result was that if the gain was zero at note_on then the voice was always muted (it actually just fell through the note logic and turned itself off). The fix was to always run the oscillator divider circuit envelopes under all circumstances to engage the note logic. The audio generation code is still skipped as it would be silent anyway when the gain is set to zero. 0.40.4 06 Jun 2009 Audio Driver Mainenance Release Added an autodetect for Jack where a small program will connect to the daemon and find out the sampling rate and period size. These are then given to bristol as parameters preventing unexpected mismatches later. Fixed a watermark issue with the ALSA drivers, the high available threshold was too low which causes the library to report false overruns. Since these come back as a failed write operation the bristol audio library was restarting the audio devices. The diagnostics reported this as a broken pipe. Resolved a typo in the ALSA drivers that damaged the periodsize and buffersize matching. Caused cyclic ticks in the output stream depending on hardware and ALSA driver versions. Changed the activesense period to 3s and timeout to 15s. There are issues when running with RT scheduling where the GUI may get starved when there is a lot of audio activity causing the engine to give a false positive of a GUI failure. Since active sense is really there to make sure everything exits gracefully when there really is a failure then the timers need to be more flexible to cater for situations of high CPU load. [0.40.5: as a side note, this only really affected a system if it had cpu-speed ondemand, or was massively over- loaded, neither of which are optimal for audio processing.] 0.40.3 25 May 2009 Maintenance release, B3 stuck notes. The Bristol B3 was exhibiting stuck notes, fairly arbitrarily however the issue was not reproducable on the development system. After a ludicrous number of debug builds to get different statistics the cause turned out to be the B3 postOpts which manipulated the voice flags and the resolution was to extend the semaphore coverage to include emulator postopts. Theoretically it would be possible to have just changed the B3 code however the engine that hosts the emulator should not be open to flag abuse in the voices and the voices are allowed to manipulate these flags. The actual cause was a race condition that only really exhibited itself on multicore/HT systems. Thanks to Andrew Coughlan and Damon Chaplin for the report and debuging output to isolate this issue. As the problem was not reproducible on the development system (single core) then tracking down the cause required a number of different debug revisions and a great deal of patience and output logging from the people involved. Releases 0.40.1 and 0.40.2 will be removed from the download site. The bristol shutdown procedures were not really compliant with the Jack API definitions, they would not deactivate/unregister the active handles before exiting. This does not work very well with multiapp environments, it causes a subgraph timeout in the API. Changed the shutdodwn code sequences so that the last exit operation will clean up the emulators in the audio thread and let the MIDI thread then unregister jack and exit so that all parties are happy. Also added some diagnostic output in the event that ports cannnot be registered - this happens if Jack has a lot of application ports to deal with so the additional message makes sense. Also coded in jack_client_open() to replace the now deprecated jack_client_new() previously being used. The Sidney emulator was about 1/2 a semitone out. After a lot of delving into the correctness of the code without much success (ie, it seemed correct) it turned out the C64 had different versions for NTSC and PAL, with different CPU clock speeds. The frequency tables were built from data taken from what had to be a confused manual since they did not match up for the clock speeds. When the due correction was applied (0.985 to 1.02 and finally 1.023MHz) it was finally pitched correctly. The trigger events for the SID MOD Env were not really correct. Any accepted note_on event would cause them to trigger however in light of the way voice separation happens it really required that the Env was only triggered if it would have a affect on the given voice. There were a few cases, voice goes via the filter and env modulates the filter or if the Env modules the voice that is being activated. Added the logic. Voice-2 arpeggiating never triggers the envelope, only its own envelope. Increased the minimum Sidney arpeggiation step, it was a ludicrous 0.3 ms, it is now a more reasonable 16ms. Maximum stays the same at roughly 250ms. The Sidney emulator had an issue with some memories and its keymode settings, the indexes were not converged correctly resulting in the radio buttons not working normally (double selected radio buttons). The OB-Xa 4-pole filter was incorrectly mixing its feedback loop, silencing the output signal. The 2-pole worked correctly. The MIDI library was altered such that all messages now carry a sequence number, it's only u32 but its only use is debugging events and with the typical event rates this will last far longer than any session. Also finally fixed the event timestamps which were previously just null. The midi and audio threads had different scheduling algorithms, one was FIFO the other RR. Since the two threads used semaphores for a critical code section for note events then there existed the possibility that the midi thread could cause large delays to the audio thread by taking the semaphore and then getting pre-empted. The fix was pragmatic, both thread have been made FIFO with different priorities. A full fix would also have been to adjust the thread priorities in the critical code however the current fix works except when there are multiple RT programs running and that should only be the case if they are all audio threads. 0.40.2 05 May 2009 Maintenance release, usability improvements. This is primarily maintenance for the last couple of releases including fixes to the SID emulator and some ARP improvements. The SID synth has more key assignment modes, both arpeggiating, visible in the GUI as Arpeg 1 and Arpeg 2. They will split the keyboard at MIDI note number 52 then assign two voices to one half and one voice to the other. Arpeg-1 has its function on the upper half, leaving the lower half as a duophonic synth allowing an arpeggiated chord as rythm for a bass sequence. Arpeg-2 will do the opposite, it will arpeggiate on the lower half allowing for arpeggiated rythm with a duophonic lead solo. These were seen as an improvement over the previous but the results need to be reported back. Bristol will now check the system for the availability of the TCP control port, defaulting to 5028. The application behaviour has always been that an engine is attempted every time the application starts and correctly speaking if a user wants to work multitimbral then the second request should be given the -engine option. Without this flag it still worked but was sloppy, the second engine would fail to get its control port and so would exit, the second GUI would still connect to the first engine and start a second emulator. The current behaviour is that each time the application is started it will look for the port availability and if it is already taken then an upwards scan is done from the port number looking for a free socket. The port can be specified explicitly with the -port option if fixed ports are required however this is not a real requirement if the -audiodev is used with Jack, for example, to specify the registration identifier for the new engine. If no engine is requested the GUI will just attempt to connect to the specified port although arguably it should check to see if the port is open - this is kind of done implicitly when the GUI attempts to connect to the port. Extended the BRISTOL_AUTOCONN by adding the following environment variables, BRISTOL_AUTO_LEFT, BRISTOL_AUTO_RIGHT and BRISTOL_AUTO_IN. If these are set they will be searched in the relevant ports list and then connected up. This only happens in conjunction with AUTOCONN. On my systems this was tested by setting them to system:playback_1, system:playback_2 and system:capture_1 resprectively, and by leaving them unset. Will see how much use they are, since they are environement variables then to be useful they would have to be scripted. Submitted code to repaint transparency layer devices when windows sizes are changed. This affects shadow layers and transparencies (such as the ARP 2600 patch cables). Prior to this the objects painted on to this layer were lost which was confusing with the ARP at least. The effort to do this was considered preferential to the alternative which was to fix the window size once defined, not allow resizing and just have the -scale option at startup. There were some compilation issues due to the SID test program not having the correct dependencies. Removed sidtest from the distribution, it is no longer required, it was only used to exercise the bristol softSID chip until it was integrated into an emulator, now done. Known issues are that the Pro-10 would fail on some systems. This is a very specific issue as some systems have been reported not to suffer from the issue. A workaround is in place however a longer term resolution will have to be sought and a bug is open against the issue. 0.40.1 25 Apr 2009 Commodore C64 SID emulator This release introduces an emulator for the Commodore C64 6581 SID audio chip. The implementation has a digital access method to program the chip registers and an 'analogue' access method to extract the audio signal. The oscillators and envelopes are implmented with integer functions as the original was partly digital, and then the filters are in floating point to emulate the analogue components. Specifics of the chip will be in the README file presently. Two of these chips were then used for a bespoke synth, the -sid. This is not based on any original design but exercises the SID emulator. One of the two chips gives the audio output, the second gives signals for modulation: one LFO, one Env and one noise source which can be as an input to a S&H circuit. This design uses a few different voice allocation routines, monophonic, three voice polyphonic plus some combination algorithms to give access to the high frequency arpeggiation used often in the C64 where a single voice would do a fast scan of several frequencies to give chords and widen out the sounds. Each of the three voices can be programmed independently. Added an environnment variable, BRISTOL_AUTOCONN, which when set will direct the jack library to autoconnect its ports to the first IO found. This will not be much use for general users however it will make testing easier. Fixed an issue where the emulations would fail unless started on midi channel 1. The issue was caused by the Globals settings using a system connection id rather than the negotiated midi channel for setting up diverse defaults tables. 0.30.9 02 Apr 2009 Bristol BassMaker, massive filter optimisations. Coded a 16 step, 4 page sequencer along the lines of the SQ-10 to generate bass lines, hence the pun. The overall feature set it pretty sparse since this is not intended to be a general purpose sequencer. Each step has a note, transpose, volume for the MIDI note and a Control option to send fine tune, mod or another MIDI note on a second channel, plus the triggers can be skipped to join notes. The control features have not been widely tested and may need some fixes. Also the fine tune and glide when applied to the Control setting are a little dependent on the emulator, something that can be altered if the is a demand. A full description is in the README file. Colin Fletcher optimised the huovilainen filter code, first factoring out kfc to reduce the number of multiplications being executed, then continueing with completely factoring out v2, and since it was generally used as a divider function this was a considerable CPU overhead. This delivered a massive improvement in the CPU utilisation, not only of the filter but the emulator generally due to the filter being so CPU intensive. The factoring out of v2 was ingenious since it was not immediately evident from the code that this would have been possible. Testing this also corrected some anomalies in the OBXa filter selection code. About 5 superfluous variables were stripped out of the filter code to reduce parameter popping and actually improve readability providing minor improvements in the filter efficiency. Applied noise injection code generally to prevent filter denormals with low to zero input signal. This is quite efficient noise generation code so should not have a big affect on the optimisations and prevent 100% from denormals. Another optimisation was applied to the filter for higher sample rates which removes the internal oversampling. At the higher rates this delivers around 40% reduced load and should not result in any loss in quality since it only applies when playing at 88kHz or greater where the filter response is still good to over 20kHz without resampling. Not all the emulators will actually use this code modification since it is only in B_FILTER2 which is sparsely deployed at the moment, something that will change as the different modifications are qualified. The result of all these optimisations is that this filter code should be about as fast at 96kHz as the previous one was at 48kHz, and as the filter code currently uses the vast majority of the emulator cycles then it is probably possible to run any of them now at the higher sample rates with little affect on net load. Applied some reduced EQ to the Hammond B3 Bright signal levels. This kept the same rough profile however the overall signal level was far in excess of the existing normal gearbox. This was required due to some big reductions in the crosstalk levels of the normal gearbox leaving bright as too loud. The changes to the crosstalk was required since the net amount was superfluous and although it brings some nice overdriven sounds it was excessive for both of the configurations to have that amount. Bristol no longer implements any Jack port auto-connect per default. After a trail of submits to LAU there were very good arguments as to why having default connections always being applied is a dangerous feature. The auto- connect remains but has to be requested with '-autoconn' although admittedly this does make it a fairly superfluous feature. The VOX Continental M2/Super/300 was silent. The global parameters page had zero set for all parameters that needed corrections to the memory loading code to force the save settings into the active set. The Polysix emulation would clip excessively with the modgroup was routed fully to the VCA. The signal gain from the LFO would result in an overdriven output. Reduced all the respective output stage signal levels, which are still quite strong anyway, and also some of the tremelo depth when mod routed. This will have a minor effect on some patches. Incorporated Andrew Coughlan's manual page for the Polysix emulator. 0.30.8 20 Mar 2009 Maintenance release, ARP 2600 fixes. When using Jack as the MIDI interface it was possible that the engine would attempt to link audio to midi channels and vice versa. The requests fail and do not break anything but the default connections don't work so its not quite as plug-n-play. Added code to check for the port name and also to parse the whole list of outputs for the first two that will link up, similarly all the inputs later. Resolved a strange issue with the ARP 2600 with respect to discrepencies between the GUI indeces and the engine indices. The problem did not show up on all systems and the root cause was being masked by a programming error in the engine using an incorrect scaling for parameters passed to it. The problem was not evident on all systems probably due to differences in type casting - the parameter is delivered as a float however the index is taken from that cast into an int with a range considerably wider than '1.0'. The fix also required changes for removing cables. The ARP 2600 filter and amplifier outputs had a signal level far stronger than most of the other components, this came from reworking the general filter input/output levels to ensure it was being driven correctly. Added in a bit of normalisation code to even the levels up. The ARP 2600 filter would also suffer denormals if all the inputs were move to zero. Almost to be expected due to the DSP involved in the filter. The initial fix is to inject about -96dB of noise if all the inputs sum to less than that. This has the nice side effect of making the filter self oscillating at high resonance, that was not previously the case. Reorganised the ARP 2600 volume options. There was a single 'Global Volume' that just drove the output stage. This was broken in several ways. Firstly it was in the memory which was a mistake to start with. Then it did not function as per the original where this single control was called 'initial volume' and was a kind of drone level for the VCA. To correct this the parameter was separated into 3 controls: Global Volume which is not in the memory, Program Volume that is in the memory, and Init Volume to allow the VCA to drone. It is noted that droning in polyphonic mode is messy however not having it with mono mode did affect capabilities. The BME filter tracking keyboard selector did not function to expectation, the tracking was either off, or honoured along with the mod group which was wrong as these are exclusive options. The X11 library will now only handle single configure events at a time. These are typically window resizing that come by the boatload due to mouse motion and if they are all handled at once we tend to get active sense failure and the engine (then the GUI) exiting. Reduced the B3 drawbar crosstalk values for both gearboxes. The previous values worked but the signal to noise (crossbar leakage) was excessive. The bright gearbox settings are still quite rich in harmonics giving a reasonably overdriven signal but the normal gearbox is now not so noisy. Distributed Andrew Coughlan Polysix patch 23 and added his sample to the website. 0.30.7 02 Mar 2009 Baumann BME-700 Build a BME-700 emulator. This is a rather rare synthesizer and is probably the best example of where an emulator makes sense, it would be pretty much impossible to get ones hands on one of these. The emulator is in its first build and the oscillator may well need some improvements. Future work will also improve response with higher samples rates by removing the internal oversampling code. To test this emulator try the options startBristol -bme700 -mono -hnp -retrig This will give a monphonic emulation with high note precedence and envelope retriggers for any note change. Added a velocity flag to the monophonic key logic such that velocity may then optionally only be taken from the first note in a legato sequence rather than from every note in the sequence. Option is called -lvel. Monophonic triggers were a little broken, the current fixed code will either always send a retrigger when the voice moves to a different note with the -retrig flag or will only send a trigger for the first of a legato sequence. The Korg MonoPoly emulator would crash. The new synchronisation code did not check for a null sync buffer and some of the emulators would pass a null buffer if sync was not configured. Related to this was reassignment of the -mono switch to be 'monophonic', equivalent to '-voices 1' rather than as an acronym for -monopoly. The switch was reassigned to make the monophonic note logic more sensible. Prophet bank select was broken, code was adding incorrect offset into the selection algorithm. 0.30.6 22 Feb 2009 Monophonic note precedence key logic. The note assignement logic now correctly implements/emulates a monophonic keyboard with low note precedence (-lnp), high note precedence (-hnp) and last note precedence. Previously there had only been code for last note - it was the polyphonic algorithm with just one voice however this gives a completely different playing style. The option only works when the voicecount is set as a single voice. Additionally there is a -retrig option to trigger in both directions when playing legato style. The code is interesting since it was firstly a little awkward to do and also since the final solution was to have the monophonic synth start playing its single voice and then just keep the voice rolling forever. It stacks up the CPU constantly but gives some useful features with the ARP 2600 and Moog Sonic-6 (and others) for droning or just tweaking them without playing and is arguably a closer emulation of a real mono synth. The voice, once assigned to a mono synth, should not be preempted by other emulations, ie, it becomes dedicated. A present release may make hnp and retrig the defaults for mono synths, and similarly invoke a single voicecount if precedence is requested. For not you will probably want to use -hnp/-lnp and -retrig to get useful results. This release might include some monophonic note logic debugging output, it will probably stay there until 0.30.7/8 depending on testing or bug reports. Finalised the frequency/step tables and moved on to implementing glide for the non-resampling oscillators. The oscillator already supported this but the frequency tables were needed to correctly fill the buffers. Poly-800 parameter #67 now controls glide for that emulator, previously not operable. Reworked all the filter code keeping only the Chamberlain and Huovilainen. Then reworked the Huovilainen for 2pole/4pole (non-resampling versions later). Put in an Oberheim modification that remixes the different pole outputs back into the main signal path. The mix is configurable however the GUI has no control that drives it: a default value is taken. The filter is a bit richer for the mix. This mod was at least considered by Oberheim for the Matrix-12 but then never implemented as the discrete circuits with quality components was a bit cost prohibitive. Here is is relatively simple work and since the filter is already computationally expensive this operation does not add much to the CPU requirements. Different codes sections use different mixing loops. The main one puts the tapped signals into the output stage only, others will mix it back into the filter feedback loop which give yet another quality however it also suppresses resonance due to the resulting phase complexities. [As a note, the application still implements 3 other filter types, the rather weak rooneys and a butterworth. The ARP also has its own lag filter for voltage processing.] The Arpeggiator/Sequencer code would leave voices hanging after the operation terminated. This was kind of known, start/stop just set the emulator flags to allow the code to be called. The resolution was to actively deschedule all voices associated with the arpeg/seq function. The LFO changes to 0.30.4 to increase the maximum speed did adversely affect a number of memories and, rather than back them out, this version introduces parameterisation to set the upper and lower limits of the LFO with defaults that were as per 0.30.3 and below. The new emulators that want to use LFO up to ranges that verge on FM functionality will request wider ranges. The default values should go from 0.1Hz to 20Hz in line with the previous releases. Build options was damaging the LD_LIBRARY_PATH where jack libs were included before the newly built library path. The result was that rebuilding the code would probably find the installed libraries rather than the new ones. The Hammond was loading excessive memories on switching the opts panels in and out, added some flags to prevent this. 0.30.5 01 Feb 2009 Maintenance release? Worked on a slew of new (short) recordings for the website, fattening out a few of the exising memories. This lead to some issues with sound quality in some emulators. These would have been fixed earlier if I actually used bristol however most of the work is in development rather than operation. Most of the sounds were configured in a matter of minutes, more work would have improved the depth but they give an idea of each of the emulations that were recorded. These short recordings highlighted a few anomalies in the code, and along with some other issues that have been gathering over a few releases the rest of this release is a set of fixes. There were apparant envelope clicks on the axxe emulation, primarily on note off events. This was due to a direct 'gain' level being mixed in with the ADSR. Corrected it with a grooming envelope on the key however the ARP lag processor would also have done this trick quite well. Applied the same change into the Odyssey as it uses a similar gain section on the amplifier. The 2600 is not affected by this since it uses patching to get around the amplifier rather than fixed signal gains. PWM on the Arp DCO was failing, affecting all the Arp emulations. The cause turned out to be a mixup with the min and max limits for the pulse width, something that was introduced when the corrected sync code was introduced in release 0.30.3. Fixed a key mapping issue where the '\' character mapped to key id zero rather than two semitones above the ']' key where it should really have been mapped. The changes are in the text profiles so could have been done locally in the event of complaints. Apart from that the mappings only cover a US QWERTY keyboard anyway. Some of the keyboard graphics were damaged during the redesign for the Poly-800 giving incorrect redraws for the 3 octave emulations. The Poly800 GUI had a typo that stuffed a non-zero termination signal level into its DCO-2 envelope causing clicking if Double was selected. A separate issue occured with the filter envelope that was not retriggering correctly, resolution was to configure this one envelope for re-zero and will have to see if it needs to be done for all of them. The duplicated raw audio output code does silence suppression however this was only intended to be for leading silence. It was implemented as a cheap way to get sample for the website but it was doing permanant silence suppression which damages the audio in most cases. Added a -mbi option and structure entry to the GUI for memory supersets that came as a side effect of reworking just some minor details of the polysix options (the -load worked however the GUI did not reflect the true memory). This was rolled into general use however some emulations already use local methods to manage this. This will only conflict if the global method is requested and it also affects Chord and Sequence memory as that does not access this parameter (yet). This is a single digit parameter adding that number of K to all memory access. Memory #1 with '-mbi 2' accesses memory #2001 on disk. The option is additionally set from the -load setting, if a memory above 999 is requested then mbi is stuffed with the most significant part and the memory index is the remainder. Revised the LFO to have a range from 0.1 to 100Hz for a pending BME emulation. The rate control is a power function so it should not affect any existing memories excessively. Broken in this release and until further notice is the -glwf option, it causes note vocalisation errors. The -lwf option should be used with each emulator to activate the lightweight filters individually rather than globally. 0.30.4 20 Jan 2009 Korg Poly-800 Built a Korg Poly 800 which was more work than anticipated. The GUI needed to have a 'membrane' support for the parameters which generally takes quite a lot of effort, perhaps less since the bit-1 already had much of the code. Another envelope was built as it is a 6 stage design however that is reusable for the pending Yamaha CS-80 that has been under construction for a while. The Poly800 emulates all the dual/single oscillator with an envelope each, plus the single filter design was integrated into the emulator PostOps() routine as well as the Poly code so that there can be a single high key tracking filter as per the original design or you can have one per voice as a bristol mod. The full set of mods and general construction are described in the README file, the only remark here is that the single filter code is a bit jumpy when the notes change by large amounts, something that could be improved. Added modifications to the bitone oscillator such that it integrates a separate sync output. This is at the base frequency with a resampled squarewave only, allowing this complex oscillator to still drive sync into other oscillators. Tested with the Crumar and Jupiter emulators. The same modifications were rolled into the explorer DCO since it also generates some combined waveforms that could distort the sync algorithms. Reworked the bitone oscillator to generate what I am for now calling waveform tendencies. The output signal will tend towards a target value under a kind of discharge circuit at a controlled rate. The result is a non-resampling oscillator, more or less, the wave is generated based on algorithms rather than wavetable resampling. The results are at least harmonically unique within bristol, at the moment only integrated into the Poly-800 emulator. They sound reasonable when heavily filtered, a little raspy otherwise. The nice thing is that they are still quite efficient (will change as the waveform heuristics develop), costing only a few percent for the generation of 8 oscillators each with 8 strands of tendencies, all slightly detuned from each other to give a quite rich result. The oscillators can generate square, ramp, saw, tri and sine with support for PW/PWM of the square, sync in/out on ramp/saw/square/tri. The triwave sync is correct softsync, the rest are hardsync with waveform inversion as required. The efficiency lends itself to oversampling which in turn could make the Huovilainen oversampling filter more efficient and give a net improvement in the sound at very little cost however that is FFS and will not be done until after the P800 is released. Integrated a new noise generator which has better performance and also a cleaner overall signal. The previous code has some excessive LF components. The Preacher gearbox was a sixth out of tune, 8 semitones. Pretty strange it was not reported and I admit I had not noticed it. The default gearbox seems to take the wheel indeces from an incorrect starting point. This also brought to light another issue with the same code. Since the user profiles were enforced recently then the tonewheel mapping file had to be in ~/.bristol and was not shadowed back to /usr/local/share. This would have caused some issues with the tones rather than the frequencies. Built another set of keyboard layouts, this time for the Poly-800 but may get rolled into other emulators later. Check Button devices would still dispatch an event if the mouse is released outside the bounds on the device. This should not be the case so checks were added for limits before callbacks are made. There was a small window when killing the app during initialisation could leave the engine waiting for the audio thread forever. It should all exit so added some timeouts to the status polling routines in the midi thread. Key bindings were not being read for library testing. Not an operational issue however it needed a fix for testing purposes at least. The pitchwheel and its associated Registered Parameter were not working in unison, had to reorganise their internal variables and the frequency calc code when changes are made. Reworked a few more shade layers and put the new key designs into a couple of the other emulators. Configure will now prompt the user to install libasound2-dev as well as libx11-dev if either are misssing. 0.30.3 19 Dec 2008 Crumar Tilogy, PWM and Sync fixes, Polysix improvements Added the String section to the Stratus emulator to produce the bigger brother of the pair, the Trilogy. As with the Organ section of the original, the string section is not a major feature and was nothing to write home about. The code adds some extra harmonics to fatten out the sound plus some panning and spacialisation to enhance the section. The features can be disabled to give a more authentic emulation of the original. Changed the graphics on the Stratus synth waveform selector, it was not a true mix but a three way switch. The graphic is emulated however the control is still continuous here. The default memory for the stratus had a bit too much key tracking configured and it shut off the filter completely for the lower octaves. Fixed some minor issues with the Stratus options panel. Took excess debugging out of Trilogy/Stratus code. Touched up the shadow layer for both these emulations. The Polysix mg controller side affected the oscillator frequency. The wheelmod should just affect the overall depth of the routed LFO, it was doing separate mod for vibrato which was undesirable. Also changed the default switch for the polysix from -poly to -polysix and -poly6. For now it will respond to both. This was an unfortunate choice originally and will presently be dropped to just the newer options. Similarly changed the Korg Mono/Poly switch to be -monopoly from -mono, also an unfortunate historical choice. The polysix waveform selection was actually wrong regarding Square and Pulse wave - square is a fixed wave that only uses a PW control to select its width, the pulse wave uses the same setting but adds PWM via another LFO, these were out of sync. Thanks to Andrew Coughlan for the insight whilst working on a Jens Johannsons lead sound, apparantly originally done with a Polysix. Andrew's patch also showed some issues with parameter memorisation for the operating modes: Poly and Mono mode could be lost on reloading a memory, now also fixed. Added in some diverse changes for the PWM code, historically the width has been an integer value in the range of the size of the wavetables and at least for some of the oscillators this was still being managed as an integer. The pulse width is now floating point and the resampling is independent of the main waveform being generated. The difference is only subtle since the original code resolved to better then 0.1% accuracy already however it did show up a couple of bugs in the prophet DCO code regarding offsets and brought to light the noise on oscillator sync with certain waveforms (notably square) that really also need to be addressed but probably in the next release as it really needs triangular (soft) sync as well as hard sync. Fixed a long running issue with oscillator sync, namely that it worked but very badly if the synchronised wave as a square. It was always ok with ramp for example. The cause related to how sync was being done, it was just resetting the resampled wave table index to zero, correctly speaking it needed phase inversion as well, now implemented. The synchronising wave is also resampled before it goes to the synchronised wave to remove the flutter or shimmer associated with synchronising to whole samples, it basically synchronises to subsamples. Phonically this is a big change and it may be rolled back into 0.20 since 0.30 is still relatively new. Alterations for this fix are still needed for bit1osc, it generates complex waves by default and they are not very good for sync signals. For now users will have to simplify the synchronising wave, a future release will have the oscillator generate a sync output signal at its base frequency. 0.30.2 15 Dec 2008 Crumar Stratus This release has an implementation of the Crumar Status 'duosynth', it used an organ divider circuit to produce some slightly lacking organ sounds with four harmonics of pure square waves plus a six voice poly synth. The organ circuit has been beefed up considerably - it can produce the same square waves however adds in alternatives (square and sine through ramp, smoothly) and some added stereo spacialisation. The interesting synth glide circuits are emulated, this is not typically polyphonic portamiento since this beast used organ divider circuits for the oscillators so independent glide on each voice was not possible. In contrast the circuits could be over and underclocked as a note starts then glide back to the target note, here emulated polyphonically. All the legato features should work - the LFO in mono mode will only strike open the LFO envelope grooming circuit once, the glide features will work in a similar legato fashion and the oscillator output can be kind of random with legato. Improved the oscillator sync algorithm however certain waveforms are still noisier than they should be. This was only in the Crumar Stratus oscillator but the alterations can be moved over to the other synchronising oscillators when finished. Altered the filter keyboard tracking for the Huovilainen to try and get better tuning. It can be made playable however that still takes quite a lot of tweaking so a few more changes are likely over the coming releases. Put the reverb back into the Sonic-6, will see what people make of it as it only works well with fat sounds (B3) or at low delays. Reworked some of the button control logic since they were not being set when withdrawn. The logic for withdrawn should really be just 'don't draw' and this was corrected. Reworked some more off the graphics for better drop shadow on the keyboards. 0.30.1 03 Dec 2008 Voyager Electric Blue, Moog Sonic 6. Voyager Electric Blue released in conjunction with some fixes to the existing explorer algorithm as detailed below. Moog Sonic 6 released, the suitcase synth. There are diverse differences with the original, implemented largely because they were denoted at the weakest points of this fair synth: Added a mod wheel that can drive GenX/Y. PWM is implemented on oscillator B Installed an ADSR rather than AR, selectable. No alternative scalings - use scala file support The emulation is not duophonic. Primarily poly with separated glide. It does have the same 'diaphonic' capabilities although they were pretty dubious in the original. Details are in the README file. There are sadly few memories configured in this first release, none in fact. The Sonic-6 implementation was the first new algorithm in a while and it has shown a few issues with gain levels regarding the filter output. This lead to a few more alterations to the normalisation of diverse emulators but it should fix the issue of filter resonance overdriving the outputs and causing clipping. It should now be a gentler easy sine wave, probably still quite strong but it should not cause clipping with most emulations. The Explorer code needed to be reviewed for a changed filter set and filter characteristics, the original stacked LPF was wrong. The code needs to have either serialised HPF/LPF or parallelised (and then stereo) LPF. This was worked into the code and an interface put together to emulate the 'Blue Ice' version of the synth. Reworked the Release parameter of the Voyager/Explorer. The existing code either configured the value or just '10' depending on the release switch. The correct coding is to either send the value or a small part of the value based on the switch setting, closer to the original. OSS drivers were broken due to a failure to convert some of the device flags correctly. The result was no subfragmentation and no subfragment buffer. Only tested with ALSA compatibility mode. Reworking the drop shadow step by step on the piano keyboard. Gives a better effect. Minor changes to the options for the different Prophet emulators. The 0.20 stream is now maintenance only. 0.20.10 27 Nov 2008 Maintenance release. Altered the permissions on the memory files and pixmap files since some users would have had problem accessing them. That would have made memories unreadable and given some incorrectly painted images. There were no complaints however it probably would not have been totally obvious what the problems even were. OSS drivers were broken due to a failure to convert some of the device flags correctly. The result was no subfragmentation and no subfragment buffer. Only tested with ALSA compatibility mode. 0.20.9 14 Nov 2008 Maintenance release. Changed the lightweight filter option to be emulation local rather than global but kept the global option now as -glwf. This allows for mono lead synths to have a thick filter and the rest to have the lower cost Chamberlains. Added an option to prevent the user interface from requesting window sizes to the window manager by default used to ensure that the aspect ratio was some kind of reasonable match to the original however this causes problems with some tiled window managers causing endless redraws. The -ar or -aspect option will just make the library paint into whatever available space is given to the GUI - the results may look gruesome if either the height or width is excessive. Added code to the XPM reader to look for *.xpm.gz and then to gunzip them first to /tmp. This reduces the installation nearly by a factor of 5 and is minimal overhead an this is only in the startup routines. If the bitmaps are manually decompressed then the overhead is avoided as the xpm is then found first. It probably needs to be noted that the benefit of having the gz images will only be seen if the previous installation is first removed. If not then the .xpm and the .gz will remain. Alterations to the diverse blueprints, most notably the MS-20 however since that is not yet functional it was a bit superfluous. The following synths still need some filter work: -explorer - moog voyager. Needs more work (*) -cs80 - Yamaha. Needs more work (* and is unfinished) * needs to be two separate filters, Chamberlain HP into Huovilainen LP. Added some checks for the number of options being given to both bristol and brighton, and if they are too few to then advise using startBristol and exiting. The goal was to advise on what should be done if somebody just attempts to use the binaries without the wrapping script, and since the script uses a host of default switches it doesn't cause these messages to print. Resolved a long running and annoying problem with closing the GUI windows - when the close is requested from the Window Manager [x] button (typically in the top right) the application does not exit as fast as it should. Had to set some WM attributes and do some more checking for Client Messages. Also had to clean up the code to terminate dual manual synths, something that became evident once the shutdown did not require a ^C in the controlling terminal. Improved the state logic between the threads such that if the audio thread cannot get hold of the target audio device then all threads will exit. This was giving problems since previously the parent thread would not exit even though the audio thread had failed. Recovery was then a manual process. We do not need to apply similar logic to the midi thread since if that does not open we will never proceed to the audio thread anyway. Known issues: Starting two mini on the same engine will seg fault when one is closed. The buffer pointers are cleared incorrectly. It will probably be a trivial fix: not to free the buffers on exit. The floating buffers are little overhead and will get reused if another emulater is started. 0.20.8 28 Sept 2008 New filters, normalised gains, diverse fixes Integrated the Huovilainen filters into the full set of emulators. Some still have filter options that may use the Chamberlain however that may change by converting the Huovilainen to a 12dB/octave option and using the Chamberlain for lightweight filters, BP and HP: Added an option for lightweight filters where the CPU intensive Huovilainen are replaced by the colder but a lot less expensive Chamberlain, -lwf. Band limited oscillators are now the default with up to 31 harmonics. The previous geometric waveforms are still available with '-blo 0' however their roughness was highlighted by the reworked filters. A few emulators do not use the global wave tables and will not inherit the BLO option but they should all use other distorts to reduce the edginess of infinite bandwidth waveforms. Normalised the signal levels on most emulations. This was lead by the Pro One developments since it gave a reasonable signal and was used to baseline the other emulations. Converted glide into a power function to give better control at low values. Converted attack into a power function to give better control at low values. Pitch wheel depth was half a semitone out of configured value. The default of 2 was being misinterpreted. Rhodes was damaged due to a conflict in operator selection since the code for the arpeggiator was finalised. The Chorus controls would select ARPEG code and that would eventually cause issues. Noise was inadvertently mixed in the Mini algorithm, passing through the reused filter buffer. Fixed this and other anomalies with mod routing. Mono emulators appeared to drop new notes when played quickly. The actual cause was a loose coding of the note_off logic where an off event would match any voice on the channel even though note_on had reassigned the voice a new key. This only happened if the note_on voice was still on the newlist waiting to be promoted onto the playlist. Normalised gains and integrated Huovilainen filters to other emulations. 0.20.7 29 Aug 2008 Sequential Circuits Pro-One, Scala tonal mapping tables, overhaul of the Prophet-10 Built a Sequential Circuits Pro-1 as a polyphonic emulator. There are some differences in operation compared to the original. Details are in the README file. The Prophet-10 needed some work primarily on layer management. The original had a few features for in-memory volume/balance/tuning, a sequencer and the memory bank functionality was organised differently. These were all worked into the emulation. The sequencer is a lot simpler than the original but can function with a sequence per memory and adds the ability to arpeggiate and to chord notes. Also reorganised the 5/10 voice management since it was a little incorrect previously and realigned the midi channel utilisation. Reworked the hammond drawbar device to support fully painted images and used that to render a new ModWheel dev with a rolling tooth design for the Pro-1. It could be improved with a local highlight rather than using the global shadow layer, something for future study. Reworked the rotary pot to support limited motion from -60 to +60 degrees with stepped movement for the Pro-1 octave selector. This could be used in the other emulations however the general use was for waveform selectors and the problem here is realestate to show the waveforms - without the full rotary action the diagrams will not fit the available space. Mono, Poly now also use it for octave controls and waveform selections requiring a bit of redesign of their blueprints. Also put into the LFO waveform selection of the Jupiter. The work also included redrawing code the complete rotary to support irregular designs. This was required for the tip of the ProOne pot that sticks out. Added a parser for Scala .scl files to build a microTonalMap for the synth. It is possible to retune the synth based on the thousands of Scala maps. The option is '-scl ' where the file can be a full path name (leading '/') or if the mapping file has been placed in the $BRISTOL/memory/profiles directory it can be a "filename.scl" or just "filename". The settings are global at the moment and there is no default scala map although that would be possible if people were interested, or a default per emulation for example. Added another two taps to the Hammond chorus organised such that there is a unique tap sweep per VC rate. Each sweep is offset against each other and for chorus then either 1, 2 or all 3 taps are remixed with the original signal at a configurable mix level. Changed the scan betweeen taps to be a more gentle sloped fade rather than a linear transition. The scan delay and LC are user configurable parameters and the tap scan time also to alter the overall speed of rotation. Altered the addition and subtraction of taps to fatten out and smoothen the sound. Reduced the spread of the taps since they are only interesting at low delays. Filled out the lower scan ranges so that they at least always scan between taps. It no longer sounds like it has a broken cap. Added a build option to configure: --disable-jack-midi. There were complaints of interoperability with the older jack MIDI libraries. I do not want to support the previous releases and this is the lowest common denominator to allow the application to at least build with the 0.103.0 API. The complaint is "too few arguments to function 'jack_midi_get_event_count()'" or similar. The audiodev name is now used for jack registrations. It is defaulted to the program name when jack drivers are requested and then overwritten if given as an explicit option. This allows visibility of each invocation of bristol into jackd. MS-20 was packing too many panels. Cleaned it up and added in the new ModWheel however it still does not work - should move it along a little bit. Minor bitmap manipulations for some resizing misfits using the -scale option. Added some more output text for cases where jackd could not be started however a review should be made of the the audio and midi thread status selections to make the operation smoother. Fixed some issues with detuning (sensitivity) where if not initialised it led to unexpected results. Put in limits testing in bristolMidiSendMsg(), something I did not want to do preferring a well behaved GUI however it has lead to issues during development that would have been nicer to have avoided and its at very little cost. The per user private memory cache should now be enforced, this should allow people to keep their private memories over reinstalls and upgrades. Prior to this the cache was only used if the directory structure was in place however that is rather unwieldly for most users for the current number of emulations. 0.20.6 13 Jun 2008 Band limited oscllators. UI Heartbeats, GUI scaling. Added in band limited master waveform tables for the base waves: square, tri, ramp/saw, and a sine wave just to be complete. These were then pushed into the diverse oscillator code for most of the emulations. The results are a lot smoother if a sufficient number of harmonics is used, '-blo 21' or more, however smaller values also give interesting results. The Mini is generally improved by not having the 'infinate bandwidth' geometrically correct waveforms, the sound is softer and warmer with relatively few harmonics. The next work on the sound generation will need to go into the filter. GUI now sends active sensing updates to the engine. This means the engine can detect UI failure and exit rather than hang around and damage the next attempt to connect (with the same MIDI channels, etc). There is one timer to control the rate at which the GUI sends updates and another time for when the engine will decide to stop the emulation. The GUI can detect failure of the engine the same way - the write operation of the active sense will fail if the TCP connection terminates at the remote side. The code could be improved, it should actually scan the list of synths however it is pretty trivial to extend it later. The reason is that the heartbeats are per emulation rather than at the top level however the generation of the heartbeats occurs in the GUI in a separate MIDI thread and hence is at the top level. GUI now has a -scale option to presize the window. Default remains 1.0 and at large scaling will automatically enable aliastype 'pre'. This can be overridden with -aliastype none. There were too many remarks about the diminutive size of the GUI and whilst the author likes the size this option improves usability. Started work on a Yamaha CS-80. Backing of Realistic MG-1 was offset since the prealiasing code, needed to be corrected (actually had a third layer still packed but not used). Explorer glide was not working due to changes to the operator indeces in the emulation not being mirrored in the GUI. Change the max device ccont from 128 to 512, already under the limit with some of the synths probably leading to a few of the crashes I have been seeing. Applied build patches from Alexis Bailler's gentoo packaging. With antialias and mobile devices (sliders) we need to repaint extra pixels during move operation or the 'blur' starts to stain the image. Fixed with some minor alterations to the Undraw code extending its range by a pixel on the X and Y axis. XImage creation failure now suggests using the '-pixmap' option but its almost a case of better never than late. I could consider changing the flag and then attempting the load again however this may already be a non-issue (was a broken 64 bit X Server issue). Introduced a lever operator that changes its size at it moves up and down its scale. This was for a part of the CS80 code. Added a configurable timer into the GUI host code midi scanning period. Horizontal scales needed redrawing fixes. 0.20.5 20 Apr 2008 First release of the Jupiter-8 emulation, GUI prealiasing, Vasiliy Basic's Mini memory suite. Integrated a 4+4 split/layerable Jupiter algorithm with arpeggiator, sequencer and chording function assignable per layer. Full write up in the README file. Changed the Jupiter design such that the VCO have selector buttons rather than single switches for register and waveform. This is not per the original but it allows me to make them non-exclusive and that will fatten up the sound. This functionality is more like the JP-6 and MKS-80. This code includes a Jack MIDI client interface. It is started with the normal options plus '-midi jack' so that it can be used in parallel to an ALSA link and TCP link to the GUI. The result is that the engine uses two midi threads, one doing bulk operations for GUI settings which might be quite slow, a higher priority thread doing Jack MIDI, and the highest priority thread doing the audio processing. Semaphores are implemented to prevent the threads interfering with eachother. Reorganised qwerty mappings for correct MIDI note selection and transpositions, brightonController.c confdev may need to be buried in window structures. Worked especially for a couple of keyboards that were not C-C. Implemented a prealiasing code which uses whole pixel blending. It is only applied to the silkscreens and gives far better imaging when the synths are resized towards fullscreen - they are still reasonably readable. Reducing the window size and normal size are a bit blurred. Configured with '-aliastype pre'. Reevaluated the arpeggiator step rates to go from 1Hz to 20Hz. The implementation of antialiasing allow threw light on some coredumps at very small window sizes caused by anomalies in the drop shadow rendering going negative due to the small sizes. Arpeggiator did not correctly terminate the note list when more keys than available voices were pressed. Resulted in hanging arpeggiation and holes in the arpeggiation sequence. Resizing windows failed on some emulations with the output signal going to zero: If some of the GUI settings did not match the engine before the resize then the sound will change. We should suppress all updates when resizing since no changes should happen to the engine. Resolved an issue with the -emulate and its interpretation of gain levels, they were a bit low. Touched up the rhodes bass graphics. Minimal, but was bored. Minor touch ups to the memorymoog, prophet, prophet52, axxe, odyssey, mini, explorer and rhodes shading graphics. Adjusted some offsets on the B3 to prevent some lines of transparency on resizing. 0.20.4 26 Mar 2008 Arpeggiating OB-Xa, fixes, synchronised threads. This is maintenance code however you may prefer to defer using it until 0.20.5 is released. There are numerous fixed integrated here however the midi note event management has changed considerably and there may be some anomalies in the implementation of the multiple dual linked listed that govern key assignments. The symptoms of such anomalies are potentially quite ugly if you run bristol with real time scheduling, the tight loops may lock your system so you may want to run it with '-priority 0' for no realtime prioritisation. There may be lots of thread and arpeggiator diagnostics that will also disappear in the next release but you can also use the -quiet flag to prevent them. Also, since the MIDI and audio thread now use exclusion then a very busy audio thread may result in what appear to be dropped notes: The note_on gets delayed due to system overhead but eventually generates a 'newlist' entry for the engine to process. If the note_off arrives before the audio thread has taken the newlist entry then it is removed before it even gets started. These actions are visible with the current debugging. A master keyboard should not be badly affected by this however the GUI can end up clumping together multiple events if the CPU load is high and that causes/exacerbates the situation. Reworked the OBXa for some stronger sounds with a couple of routing corrections. Overall sounds is a lot richer. This lead to changing the glide to be a log controller rather than lin, another improvement that will affect existing memories though. Will become a general capability. Fixed some flagging issues with OBX modpanel and layer assignments. Adjusted the mod mix and corrected the mod LFO rate controller. Should build some more OBXa memories as well. Rework OBXa dual/split options for single midi channel. Reworked some of the OBXa graphics including a shading layer ready for distribution. Arpeggiating sequencing now records under suitable control - only emulation with an interface is in the OBXa, Bit-100 but others may follow. The settings can be saved in a memory to be recalled and recoded to the engine. There is serious fun to be had now with the OBX-a emulator and sequencing/arpeggiation. Details are in the readme file but basically start arpeggiating and then crank down the filter envelope decay and play with the filter cutoff and mod level. Implemented the chording code as a small extension to the 0.20.3 sequencer. When enabled it will assign a voice to every note in the note list, transposing them as it goes. Worked the arpeggiator changes back into the Juno-60 code. Made the OBX-a Seq be once per voice rather than once per synth. The LFO rate parameter was converted to a log controller rather than a linear one, it improves response and allows for some very slow cycles. It will affect some memory settings. Glide also changed to logarithmic control. Arpeggiator rate similarly. The memory library was changed such that it honoured the active parameter when calling memory locations, something that may well have changed the characters of the other synths. Went through the code to clean up the obvious ones but should run through them all again. It is now possible to have the GUI search for an emulation rather than passing the emulation exlicitly. This is with the -emulate option. The feature also sets default voice counts, detunes, gains, etc, from the emulation such that the options such as "-voices 10 -emulate jupiter8" and "-voices 10 -jupiter8" are different - the first call would default the voice count to 8 from the emulator, the second would have the emulate inherit the explicit option of 10 voices and since we have not actually requested an emulation then the remaining options will not be taken from the application defaults. Installed some new key bitmaps, not sure about the results as they look a little surreal, almost chrome rather than ebony. Corrected some tv_usec comparison failures that were damaging the double click timers and defaulting to 1000ms only. The bristol ASLA seq interface would misinterpret note on/velocity zero. Caused some strange results with certain keyboards, and only with some bristol features (arpeggio) since it is correctly reinterpretted later in the chain. Also, the OB-Xa midi tracking would double strike with the GUI linked up to the master controller, the GUI was not honouring exclusion and retransmitted midi events already seen by the engine. Reorganise the transposition system for some emulations, they now correctly request the transpose to the engine rather than just scale their own keyboard. Both methods work and are arguably both correct however unless the engine is informed of a tranposition then it will not be audibile from a master keyboard driving the engine. This alteration needs to be reviewed as it separates the midi key id from the qwerty keyboard id's and that is awkward for anybody who wants to build their own mapping files. The mapping is now not qwerty key to midi key but qwerty key to GUI button index - for most emulations this is the key 0 to 60 on a 61 notes keyboard. Also separated the mapping table per window rather than globally - when the GUI goes medusa this will be required. Resolved another window timing issue with note on events at high load. This required using a couple of semaphores and was a big change to the note event management. It ironed out a few other unlikely situation such as running two monophonic synths simultaneously would give unexpected results - their note selections could get intermixed. The use of semaphores for mutual exclusion of the midi and audio threads was very worth the effort as it will probably be used to distribute load over different cores with multiple audio threads presently. Resolved a lingering seg fault in the DX operator with the bounds checking that was added and cleaned up the L1/L2 gain levels to be lin rather than log, the log did not work well for these controls. Fixed a heap corruption in GUI has needed addressing for rather a long time instead of providing a long term workaround. Resolved a couple of related issues with detection of pure blue from negative offsets that also caused segfaults that have been annoying me for a while. The workaround that had been in place for several releases was pretty ugly. Cleaned up some parts of the code that were giving in my opinion spurious error messaging during compilation. 0.20.3 05 Mar 2008 Integrated a new Crumar Bit-100 emulation Finalised the bit-100, some extra options, ability to save -1 and -99 memories. Restructured the rate algorithm for the glide, there were historical issues with its mathematical correctness. Additionally added a bristol NRP to allow the maximum glide time to be configurable. The default value was up to 30s however that often felt excessive and makes configuring short values awkward, changed this to be 10s with the ability to request up to 30. The GUI now responds to the -glide option per emulation and the Bit emulations have memory parameterisation. Added pink and filtered noise options to the BIT synths, defaults to white. The option 'white' could be dropped and turned into Pink with progressive filter. Added a flag required to enable NRP parameter changes in the engine. Default is now not to pass them for interpretation since it is a rather arbitrary interface and has been probably responsible for noisy interaction with some master keyboards. Diverse fixes to the BIT emulations: Layer volumes were damaged going into split/layer settings. Layer transpose, split and midi channel tracking needed some corrections for the different options. Specifically there are flags for supporting different settings per layer (per default they remain in sync) and these were not being honoured. The same fixes were required to ensure that non-aligned settings would be correctly returned after dual loading splits and layers. Layer parking was damaged (required writeThru cache enabled to work). Memory loading was damages for high ordered parameters. More issues with the high order parameters. Restructured the arpeggiator to cetralise the code ready to put it into the Jupiter emulator. Code inserted to allow the arpeggiator to hook into the midi note event dispatching to prepare it for reprogramming. Tested now with jack 0.99, 0.103 and 0.109 successfully. Updated copyright dates to reflect 2008. 0.20.2 25 Feb 2008 Integrated a few Crumar Bit emulations. Edited brightonButton for highlighted buttons, required repainting the control and could be rolled back into the brightonButton rather than being separate. Build a Crumar Bit-99/Bit-1 and an m2, all variations on the bit-99. Added several bristol features via data entry parameters. The capabilities and the differences to the original are documented on the website and in the README files with the distribution. Patched in a dummy audio driver such that no audio operations are executed. This may seem rather daft for a synth however working under virtualized systems often gives dodgy and unreliable audio interfacing so having a dummy lets me still work on the GUI to engine interfacing rather than limiting the work to the GUI. This is accessible with '-audio dummy'. Fixed an issue with port redirection and multilayer synths failing. NRP were being incorrectly interpreted which meant that emulation gains and detunes were not being registered. Velocity of note off events was being mapped into voice velocity as well as note-off velocity. This is incorrect as it causes jumps in envelope gains, etc. The correct behaviour is for device that want to use note off velocity should search for it in the correct place. The bristol ADSR does not adjust release rates by velocity however it could by using this explicitly. The envelope uses a power gain curve that is precalculated for lookups on attack/decay rates. It was a little damaged at the zero point and could cause 'inf' failures on some of the work being done, highly inefficient. Only seen in very rare cases and normally just during development since the code avoided using the limits. Corrected. Implemented OMNI mode however only the Crumar allow access to it at the moment. Transpose has been reimplemented such that the MIDI library is correctly handling the transpose. Previously it would lose track of some notes - press key 36, transpose 12 notes and it would not be able to match the note off to the original note on. The fix was resonable trivial and now the rest of the synths should also start using this method, something that will happen later. Velocity control has been added into the GUI so that it can be requested at start time per emulation. I should try and document all the 500 or so different mappings - the only references at the moment are the source code. 0.20.1 20 Jan 2008 First release of the 0.20 stream Designed a 7 segment red led digit display for the Jupiter panel. The original had an 8 segment display however the floating point was superfluous and has been left out. Compilation without jack or ALSA would fail dismally, the make routines would not pull out all the ALSA definitions. There may remain some issues since the OSS Midi interface does not seem to work, only rawmidi. If you really want OSS support with MIDI and all then mail the author. The changes altered the list of drivers, removing the Sun D-BRI and ALSA revisions prior to 0.9, both of which are now antiquated anyway. The remaining audio interfaces are: OSS (pretty much any release as the interface is stable) ALSA 0.9 or greater (SND_LIB_MAJOR=1) Jack 0.99 or greater There does not seem to be any jack version information available from the include files at compile time unfortunately, something that may be an issue with the currently new 0.109 release that appears to have altered the library interface specification. This should not be released until jackd with a 64 sample period size has been tested (reported to fail) and we should also consider waiting until the jack interface has been folded into the bristol audio library even though it does not like being there. That may wait, the alterations the audio library to remove the diverse unused interfaces and changes to the compilation flags seems to improve stability (and may be ported back to 0.10 at some point). After that we can start breaking things again. Cleaned up some of the debuging. Removed the bristol files from the brighton directory. This release is based on 0.10.13 with the above changes. 0.10.13 19 Jan 2008 Maintenance release. Resolved a failure in the Vox M2 percussive harmonics, they were not decaying, an issue with the operator selection in the GUI. Cosmetic alterations to some of the vox switch images, prophet panels, etc. Added some bounds checking to the jack interface to prevent a couple of errors that occur when failing to open the interface. XImage issues with 64bit sytems - the XCreateImage() fails due to pad and line length errata. Workaround is to use -pixmap (avoids the XImage acceleration code) and the fix needs testing but does not break 32 bit systems. This will be the last development of 0.10 stream, no more features only bug fixes. Further developments will go into the pending 0.20 stream. 0.10.12 03 Dec 2007 Maintenance release. RT priority is now defaulted to 75, a value of zero for the runtime parameter does not reschedule the thread at all, it is left up to the linked libraries. Vox Continental would segfault due to pedalboard buffer pointers. Implemented a workaround for damaged segment sizes with some jack attachements but this is not really a fix, it just avoids the problem by exiting a little more gracefully when there is a mismatch. It may become the fix though, the problem only happens when I cannot find the period size a priori. Reworked parts of the engine code such that it checks for data availability with select rather than going into a wait state. This is a lot cleaner as it has a timeout for failure situations. Timer defaults to a few seconds only, that could be improved. Rhodes voices were broken due to reorganisation of the ADSR default gain to be liniar rather than logarithmic, firstly the notes barely decayed but also the harmonic content did not vary from the FM algorithm. Integrated a chorus into the Rhodes GUI and a wrapper in the engine FM code. 0.10.11 27 Oct 2007 Arpeggiator written into the MIDI library. Reworked the Juno image for more edging and new sliders. Built some default "temperature sensitivity" into the dual manual synths, it should improve the sound, at least when layered. Reorganised the voice initialisation code to have better GM2 conformancy. Double click timout made into a GUI configurable option. Added a 7 segment LED digit block to the library for the Jupiter display. Implemented the arpeggiator for the Juno. It was a requirments for the Jupiter however it is easier to test with a synth that already works. Reworked the threeway switch so that it was sequential, required some changes to the emulations using them. 0.10.10 01 Oct 2007 Bass pedalboard integration for Hammond and VOX. Fixed the Vox M2 memories. Also reworked the octave frequency of its harmonics since the reed should be an octave higher. The bass pedals are now visible but the envelope closes early under some situations. The frequency table for the VOX was 'too correct', rewrote the vox microtonal map to have a table based on integer division from 1MHz to introduce a few cents of detune as per original. Some of the microtonal maps were incorrect, loss of key 108. Had no effect as none of the emulations used the microtonal map however it needed to be fixed. Put a bass pedalboard into the Hammond B3 emulation. It requires extra graphics space which is not an issue, and for both emulations the pedalboards kind of come for free - they use the same MIDI channel as the lower manual but call a different oscillator depending on MIDI note. The B3 memory structures had to change to support the lower manual drawbars. If you had your own memories in ~/.bristol/memory/hammondB3/* then you should really delete them. Made the audio thread priority a runtime option. Reworked the prophet pot bitmaps for higher contrast and closer alignment. Distributing the GM2 MIDI controller mappings as default, not all emulations support it though - does not work well for the dual manual synths nor the organs. 0.10.9 16 Sept 2007 Reworked installation procedures, Vox-300 Thanks to Nicolai Lissner for some directions on the autoconf install locations. Made some fixes to the control key interpretation however, correctly speaking, it is still actually damaged. The 'incorrectness' is minimal so will spare any resolution until it really is needed. Finished work on a dual manual VOX Super Continental (M-II, 300, etc), most of it works, the only unimplemented feature is the bass sustain envelope. Recoloured the Memory Moog buttons. 0.10.8 01 Sept 2007 Realistic Concertmate, recolorations, fixes Fixed some issues with the OB routing for correcting the mix button settings. Transparency shadow would damage on redrawing. Fixed for the hammond however for some of the synths (pro10) this shadow is lost on resizing the window. FFS. Minor recolouration of some of the hammond bitmaps for offwhite controls. Recoloration of the ARP Odyssey sliders. ARP Odyssey Ring Mod was broken due to 2600 alterations. Was bored, so programmed a Realistic (Moog) Concertmate MG-1 as a giveaway. 0.10.7 29 Jul 2007 migration of graphics from pixmap to ximage Net performance improvement just for this one change is 5 to 10 times the rendering rate. The brighton and B11 library are now again in the same order of magnitude of CPU requirements with brighton about 1/4 of the B11 interface. The overall improvement is best reviewed with the ARP 2600, before all the optimisations it could take over 10 seconds to load a memory, now it is probably closer to 1/10th of a second. There are still some issues with the XImage interface and this is a configurable option (--disable-ximage) however I am also going to turn this into a runtime option rather than just compile time. Now that the interface speed is optimised the antialiasing code has been reintroduced again as a compile and runtime option. It does have a performance hit. The antialiasing has two parameters, the depth of bit masking and the type - texture or all. Antialiasing with the 'all' option affects the total representation, using the texture option only affects the backgrounds such that the devices maintain clarity. Added a monochrome '-grayscale' option, aliasaed as '-gs|-greyscale' which does late stage color replacement to shades of gray. In itself it is not very useful as all displays are color however the algorithms for color conversion will be used presently in some menuing features. There are 5 values: 1 is an average of the three color components. 2 is half the average (dimming) 3 is quarter the average (dimming) 4 is the minimum component 5 is the maximum component Of these the first 3 will be used, in a generalised algorithm, for the grey shaded floating menus. 0.10.6 27 June 2007 bugfixes and GUI efficiency improvements. Implemented a color cache to optimize the rendering algorithm. It changes the 'quality' parameter to a BBP value to which colors are rounded (thus affecting the quality of the rendered image) and uses the subsequent red color as an index into a cache table. Each row is a doubly linked sorted list, first by green, then blue by green. Search depth is now no longer the average of half the number of colors but closer to half the row length (which in turn depends on the color quality). Delivers about 10 to 50 times improvement, especially for the color intensive transparency layers. Cache stats are available from the ^P XPM dump command. The remaining inefficiencies in the brighton X11 lib should now also be addressed. Prior to these changes the brigton interface itself was the most intensive operation, it is now only about 10% of the CPU required to repaint, hence there is space for another 5 to 10 fold improvement. Corrected inefficiencies in the horizontal scaler repainting. Originally this painted the whole width of the scaler and was resolved to just paint the area redrawn by the movement, roughly doubling its performance. Perfectly vertical patchcables were incorrecty rendered. The actual painting was correct however the rendering onto the screen was too narrow. 0.10.5 06 June 2007 added roadrunner electric piano 0.10.4 24 May 2007 added Solina string machine Potentials: Some of the diverse synth memories are damaged. ARP 2600 has damaged vertical patch cables. Move the key mappings and controller mappings to .mcm file as they are static. Removed clipping in new keyclick generation. 0.10.3 18 May 2007 added the following Modifications to configure.ac and Makefile.am to correct autotools errors. Corrected use of --exec_prefix for configure process. Note velocity, Poly and Channel Pressure curve mappings from file. Global. Note integer index mapping in same configuration file. Global. Note Microtonal tunings. Global settings - affects the whole engine. Note velocity map - per emulation. Note microtonal map - per emulation. B3 key noise generated per bus with configurable delays and gain per contact. Reverse controller motion of hammond drawbars (mappings?). Controller mapped value curves for lin/log/exp/parabolic with inverse table. Resolved issues with use of '-jack' flag as opposed to '-audio jack'. More keyboard velocity curves of which one mapping per emulation. Pitch bend damaged by microtonal mapping implementation, fixed. 0.10.2: 10 May 2007 Changes to automake configuration files for installation prefixes. 0.10.1: 4 May 2007 Probable first distribution of the bristol version using GNU autotools. bristol-0.60.11/depcomp0000755000175000017500000005064312073601233011640 00000000000000#! /bin/sh # depcomp - compile a program generating dependencies as side-effects scriptversion=2012-03-27.16; # UTC # Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009, 2010, # 2011, 2012 Free Software Foundation, Inc. # 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, 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. # Originally written by Alexandre Oliva . case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] Run PROGRAMS ARGS to compile a file, generating dependencies as side-effects. Environment variables: depmode Dependency tracking mode. source Source file read by 'PROGRAMS ARGS'. object Object file output by 'PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. tmpdepfile Temporary file to use when outputting dependencies. libtool Whether libtool is used (yes/no). Report bugs to . EOF exit $? ;; -v | --v*) echo "depcomp $scriptversion" exit $? ;; esac # A tabulation character. tab=' ' # A newline character. nl=' ' if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. depfile=${depfile-`echo "$object" | sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi cygpath_u="cygpath -u -f -" if test "$depmode" = msvcmsys; then # This is just like msvisualcpp but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvisualcpp fi if test "$depmode" = msvc7msys; then # This is just like msvc7 but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvc7 fi if test "$depmode" = xlc; then # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency informations. gccflag=-qmakedep=gcc,-MF depmode=gcc fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. ## Unfortunately, FreeBSD c89 acceptance of flags depends upon ## the command line argument order; so add the flags where they ## appear in depend2.am. Note that the slowdown incurred here ## affects only configure: in makefiles, %FASTDEP% shortcuts this. for arg do case $arg in -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; *) set fnord "$@" "$arg" ;; esac shift # fnord shift # $arg done "$@" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ## The second -e expression handles DOS-style file names with drive letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the "deleted header file" problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. tr ' ' "$nl" < "$tmpdepfile" | ## Some versions of gcc put a space before the ':'. On the theory ## that the space means something, we add a space to the output as ## well. hp depmode also adds that space, but also prefixes the VPATH ## to the object. Take care to not repeat it in the output. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like '#:fec' to the end of the # dependency line. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ tr "$nl" ' ' >> "$depfile" echo >> "$depfile" # The second pass generates a dummy entry for each header file. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> "$depfile" else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; xlc) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the # current directory. Also, the AIX compiler puts '$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then tmpdepfile1=$dir$base.u tmpdepfile2=$base.u tmpdepfile3=$dir.libs/$base.u "$@" -Wc,-M else tmpdepfile1=$dir$base.u tmpdepfile2=$dir$base.u tmpdepfile3=$dir$base.u "$@" -M fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then # Each line is of the form 'foo.o: dependent.h'. # Do two passes, one to just change these to # '$object: dependent.h' and one to simply 'dependent.h:'. sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; icc) # Intel's C compiler anf tcc (Tiny C Compiler) understand '-MD -MF file'. # However on # $CC -MD -MF foo.d -c -o sub/foo.o sub/foo.c # ICC 7.0 will fill foo.d with something like # foo.o: sub/foo.c # foo.o: sub/foo.h # which is wrong. We want # sub/foo.o: sub/foo.c # sub/foo.o: sub/foo.h # sub/foo.c: # sub/foo.h: # ICC 7.1 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using '\': # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... # tcc 0.9.26 (FIXME still under development at the moment of writing) # will emit a similar output, but also prepend the continuation lines # with horizontal tabulation characters. "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form 'foo.o: dependent.h', # or 'foo.o: dep1.h dep2.h \', or ' dep3.h dep4.h \'. # Do two passes, one to just change these to # '$object: dependent.h' and one to simply 'dependent.h:'. sed -e "s/^[ $tab][ $tab]*/ /" -e "s,^[^:]*:,$object :," \ < "$tmpdepfile" > "$depfile" sed ' s/[ '"$tab"'][ '"$tab"']*/ /g s/^ *// s/ *\\*$// s/^[^:]*: *// /^$/d /:$/d s/$/ :/ ' < "$tmpdepfile" >> "$depfile" rm -f "$tmpdepfile" ;; hp2) # The "hp" stanza above does not work with aCC (C++) and HP's ia64 # compilers, which have integrated preprocessors. The correct option # to use with these is +Maked; it writes dependencies to a file named # 'foo.d', which lands next to the object file, wherever that # happens to be. # Much of this is similar to the tru64 case; see comments there. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then tmpdepfile1=$dir$base.d tmpdepfile2=$dir.libs/$base.d "$@" -Wc,+Maked else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d "$@" +Maked fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" # Add 'dependent.h:' lines. sed -ne '2,${ s/^ *// s/ \\*$// s/$/:/ p }' "$tmpdepfile" >> "$depfile" else echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" "$tmpdepfile2" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in 'foo.d' instead, so we check for that too. # Subdirectories are respected. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then # With Tru64 cc, shared objects can also be used to make a # static library. This mechanism is used in libtool 1.4 series to # handle both shared and static libraries in a single compilation. # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. # # With libtool 1.5 this exception was removed, and libtool now # generates 2 separate objects for the 2 libraries. These two # compilations output dependencies in $dir.libs/$base.o.d and # in $dir$base.o.d. We have to check for both files, because # one of the two compilations can be disabled. We should prefer # $dir$base.o.d over $dir.libs/$base.o.d because the latter is # automatically cleaned when .libs/ is deleted, while ignoring # the former would cause a distcleancheck panic. tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 tmpdepfile2=$dir$base.o.d # libtool 1.5 tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 "$@" -Wc,-MD else tmpdepfile1=$dir$base.o.d tmpdepfile2=$dir$base.d tmpdepfile3=$dir$base.d tmpdepfile4=$dir$base.d "$@" -MD fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; msvc7) if test "$libtool" = yes; then showIncludes=-Wc,-showIncludes else showIncludes=-showIncludes fi "$@" $showIncludes > "$tmpdepfile" stat=$? grep -v '^Note: including file: ' "$tmpdepfile" if test "$stat" = 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The first sed program below extracts the file names and escapes # backslashes for cygpath. The second sed program outputs the file # name when reading, but also accumulates all include files in the # hold buffer in order to output them again at the end. This only # works with sed implementations that can handle large buffers. sed < "$tmpdepfile" -n ' /^Note: including file: *\(.*\)/ { s//\1/ s/\\/\\\\/g p }' | $cygpath_u | sort -u | sed -n ' s/ /\\ /g s/\(.*\)/'"$tab"'\1 \\/p s/.\(.*\) \\/\1:/ H $ { s/.*/'"$tab"'/ G p }' >> "$depfile" rm -f "$tmpdepfile" ;; msvc7msys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M # Require at least two characters before searching for ':' # in the target name. This is to cope with DOS-style filenames: # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. "$@" $dashmflag | sed 's:^['"$tab"' ]*[^:'"$tab"' ][^:][^:]*\:['"$tab"' ]*:'"$object"'\: :' > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" tr ' ' "$nl" < "$tmpdepfile" | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # Remove any Libtool call if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # X makedepend shift cleared=no eat=no for arg do case $cleared in no) set ""; shift cleared=yes ;; esac if test $eat = yes; then eat=no continue fi case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; # Strip any option that makedepend may not understand. Remove # the object too, otherwise makedepend will parse it as a source file. -arch) eat=yes ;; -*|$object) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix=`echo "$object" | sed 's/^.*\././'` touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" # makedepend may prepend the VPATH from the source file name to the object. # No need to regex-escape $object, excess matching of '.' is harmless. sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" sed '1,2d' "$tmpdepfile" | tr ' ' "$nl" | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi IFS=" " for arg do case "$arg" in -o) shift ;; $object) shift ;; "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E 2>/dev/null | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" echo "$tab" >> "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; msvcmsys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: bristol-0.60.11/libbristol/0000755000175000017500000000000012100257365012504 500000000000000bristol-0.60.11/libbristol/opmgt.c0000644000175000017500000000527311746476475013751 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* * Library routines for operator management. Initialisation, creation and * destruction of operator.s */ #include "bristol.h" extern void bristolfree(char *); void bristolOPfree(bristolOP *operator) { #ifdef DEBUG printf("bristolOPfree(%x)\n", operator); #endif bristolfree((char *) operator); } /* * Free up any memory from our op and io structures. Should be in library. */ int cleanup(bristolOP *operator) { #ifdef DEBUG printf("cleanup(%x)\n", operator); #endif bristolOPfree(operator); return(0); } bristolIO * bristolIOinit(bristolIO **io, int index, char *name, int rate, int samplecount) { #ifdef DEBUG printf("bristolIOinit(%x, %i, %s, %i, %i)\n", io, index, name, rate, samplecount); #endif *io = (bristolIO *) bristolmalloc(sizeof(bristolIO)); /* * Much of this will probably go into a library, for the basic init work * of any operator. The local stuff will remain in the operator code. */ (*io)->IOname = name; (*io)->index = index; (*io)->flags = 0; (*io)->last = (struct BristolIO *) NULL; (*io)->next = (struct BristolIO *) NULL; (*io)->samplecnt = samplecount; (*io)->samplerate = rate; /* * And get an IO buffer. */ (*io)->bufmem = (float *) bristolmalloc((*io)->samplecnt * sizeof(float)); return(*io); } /* * Create the operator structure, and do some basic init work. */ bristolOP * bristolOPinit(bristolOP **operator, int index, int samplecount) { #ifdef DEBUG printf("bristolOPinit(%x, %i, %i)\n", operator, index, samplecount); #endif *operator = (bristolOP *) bristolmalloc(sizeof(bristolOP)); /* * Much of this will probably go into a library, for the basic init work * of any operator. The local stuff will remain in the operator code. */ (*operator)->index = index; (*operator)->flags = 0; (*operator)->last = (struct BristolOP *) NULL; /* filled in by parent */ (*operator)->next = (struct BristolOP *) NULL; /* filled in by parent */ return(*operator); } bristol-0.60.11/libbristol/debugging.c0000644000175000017500000000537111746476475014555 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* * Library routines for operator management. Initialisation, creation and * destruction of operator.s */ #include "bristol.h" int bristolParamPrint(bristolOPParam *param) { #ifdef DEBUG printf("bristolParamPrint(0x%08x)\n", param); #endif printf(" name %s\n", param->pname); printf(" desc %s\n", param->description); printf(" type %i\n", param->type); printf(" low %i\n", param->low); printf(" high %i\n", param->high); printf(" flags %i\n", param->flags); return(0); } int bristolIOprint(bristolOPIO *io) { #ifdef DEBUG printf("bristolIOprint(0x%08x)\n", io); #endif printf(" name %s\n", io->ioname); printf(" desc %s\n", io->description); printf(" rate %i\n", io->samplerate); printf(" count %i\n", io->samplecount); printf(" flags %x\n", io->flags); printf(" buf %p\n", io->buf); return(0); } int bristolSpecPrint(bristolOPSpec *specs) { int i; #ifdef DEBUG printf("bristolSpecPrint(0x%08x)\n", specs); #endif printf(" name %s\n", specs->opname); printf(" desc %s\n", specs->description); printf(" pcount %i\n", specs->pcount); printf(" param %p\n", specs->param); printf(" iocount %i\n", specs->iocount); printf(" io %p\n", specs->io); printf(" lclsize %i\n", specs->localsize); for (i = 0; i < specs->iocount; i++) bristolIOprint(&specs->io[i]); for (i = 0; i < specs->pcount; i++) bristolParamPrint(&specs->param[i]); return(0); } int bristolOPprint(bristolOP *operator) { #ifdef DEBUG printf("bristolOPprint(0x%08x)\n", operator); #endif printf(" index %i\n", operator->index); printf(" flags %i\n", operator->flags); printf(" next %p\n", operator->next); printf(" last %p\n", operator->last); printf(" spec %p\n", operator->specs); printf(" size %i\n", operator->size); printf(" init %p\n", operator->init); printf(" dest %p\n", operator->destroy); printf(" reset %p\n", operator->reset); printf(" param %p\n", operator->param); printf(" operate %p\n", operator->operate); bristolSpecPrint(operator->specs); return(0); } bristol-0.60.11/libbristol/Makefile.in0000644000175000017500000004166112073601233014475 00000000000000# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = libbristol DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LIBRARIES = $(noinst_LIBRARIES) ARFLAGS = cru libbristol_a_AR = $(AR) $(ARFLAGS) libbristol_a_LIBADD = am_libbristol_a_OBJECTS = audioRoutines.$(OBJEXT) \ bristolcdefs.$(OBJEXT) debugging.$(OBJEXT) \ mixroutines.$(OBJEXT) opmgt.$(OBJEXT) libbristol_a_OBJECTS = $(am_libbristol_a_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libbristol_a_SOURCES) DIST_SOURCES = $(libbristol_a_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALSA_CFLAGS = @ALSA_CFLAGS@ ALSA_LIBS = @ALSA_LIBS@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BRIGHTON_HAS_AUTOZOOM = @BRIGHTON_HAS_AUTOZOOM@ BRIGHTON_HAS_SHMIMAGE = @BRIGHTON_HAS_SHMIMAGE@ BRIGHTON_HAS_X11 = @BRIGHTON_HAS_X11@ BRIGHTON_HAS_XIMAGE = @BRIGHTON_HAS_XIMAGE@ BRIGHTON_LIBB11 = @BRIGHTON_LIBB11@ BRIGHTON_LIBX11 = @BRIGHTON_LIBX11@ BRIGHTON_LIBXEXT = @BRIGHTON_LIBXEXT@ BRIGHTON_LIBXLIBS = @BRIGHTON_LIBXLIBS@ BRIGHTON_X11_DIR = @BRIGHTON_X11_DIR@ BRISTOL_BARRIER = @BRISTOL_BARRIER@ BRISTOL_DIR = @BRISTOL_DIR@ BRISTOL_HAS_ALSA = @BRISTOL_HAS_ALSA@ BRISTOL_HAS_DRAIN = @BRISTOL_HAS_DRAIN@ BRISTOL_HAS_JACK = @BRISTOL_HAS_JACK@ BRISTOL_HAS_JACK_MIDI = @BRISTOL_HAS_JACK_MIDI@ BRISTOL_HAS_JACK_SESSION = @BRISTOL_HAS_JACK_SESSION@ BRISTOL_HAS_LIBLO = @BRISTOL_HAS_LIBLO@ BRISTOL_HAS_OSS = @BRISTOL_HAS_OSS@ BRISTOL_HAS_PA = @BRISTOL_HAS_PA@ BRISTOL_JACK_DEFAULT = @BRISTOL_JACK_DEFAULT@ BRISTOL_JACK_DEFAULT_MIDI = @BRISTOL_JACK_DEFAULT_MIDI@ BRISTOL_JACK_MULTI_CLOSE = @BRISTOL_JACK_MULTI_CLOSE@ BRISTOL_LIBPALIBS = @BRISTOL_LIBPALIBS@ BRISTOL_LIB_PA = @BRISTOL_LIB_PA@ BRISTOL_LIN_ATTACK = @BRISTOL_LIN_ATTACK@ BRISTOL_MAJOR_VERSION = @BRISTOL_MAJOR_VERSION@ BRISTOL_MICRO_VERSION = @BRISTOL_MICRO_VERSION@ BRISTOL_MINOR_VERSION = @BRISTOL_MINOR_VERSION@ BRISTOL_PA_DIR = @BRISTOL_PA_DIR@ BRISTOL_SEMAPHORE = @BRISTOL_SEMAPHORE@ BRISTOL_SEM_OPEN = @BRISTOL_SEM_OPEN@ BRISTOL_SO_VERSION = @BRISTOL_SO_VERSION@ BRISTOL_VERSION = @BRISTOL_VERSION@ BRR = @BRR@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFAULT_AUDIO_FLAG = @DEFAULT_AUDIO_FLAG@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JACK_CFLAGS = @JACK_CFLAGS@ JACK_LIBS = @JACK_LIBS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBLO_CFLAGS = @LIBLO_CFLAGS@ LIBLO_LIBS = @LIBLO_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ _BRISTOL_VOICES = @_BRISTOL_VOICES@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = foreign AM_CFLAGS = -pthread -Wall -g -I$(srcdir)/../include/bristol -I$(srcdir)/../include/slab -DBRISTOL_HAS_ALSA=@BRISTOL_HAS_ALSA@ @BRISTOL_HAS_PA@ #libbristol_a_LDFLAGS=-export-dynamic -version-info @BRISTOL_SO_VERSION@ -march=core2 -msse -msse2 -mfpmath=sse -ffast-math -fomit-frame-pointer -O3 #libbristol_la_LIBADD=$(top_builddir)/libbristol/libbristol.la noinst_LIBRARIES = libbristol.a libbristol_a_SOURCES = audioRoutines.c bristolcdefs.c debugging.c mixroutines.c opmgt.c all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign libbristol/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign libbristol/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libbristol.a: $(libbristol_a_OBJECTS) $(libbristol_a_DEPENDENCIES) $(EXTRA_libbristol_a_DEPENDENCIES) -rm -f libbristol.a $(libbristol_a_AR) libbristol.a $(libbristol_a_OBJECTS) $(libbristol_a_LIBADD) $(RANLIB) libbristol.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audioRoutines.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bristolcdefs.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/debugging.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mixroutines.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/opmgt.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLIBRARIES ctags distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am tags uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: bristol-0.60.11/libbristol/Makefile.am0000755000175000017500000000077212073330071014464 00000000000000AUTOMAKE_OPTIONS = foreign AM_CFLAGS = -pthread -Wall -g -I$(srcdir)/../include/bristol -I$(srcdir)/../include/slab -DBRISTOL_HAS_ALSA=@BRISTOL_HAS_ALSA@ @BRISTOL_HAS_PA@ #libbristol_a_LDFLAGS=-export-dynamic -version-info @BRISTOL_SO_VERSION@ -march=core2 -msse -msse2 -mfpmath=sse -ffast-math -fomit-frame-pointer -O3 #libbristol_la_LIBADD=$(top_builddir)/libbristol/libbristol.la noinst_LIBRARIES = libbristol.a libbristol_a_SOURCES = audioRoutines.c bristolcdefs.c debugging.c mixroutines.c opmgt.c bristol-0.60.11/libbristol/mixroutines.c0000644000175000017500000000577611746476475015221 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* * This code should open the midi device (working with ALSA raw midi only for * the moment (9/11/01)), and read data from it. Not sure how it will be read, * either buffers, events, or perhaps just raw data. At some point in the * development this will become a separate thread in the synth code. */ /* * This should go into a library, is used from various places. */ void bufmerge(register float *src, register float gain1, register float *dst, register float gain2, register int size) { float *buf3 = dst; for (;size > 0; size-=16) { *dst++ = *buf3++ * gain2 + *src++ * gain1; *dst++ = *buf3++ * gain2 + *src++ * gain1; *dst++ = *buf3++ * gain2 + *src++ * gain1; *dst++ = *buf3++ * gain2 + *src++ * gain1; *dst++ = *buf3++ * gain2 + *src++ * gain1; *dst++ = *buf3++ * gain2 + *src++ * gain1; *dst++ = *buf3++ * gain2 + *src++ * gain1; *dst++ = *buf3++ * gain2 + *src++ * gain1; *dst++ = *buf3++ * gain2 + *src++ * gain1; *dst++ = *buf3++ * gain2 + *src++ * gain1; *dst++ = *buf3++ * gain2 + *src++ * gain1; *dst++ = *buf3++ * gain2 + *src++ * gain1; *dst++ = *buf3++ * gain2 + *src++ * gain1; *dst++ = *buf3++ * gain2 + *src++ * gain1; *dst++ = *buf3++ * gain2 + *src++ * gain1; *dst++ = *buf3++ * gain2 + *src++ * gain1; } /* * Correctly speaking we should check here to make sure that size is zero * and cater for the last 'n' samples however I think we can just take a * minimum count of 16 and take the rest in powers of two. */ } void bufadd(register float *buf1, register float add, register int size) { for (;size > 0; size-=16) { *buf1++ += add; *buf1++ += add; *buf1++ += add; *buf1++ += add; *buf1++ += add; *buf1++ += add; *buf1++ += add; *buf1++ += add; *buf1++ += add; *buf1++ += add; *buf1++ += add; *buf1++ += add; *buf1++ += add; *buf1++ += add; *buf1++ += add; *buf1++ += add; } } void bufset(register float *buf1, register float set, register int size) { for (;size > 0; size-=16) { *buf1++ = set; *buf1++ = set; *buf1++ = set; *buf1++ = set; *buf1++ = set; *buf1++ = set; *buf1++ = set; *buf1++ = set; *buf1++ = set; *buf1++ = set; *buf1++ = set; *buf1++ = set; *buf1++ = set; *buf1++ = set; *buf1++ = set; *buf1++ = set; } } bristol-0.60.11/libbristol/audioRoutines.c0000644000175000017500000002024611746476475015452 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #define DUPLICATE /* * We need to declare a duplexDev from the SLab routines, initialise this for * a set of audio parameters (sampleRate, driverType, resolution, etc), and * then call our audio open library, also from SLab. The benefits of this are * the need to only maintain one audio library for any new driver release * across all the audio applications. It requires a bit of work here, but the * benefits far outway the extra work. It does require that I import a lot of * structures (ie, headers) from SLab. */ #include "bristol.h" #include "bristolmidi.h" #include "engine.h" #ifdef TEST #include #endif #ifdef DUPLICATE #include #include #include #include int dupfd = -1; #endif static duplexDev audioDev; extern int audioClose(duplexDev *); extern int audioOpen(duplexDev *, int, int); extern int audioWrite(duplexDev *, char *, int); extern int audioRead(duplexDev *, char *, int); extern int setAudioStart2(duplexDev *, int); int bristolAudioClose() { return(audioClose(&audioDev)); } int bristolAudioOpen(char *device, int rate, int count, int flags) { printf("bristolAudioOpen(%s, %i, %i, %x)\n", device, rate, count, flags); /* * Take the audioDev, configure a full set of reasonable parameters as * required by the libslabaudio, and call audioOpen with this device. */ audioDev.channels = 2; audioDev.samplecount = count; audioDev.writeSampleRate = rate; audioDev.devID = 0; if ((audioDev.preLoad = flags & 0x00ff) == 0) audioDev.preLoad = 4; audioDev.fd2 = -1; /* * need to keep the as well, and need to reference the format to make sure * we get the correct buffer size. For now only shorts on output. * * Can this warning, multichannel will be handled with Jack #warning Fix buf calc for formats and channels */ audioDev.fragSize = count * sizeof(short) * audioDev.channels; audioDev.fragBuf = 0; audioDev.OSegmentSize = audioDev.fragSize; #if (BRISTOL_HAS_ALSA == 1) if (flags & BRISTOL_ALSA) audioDev.siflags = AUDIO_ALSA; #endif #ifdef BRISTOL_PA if (flags & BRISTOL_PULSE_S) audioDev.siflags = AUDIO_PULSE; #endif audioDev.cflags |= SLAB_SUBFRAGMENT; audioDev.cflags |= SLAB_AUDIODBG; sprintf(audioDev.devName, "%s", device); audioDev.mixerName[0] = '\0'; #ifdef TEST audioDev.fragBuf = (char *) bristolmalloc(audioDev.fragSize); return(audioDev.fragSize); #endif audioDev.flags = SLAB_FULL_DUPLEX; if (flags & BRISTOL_DUMMY) audioDev.flags |= AUDIO_DUMMY; if (audioOpen(&audioDev, 0, SLAB_ORDWR) < 0) return(-1); printf( "opened audio device with a fragment size of %i, buffer %p, fd %i/%i\n", audioDev.fragSize, audioDev.fragBuf, audioDev.fd, audioDev.fd2); return(audioDev.fragSize); } int bristolAudioStart() { return(setAudioStart2(&audioDev, 0)); } static short accum = 0; int bristolAudioWrite(register float *buf, register int count) { register short *audioBuf; register int clipped = 0, result, Count = count; if (audioDev.flags & SLAB_AUDIODBG2) printf("bristolAudioWrite(%p, %i), %i\n", buf, count, audioDev.samplecount); /* * Based on the assumption that we are always going to be working with * floats, and the output device has a given format (assume 16 bit for now) * then convert the buffer of data. */ audioBuf = (short *) audioDev.fragBuf; /* * sample count is actually frame count, ie, this is actually a sample from * each channel. As such, it looks like count is wrong. It is correct. */ for (; Count > 0; Count-=4) { /* * This is a conversion routine from the floats used by bristol, and * most of the code is for clipchecking. */ *(audioBuf++) = (short) (*buf > 32767?32767:*buf < -32767?-32767:*buf); if ((*buf > 32767) || (*buf < -32768)) clipped = 1; buf++; *(audioBuf++) = (short) (*buf > 32767?32767:*buf < -32767?-32767:*buf); buf++; *(audioBuf++) = (short) (*buf > 32767?32767:*buf < -32767?-32767:*buf); buf++; *(audioBuf++) = (short) (*buf > 32767?32767:*buf < -32767?-32767:*buf); if ((*buf > 32767) || (*buf < -32768)) clipped = 1; buf++; *(audioBuf++) = (short) (*buf > 32767?32767:*buf < -32767?-32767:*buf); buf++; *(audioBuf++) = (short) (*buf > 32767?32767:*buf < -32767?-32767:*buf); if ((*buf > 32767) || (*buf < -32768)) clipped = 1; buf++; *(audioBuf++) = (short) (*buf > 32767?32767:*buf < -32767?-32767:*buf); if ((*buf > 32767) || (*buf < -32768)) clipped = 1; buf++; *(audioBuf++) = (short) (*buf > 32767?32767:*buf < -32767?-32767:*buf); buf++; } #ifdef TEST return(0); #endif if ((result = audioWrite(&audioDev, audioDev.fragBuf, audioDev.samplecount)) < 0) { printf("Write Failed: %i\n", result); /* * We could get into a panic here. The device originally opened * correctly (otherwise we would assumably not be writing here. Lets * just close and reopen the device, and see how things go. * * We should actually return a bad value, and continue, letting the * calling party clear things up. This has been done. */ return(result); } #ifdef DUPLICATE if (dupfd > 0) { register short *sbuf = (short *) audioDev.fragBuf, d; Count = count; for (; Count > 0; Count--) accum += *sbuf++ / 2; if (accum != 0) d = write(dupfd, audioDev.fragBuf, audioDev.fragSize); } #endif if (clipped) printf("Clipping output\n"); return(0); } int bristolAudioRead(register float *buf, register int count) { register short *audioBuf; register int count2 = count; register float norm = 12.0f/32768.0f; if (audioDev.flags & SLAB_AUDIODBG2) printf("bristolAudioRead(%i), %i\n", count, audioDev.samplecount); /* * Based on the assumption that we are always going to be working with * floats, and the output device has a given format (assume 16 bit for now) * then convert the buffer of data. */ audioBuf = ((short *) audioDev.fragBuf) - 2; #ifdef TEST { usleep(6000); return(0); } #endif if (audioRead(&audioDev, audioDev.fragBuf, audioDev.samplecount) < 0) { printf("Read Failed: fs %i, %p\n", audioDev.fragSize, audioDev.fragBuf); return(-6); } /* * Demultiplex channels. * * The count is samples, but data is in frames, ie, two samples for the * time being. I really want this data to be in a format that is +/-12, * that means we have to normalise it and we should do it here. */ for (; count > 0; count-=8) { *buf++ = ((float) *(audioBuf+=2)) * norm; *buf++ = ((float) *(audioBuf+=2)) * norm; *buf++ = ((float) *(audioBuf+=2)) * norm; *buf++ = ((float) *(audioBuf+=2)) * norm; *buf++ = ((float) *(audioBuf+=2)) * norm; *buf++ = ((float) *(audioBuf+=2)) * norm; *buf++ = ((float) *(audioBuf+=2)) * norm; *buf++ = ((float) *(audioBuf+=2)) * norm; } audioBuf = ((short *) audioDev.fragBuf) - 1; for (; count2 > 0; count2-=8) { *buf++ = ((float) *(audioBuf+=2)) * norm; *buf++ = ((float) *(audioBuf+=2)) * norm; *buf++ = ((float) *(audioBuf+=2)) * norm; *buf++ = ((float) *(audioBuf+=2)) * norm; *buf++ = ((float) *(audioBuf+=2)) * norm; *buf++ = ((float) *(audioBuf+=2)) * norm; *buf++ = ((float) *(audioBuf+=2)) * norm; *buf++ = ((float) *(audioBuf+=2)) * norm; } return(0); } /* * This was added for enabling audio debug */ int bristolAudioOption(int option, int value) { switch (option) { case BRISTOL_NRP_REQ_DEBUG: if (value == 0) audioDev.cflags &= ~SLAB_AUDIODBG; else if (value == 1) audioDev.cflags |= SLAB_AUDIODBG; else audioDev.cflags |= SLAB_AUDIODBG|SLAB_AUDIODBG2; break; } return(0); } bristol-0.60.11/libbristol/bristolcdefs.c0000644000175000017500000000276411746476475015310 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include /* only for init library */ #include "bristol.h" void * bristolmalloc(size) { char *mem; mem = malloc(size); #ifdef DEBUG printf("bristolmalloc: %x, %i\n", mem, size); #endif return(mem); } void * bristolmalloc0(size) { char *mem; mem = bristolmalloc(size); #ifdef DEBUG printf("bristolmalloc0: %x, %i\n", mem, size); #endif bzero(mem, size); return(mem); } void bristolfree(void *mem) { #ifdef DEBUG printf("bristolfree: %x\n", mem); #endif if (mem != NULL) free(mem); #ifdef DEBUG else printf("attempt to free (null)\n"); #endif } void bristolbzero(char *mem, int count) { #ifdef DEBUG printf("bristolzero: %x\n", mem); #endif if (mem == NULL) return; bzero(mem, count); } bristol-0.60.11/README0000644000175000017500000062013211412626667011155 00000000000000 Bristol Emulations ------------------ This is a write-up of each of the emulated synthesisers. The algorithms employed were 'gleaned' from a variety of sources including the original owners manuals, so they may be a better source of information. The author has owned and used a selection but far from all of the originals. Some of them were built just from descriptions of their operation, or from understanding how synths work - most of them were based on the Mini Moog anyway. Many of the synths share components: the filter covers most of them, the Prophets and Oberheims share a common oscillator and the same LFO is used in many of them. Having said that each one differs considerably in the resulting sound that is generated, more so than initially expected. Each release refines each of the components and the result is that all emulations benefit from the improvements. All the emulations have distinctive sounds, not least due to that the original instruments used different modulations and mod routing. The filter, which is a large defining factor in the tonal qualities of any synth, is common to all the emulations. The filter implements a few different algorithms and these do separate each of the synths: the Explorer layering two low pass filters on top of each other: the OB-Xa using different types depending on 'Pole' selection. Since release 0.20.8 the emulator has had a Houvillainen non-linear ladder filter integrated which massively improves the quality at considerable expense to the CPU. There is one further filter algorithm used solely for the Leslie rotary emulator crossover, this is a butterworth type filter. Bristol is in no way related to any of the original manufacturers whose products are emulated by the engine and represented by the user interface, bristol does not suggest that the emulation is a like representation of the original instrument, and the author maintains that if you want the original sound then you are advised to seek out the original product. Alternatively a number of the original manufacturers now provide their own vintage collections which are anticipated to be more authentic. All names and trademarks used by Bristol are ownership of the respective companies and it is not inteded to misappropriate their use here. If you have concerns you are kindly requested to contact the author. The write-up includes the parameter operations, modulations, a description of the original instrument and a brief list of the kind of sounds you can expect by describing a few of the well known users of the synth. Several emulations have not been written up. Since the APR 2600 was implemented it became a rather large job to actually describe what was going on. If you really want to know about the synths that are not in this document then you might want to search for their owners manuals. All emulations are available from the same engine, just launch multiple GUIs and adjust the midi channels for multi timbrality and layering. It is noted here that the engine is relatively 'dumb'. Ok, it generates a very broad range of sounds, currently about 25 different synthesisers and organs, but it is not really intelligent. Memories are a part of the GUI specification - it tells the engine which algorithm to use on which MIDI channel, then it calls a memory routine that configures all the GUI controllers and a side effect of setting the controllers is that their values are sent to the engine. This is arguably the correct model but it can affect the use of MIDI master keyboards. The reason is that the GUI is really just a master keyboard for the engine and drives it with MIDI SYSEX messages over TCP sessions. If you were to alter the keyboard transpose, for example, this would result in the GUI sending different 'key' numbers to the engine when you press a note. If you were already driving the synth from a master keyboard then the transpose button in the Brighton GUI would have no effect - the master keyboard would have to be transposed instead. This apparent anomaly is exacerbated by the fact that some parameters still are in the engine, for example master tuning is in the engine for the pure fact that MIDI does not have a very good concept of master tuning (only autotuning). Irrespective of this, bristol is a synthesiser so it needs to be played, tweaked, driven. If you think that any of the behaviour is anomalous then let me know. One known issue in this area is that if you press a key, transpose the GUI, then release the key - it will not go off in the engine since the GUI sends a different key code for the note off event - the transposed key. This cannot be related to the original keypress. This could be fixed with a MIDI all notes off event on 'transpose', but I don't like them. Also, since the 0.20 stream the problem only affects a few of the emulations, the rest now sending a transpose message to the engine and letting it do the work. Since release 0.30.6 the engine correctly implements monophonic note logic. Prior to this the whole engine was polyphonic and playing with one voice only gave last note preference which dramatically affects playing styles - none of the cool legato effects of the early monophonics. The quoted release fix this limitation where the engine will keep a keymap of all played keys (one per emulation) when started with a single voice and uses this map to provide consistent note precedence, high note logic, low note logic or just using the previously implemented last note logic. In this release the keymap was only maintained with monophonic emulations, this is a potential extension as even in polyphonic mode it would be useful for arpeggiation (which is currently implemented using a FIFO rather than an ordered keymap). Moog Mini --------- It is perhaps not possible to write up who used this synth, the list is endless. Popular as it was about the first non-modular synthesiser, built as a fixed configuration of the racked or modular predecessors. Best known at the time on Pink Floyd 'Dark Side of the Moon' and other albums. Rick Wakeman used it as did Jean Michel Jarre. Wakefield could actually predict the sound it would make by just looking at the settings, nice to be able to do if a little unproductive but it went to show how this was treated as an instrument in its own right. It takes a bit of work to get the same sweet, rich sounds out of the emulation, but it can be done with suitable tweaking. The original was monophonic, although a polyphonic version was eventually made after Moog sold the company - the MultiMoog. This emulation is more comparable to that model as the sound is a bit thinner and can be polyphonic. The design of this synth became the pole bearer for the following generations: it had three oscillators, one of which could become a low frequency modulator. They were fed into a mixer with a noise source, and were then fed into a filter with 2 envelope generators to contour the wave. Modulation capabilities were not extensive, but interestingly enough it did have a frequency modulation (FM) capability, eventually used by Yamaha to revolutionise the synthesiser market starting the downfall of analogue synthesis twenty years later. All the analogue synths were temperature sensitive. It was not unusual for the synths to 'detune' between sound test and performance as the evening set in. To overcome this they could optionally produce a stable A-440Hz signal for tuning the oscillators manually - eventually being an automated option in the newer synths. Whilst this digital version has stable frequency generation the A-440 is still employed here for the sake of it. Modifiers and mod routing are relatively simple, Osc-3 and noise can be mixed, and this signal routed to the oscillator 1 and 2 frequency or filter cutoff. The synth had 5 main stages as follows: Control: Master tuning: up/down one note. Glide: (glissando, portamento). The rate at which one key will change its frequency to the next played key, 0 to 30 seconds. Mod: source changes between Osc-3 and noise. Release: The envelope generators had only 3 parameters. This governed whether a key would release immediately or would use Decay to die out. Multi: Controls whether the envelope will retrigger for each new keypress. Oscillators: There are three oscillators. One and two are keyboard tracking, the third can be decoupled and used as an LFO modulation source. Oscillator 1: Octave step from 32' to 1'. Waveform selection: sine/square/pulse/ramp/tri/splitramp Mod: controls whether Osc-3/noise modulates frequency Oscillator 2: Octave step from 32' to 1'. Fine tune up/down 7 half notes. Waveform selection: sine/square/pulse/ramp/tri/splitramp Mod: controls whether Osc-3/noise modulates frequency Oscillator 3: Octave step from 32' to 1'. Fine tune up/down 7 half notes. Waveform selection: sine/square/pulse/ramp/tri/splitramp LFO switch to decouple from keytracking. Mixer: Gain levels for Oscillator 1/2/3 Mixing of the external input source into filter Noise source with white/pink switch. Note: The level at which Osc-3 and noise modulates sound depends on its gain here, similarly the noise. The modulator mix also affects this, but allows Osc-3 to mod as well as sound. The modwheel also affect depth. Filter: Cutoff frequency Emphasis (affects Q and resonance of filter). Contour: defines how much the filter envelope affects cutoff. Mod - Keyboard tracking of cutoff frequency. Mod - Osc-3/noise modulation of cutoff frequency. Contour: The synth had two envelope generators, one for the filter and one for the amplifier. Release is affected by the release switch. If off the the sound will release at the rate of the decay control. Attack: initial ramp up of gain. Decay: fall off of maximum signal down to: Sustain: gain level for constant key-on level. Key: Touch sensitivity of amplifier envelope. Improvements to the Mini would be some better oscillator waveforms, plus an alternative filter as this is a relatively simple synthesiser and could do with a warmer filter (this was fixed with integration of the houvillanen filters although the do consume a lot of CPU to do it). The Output selection has a Midi channel up/down selector and memory selector. To read a memory either use the up/down arrows to go to the next available memory, or type in a 3 digit number on the telephone keypad and press 'L' for load or 'S' for save. As of release 0.20.5 Vasiliy Basic contributed his Mini memory banks and they are now a part of the distribution: Programs for Bristol's "Mini" (from 50 to 86 PRG) List of programs: -Melodic- 50 - Trumpet 51 - Cello 52 - Guitar 1 53 - Guitar 2 54 - Fingered Bass 55 - Picked Bass 56 - Harmonica 57 - Accordion 58 - Tango Accordion 59 - Super Accordion 60 - Piano 61 - Dark Organ 62 - Flute 63 - Music Box 64 - Glass Xylo 65 - Glass Pad 66 - Acid Bass -Drums- 67 - Bass Drum 1 68 - Bass Drum 2 69 - Bass Drum 3 70 - Bass Drum 4 71 - Tom 72 - Snare 1 73 - Snare 2 74 - Snare 3 75 - Snare 4 76 - Cl HH 1 77 - Op HH 1 78 - Crash Cym 1 79 - Crash Cym 2 80 - Cl HH 2 81 - Op HH 2 -FX- 82 - Sea Shore 83 - Helicopter 1 84 - Helicopter 2 85 - Bird Tweet 86 - Birds Tweet Sequential Circuits Prophet-5 Sequential Circuits Prophet-52 (the '5' with chorus) ---------------------------------------------------- Sequential circuits released amongst the first truly polyphonic synthesisers where a group of voice circuits (5 in this case) were linked to an onboard computer that gave the same parameters to each voice and drove the notes to each voice from the keyboard. The device had some limited memories to allow for real live stage work. The synth was amazingly flexible regaring the oscillator options and modulation routing, producing some of the fattest sounds around. They also had some of the fattest pricing as well, putting it out of reach of all but the select few, something that maintained its mythical status. David Sylvian of Duran Duran used the synth to wide acclaim in the early 80's as did many of the new wave of bands. The -52 is the same as the -5 with the addition of a chorus as it was easy, it turns the synth stereo for more width to the sound, and others have done it on the Win platform. The design of the Prophet synthesisers follows that of the Mini Moog. It has three oscillators one of them as a dedicated LFO. The second audio oscillator can also function as a second LFO, and can cross modulate oscillator A for FM type effects. The audible oscillators have fixed waveforms with pulse width modulation of the square wave. These are then mixed and sent to the filter with two envelopes, for the filter and amplifier. Modulation bussing is quite rich. There is the wheel modulation which is global, taking the LFO and Noise as a mixed source, and send it under wheel control to any of the oscillator frequency and pulse width, plus the filter cutoff. Poly mods take two sources, the filter envelope and Osc-B output (which are fully polyphonic, or rather, independent per voice), and can route them through to Osc-A frequency and Pulse Width, or through to the filter. To get the filter envelope to actually affect the filter it needs to go through the PolyMod section. Directing the filter envelope to the PW of Osc-A can make wide, breathy scanning effects, and when applied to the frequency can give portamento effects. LFO: Frequency: 0.1 to 50 Hz Shape: Ramp/Triangle/Square. All can be selected, none selected should give a sine wave (*) (*) Not yet implemented. Wheel Mod: Mix: LFO/Noise Dest: Osc-A Freq/Osc-B Freq/Osc-A PW/Osc-B PW/Filter Cutoff Poly Mod: These are affected by key velocity. Filter Env: Amount of filter envelope applied Osc-B: Amount of Osc-B applied: Dest: Osc-A Freq/Osc-A PW/Filter Cutoff Osc-A: Freq: 32' to 1' in octave steps Shape: Ramp or Square Pulse Width: only when Square is active. Sync: synchronise to Osc-B Osc-B: Freq: 32' to 1' in octave steps Fine: +/- 7 semitones Shape: Ramp/Triangle/Square Pulse Width: only when Square is active. LFO: Lowers frequency by 'several' octaves. KBD: enable/disable keyboard tracking. Mixer: Gain for Osc-A, Osc-B, Noise Filter: Cutoff: cuttof frequency Res: Resonance/Q/Emphasis Env: amount of PolyMod affecting to cutoff. Envelopes: One each for PolyMod (filter) and amplifier. Attack Decay Sustain Release Global: Master Volume A440 - stable sine wave at A440 Hz for tuning. Midi: channel up/down Release: release all notes Tune: autotune oscillators. Glide: amount of portamento Unison: gang all voices to a single 'fat' monophonic synthesiser. This is one of the fatter of the Bristol synths and the design of the mods is impressive (not my design, this is as per sequential circuits spec). Some of the cross modulations are noisy, notably 'Osc-B->Freq Osc-A' for square waves as dest and worse as source. The chorus used by the Prophet-52 is a stereo 'Dimension-D' type effect. The signal is panned from left to right at one rate, and the phasing and depth at a separate rate to generate subtle chorus through to helicopter flanging. Memories are loaded by selecting the 'Bank' button and typing in a two digit bank number followed by load. Once the bank has been selected then 8 memories from the bank can be loaded by pressing another memory select and pressing load. The display will show free memories (FRE) or programmed (PRG). Yamaha DX-7 ----------- Released in the '80s this synth quickly became the most popular of all time. It was the first fully digital synth, employed a revolutionary frequency modulated algorithm and was priced much lower than the analogue monsters that preceded it. Philip Glass used it to wide effect for Miami Vice, Prince had it on many of his albums, Howard Jones produced albums filled with its library sounds. The whole of the 80's were loaded with this synth, almost to the point of saturation. There was generally wide use of its library sounds due to the fact that it was nigh on impossible to programme, only having entry buttons and the algorithm itself was not exactly intuitive, but also because the library was exceptional and the voices very playable. The emulation is a 6 operator per voice, and all the parameters are directly accessible to ease programming. The original DX had six operators although cheaper models were release with just 4 operators and a consequently thinner sound. Each operator is a sine wave oscillator with its own envelope generator for amplification and a few parameters that adjusted its modulators. It used a number of different algorithms where operators were mixed together and then used to adjust the frequency of the next set of operators. The sequence of the operators affected the net harmonics of the overall sound. Each operator has a seven stage envelope - 'ramp' to 'level 1', 'ramp' to 'level 2', 'decay' to 'sustain', and finally 'release' when a key is released. The input gain to the frequency modulation is controllable, the output gain is also adjustable, and the final stage operators can be panned left and right. Each operator has: Envelope: Attack: Ramp rate to L1 L1: First target gain level Attack: Ramp rate from L2 to L2 L2: Second target gain level Decay: Ramp rate to sustain level Sustain: Continuous gain level Release: Key release ramp rate Tuning: Tune: +/- 7 semitones Transpose: 32' to 1' in octave increments LFO: Low frequency oscillation with no keyboard control Gain controls: Touch: Velocity sensitivity of operator. In gain: Amount of frequency modulation from input Out gain: Output signal level IGC: Input gain under Mod control OGC: Output gain under Mod control Pan: L/R pan of final stage operators. Global and Algorithms: 24 different operator staging algorithms Pitchwheel: Depth of pitch modifier Glide: Polyphonic portamento Volume Tune: Autotune all operators Memories can be selected with either submitting a 3 digit number on the keypad, or selecting the orange up/down buttons. An improvement could be more preset memories with different sounds that can then be modified, ie, more library sounds. There are some improvements that could be made to polyphonic mods from key velocity and channel/poly pressure that would not be difficult to implement. The addition of triangle of other complex waveforms could be a fun development effort (if anyone were to want to do it). The DX still has a prependancy to seg fault, especially when large gains are applied to input signals. This is due to loose bounds checking that will be extended in a present release. Roland Juno-60 -------------- Roland was one of the main pacemakers in analogue synthesis, also competing with the Sequential and Oberheim products. They did anticipate the moving market and produced the Juno-6 relatively early. This was one of the first accessible synths, having a reasonably fat analogue sound without the price card of the monster predecessors. It brought synthesis to the mass market that marked the decline of Sequential Circuits and Oberheim who continued to make their products bigger and fatter. The reduced price tag meant it had a slightly thinner sound, and a chorus was added to extend this, to be a little more comparable. The synth again follows the Mini Moog design of oscillators into filter into amp. The single oscillator is fattened out with harmonics and pulse width modulation. There is only one envelope generator that can apply to both the filter and amplifier. Control: DCO: Amount of pitch wheel that is applied to the oscillators frequency. VCF: Amount of pitch wheel that is applied to the filter frequency. Tune: Master tuning of instrument Glide: length of portamento LFO: Manual control for start of LFO operation. Hold: (*) Transpose: Up/Down one octave Hold: prevent key off events LFO: Rate: Frequency of LFO Delay: Period before LFO is activated Man/Auto: Manual or Automatic cut in of LFO DCO: LFO: Amount of LFO affecting frequency. Affected by mod wheel. PWM: Amount of LFO affecting PWM. Affected by mod wheel. ENV/LFO/MANUAL: Modulator for PWM Waveform: Pulse or Ramp wave. Pulse has PWM capabily. Sub oscillator: On/Off first fundamental square wave. Sub: Mixer for fundamental Noise: Mixer of white noise source. HPF: High Pass Filter Freq: Frequency of cutoff. VCF: Freq: Cutoff frequency Res: Resonance/emphasis. Envelope: +ve/-ve application Env: Amount of contour applied to cutoff LFO: Depth of LFO modulation applied. KBD: Amount of key tracking applied. VCA: Env/Gate: Contour is either gated or modulated by ADSR Level: Overall volume ADSR: Attack Decay Sustain Release Chorus: 8 Selectable levels of Dimension-D type helicopter flanger. * The original instrument had a basic sequencer on board for arpeggio effects on each key. In fact, so did the Prophet-10 and Oberheims. This was only implemented in 0.10.11. The LFO cut in and gain is adjusted by a timer and envelope that it triggers. The Juno would improve from the use of the prophet DCO rather than its own one. It would require a second oscillator for the sub frequency, but the prophet DCO can do all the Juno does with better resampling and PWM generation. Moog Voyager (Bristol "Explorer") --------------------------------- This was Robert Moog's last synth, similar in build to the Mini but created over a quarter of a century later and having far, far more flexibility. It was still monophonic, a flashback to a legendary synth but also a bit like Bjorn Borg taking his wooden tennis racket back to Wimbledon long after having retired and carbon fibre having come to pass. I have no idea who uses it and Bjorn also crashed out in the first round. The modulation routing is exceptional if not exactly clear. The Voyager, or Bristol Explorer, is definitely a child of the Mini. It has the same fold up control panel, three and half octave keyboard and very much that same look and feel. It follows the same rough design of three oscillators mixed with noise into a filter with envelopes for the filter and amplifier. In contrast there is an extra 4th oscillator, a dedicated LFO bus also Osc-3 can still function as a second LFO here. The waveforms are continuously selected, changing gradually to each form: bristol uses a form of morphing get get similar results. The envelopes are 4 stage rather than the 3 stage Mini, and the effects routing bears no comparison at all, being far more flexible here. Just because its funny to know, Robert Moog once stated that the most difficult part of building and releasing the Voyager was giving it the title 'Moog'. He had sold his company in the seventies and had to buy back the right to use his own name to release this synthesiser as a Moog, knowing that without that title it probably would not sell quite as well as it didn't. Control: LFO: Frequency Sync: LFO restarted with each keypress. Fine tune +/- one note Glide 0 to 30 seconds. Modulation Busses: Two busses are implemented. Both have similar capabilities but one is controlled by the mod wheel and the other is constantly on. Each bus has a selection of sources, shaping, destination selection and amount. Wheel Modulation: Depth is controller by mod wheel. Source: Triwave/Ramp/Sample&Hold/Osc-3/External Shape: Off/Key control/Envelope/On Dest: All Osc Frequency/Osc-2/Osc-3/Filter/FilterSpace/Waveform (*) Amount: 0 to 1. Constant Modulation: Can use Osc-3 as second LFO to fatten sound. Source: Triwave/Ramp/Sample&Hold/Osc-3/External Shape: Off/Key control/Envelope/On Dest: All Osc Frequency/Osc-2/Osc-3/Filter/FilterSpace/Waveform (*) Amount: 0 to 1. * Destination of filter is the cutoff frequency. Filter space is the difference in cutoff of the two layered filters. Waveform destination affects the continuously variable oscillator waveforms and allows for Pulse Width Modulation type effects with considerably more power since it can affect ramp to triangle for example, not just pulse width. Oscillators: Oscillator 1: Octave: 32' to 1' in octave steps Waveform: Continuous between Triangle/Ramp/Square/Pulse Oscillator 2: Tune: Continuous up/down 7 semitones. Octave: 32' to 1' in octave steps Waveform: Continuous between Triangle/Ramp/Square/Pulse Oscillator 3: Tune: Continuous up/down 7 semitones. Octave: 32' to 1' in octave steps Waveform: Continuous between Triangle/Ramp/Square/Pulse Sync: Synchronise Osc-2 to Osc-1 FM: Osc-3 frequency modulates Osc-1 KBD: Keyboard tracking Osc-3 Freq: Osc-3 as second LFO Mixer: Gain levels for each source: Osc-1/2/3, noise and external input. Filters: There are two filters with different configuration modes: 1. Two parallel resonant lowpass filters. 2. Serialised HPF and resonant LPF Cutoff: Frequency of cutoff Space: Distance between the cutoff of the two filters. Resonance: emphasis/Q. KBD tracking amount Mode: Select between the two operating modes. Envelopes: Attack Decay Sustain Release Amount to filter (positive and negative control) Velocity sensitivity of amplifier envelope. Master: Volume LFO: Single LFO or one per voice (polyphonic operation). Glide: On/Off portamento Release: On/Off envelope release. The Explorer has a control wheel and a control pad. The central section has the memory section plus a panel that can modify any of the synth parameters as a real time control. Press the first mouse key here and move the mouse around to adjust the controls. Default values are LFO frequency and filter cutoff but values can be changed with the 'panel' button. This is done by selecting 'panel' rather than 'midi', and then using the up/down keys to select parameter that will be affected by the x and y motion of the mouse. At the moment the mod routing from the pad controller is not saved to the memories, and it will remain so since the pad controller is not exactly omnipresent on MIDI master keyboards - the capabilities was put into the GIU to be 'exact' to the design. This synth is amazingly flexible and difficult to advise on its best use. Try starting by mixing just oscillator 1 through to the filter, working on mod and filter options to enrich the sound, playing with the oscillator switches for different effects and then slowly mix in oscillator 2 and 3 as desired. Memories are available via two grey up/down selector buttons, or a three digit number can be entered. There are two rows of black buttons where the top row is 0 to 4 and the second is 5 to 9. When a memory is selected the LCD display will show whether it is is free (FRE) or programmed already (PRG). Hammond B3 (dual manual) ------------------------ The author first implemented the Hammond module, then extended it to the B3 emulation. Users of this are too numerous to mention and the organ is still popular. Jimmy Smith, Screaming Jay Hawkins, Kieth Emerson, Doors and almost all american gospel blues. Smith was profuse, using the instrument for a jazz audience, even using its defects (key noise) to great effect. Emerson had two on stage, one to play and another to kick around, even including stabbing the keyboard with a knife to force keylock during performances (Emerson was also a Moog fan with some of the first live performances). He also used the defects of the system to great effect, giving life to the over- driven Hammond sound. The Hammond was historically a mechanical instrument although later cheaper models used electronics. The unit had a master motor that rotated at the speed of the mains supply. It drove a spindle of cog wheels and next to each cog was a pickup. The pickup output went into the matrix of the harmonic drawbars. It was originally devised to replace the massive pipe organs in churches - Hammond marketed their instruments with claims that they could not be differentiated from the mechanical pipe equivalent. He was taken to court by the US government for misrepresentation, finally winning his case using a double blind competitive test against a pipe organ, in a cathedral, with speakers mounted behind the organ pipes and an array of music scholars, students and professionals listening. The results spoke for themselves - students would have scored better by simply guessing which was which, the professionals fared only a little better than that. The age of the Hammond organ had arrived. The company had a love/hate relationship with the Leslie speaker company - the latter making money by selling their rotary speakers along with the organ to wide acceptance. The fat hammond 'chorus' was a failed attempt to distance themselves from Leslie. That was never achieved due to the acceptance of the Leslie, but the chorus did add another unique sound to the already awesome instrument. The rotary speaker itself still added an extra something to the unique sound that is difficult imagine one without the other. It has a wide range of operating modes most of which are included in this emulator. The chorus emulation is an 8 stage phase shifting filter algorithm with a linear rotor between the taps. Parameterisation of the first B3 window follows the original design: Leslie: Rotary speaker on/off Reverb: Reverb on/off VibraChorus: 3 levels of vibrato, 3 of chorus. Bright: Added upper harmonics to waveforms. Lower and Upper Manual Drawbars: The drawbars are colour coded into white for even harmonics and black for odd harmonics. There are two subfrequencies in brown. The number given here are the length of organ pipe that would correspond to the given desired frequency. 16 - Lower fundamental 5 1/3 - Lower 3rd fundamental 8 - Fundamental 4 - First even harmonic 2 2/3 - First odd harmonic 2 - Second even harmonic 1 3/5 - Second odd harmonic 1 1/3 - Third odd harmonic 1 - Third even harmonic The drawbars are effectively mixed for each note played. The method by which the mixing is done is controlled in the options section below. There were numerous anomalies shown by the instrument and most of them are emulated. The Hammond could provide percussives effect the first even and odd harmonics. This gave a piano like effect and is emulated with Attack/Decay envelope. Perc 4' - Apply percussive to the first even harmonic Perc 2 2/3' - Apply percussive to the first odd harmonic Slow - Adjust rate of decay from about 1/2 second to 4 seconds. Soft - Provide a soft attack to each note. The soft attack is an attempt to reduce the level of undesired key noise. The keyboard consisted of a metal bar under each key that made physical contact with 9 sprung teeth to tap off the harmonics. The initial contact would generate noise that did not really accord to the pipe organ comparison. This was reduced by adding a slow start to each key, but the jazz musicians had used this defect to great effect, terming it 'key click' and it became a part of the Hammond characteristics. Some musicians would even brag about how noisy there organ was. On the left had side are three more controls: Volume potentiometer Options switch discussed below. Rotary Speed: low/high speed Leslie rotation. Shifts between the speeds are suppressed to emulate the spin up and down periods of the leslie motors. The options section, under control of the options button, has the parameters used to control the emulation. These are broken into sections and discussed individually. Leslie: The Leslie rotary speaker consisted of a large cabinet with a bass speaker and a pair of high frequency air horns. Each were mounted on its own rotating table and driven around inside the cabinet by motors. A crossover filter was used to separate the frequencies driven to either speaker. Each pair was typically isolated physically from the other. As the speaker rotated it would generate chorus type effects, but far richer in quality. Depending on where the speaker was with respect to the listener the sound would also appear to rotate. There would be different phasing effects based on signal reflections, different filtering effects depending on where the speaker was in respect to the cabinet producing differences resonances with respect to the internal baffling. Separate: Sync: No Bass: The Leslie had two motors, one for the horns and one for the voice coil speaker. These rotated at different speeds. Some players preferred to have both rotate at the same speed, would remove the second motor and bind the spindles of each speaker table, this had the added effect that both would also spin up at the same rate, not true of the separated motors since each table had a very different rotary moment. The 'No Bass' option does not rotate the voice coil speaker. This was typically done since it would respond only slowly to speed changes, this left just the horns rotating but able to spin up and down faster. Brake: Some cabinets had a brake applied to the tables such that when the motor stopped the speakers slowed down faster. X-Over: This is the cross over frequency between the voice coil and air horns. Uses a butterworth filter design. Inertia: Rate at which speaker rotational speed will respond to changes. Overdrive: Amount by which the amplifier is overdriven into distortion. H-Depth/Frequency/Phase L-Depth/Frequency/Phase These parameters control the rotary phasing effect. The algorithm used has three differently phased rotations used for filtering, phasing and reverberation of the sound. These parameters are used to control the depth and general phasing of each of them, giving different parameters for the high and low speed rotations. There are no separate parameters for the voice coil or air horns, these parameters are for the two different speeds only, although in 'Separate' mode the two motors will rotate at slightly different speeds. Chorus V1/C1 - Lowest chorus speed V2/C2 - Medium chorus speed V3/C3 - High chorus speed Percussion: Decay Fast/Slow - controls the percussive delay rates. Attack Slow Fast - Controls the per note envelope attack time. The percussives are emulated as per the original design where there was a single envelope for the whole keyboard and not per note. The envelope will only restrike for a cleanly pressed note. Finally there are several parameters affecting the sine wave generation code. The Hammond used cogged wheels and coil pickups to generate all the harmonics, but the output was not a pure sine wave. This section primarily adjusts the waveform generation: Preacher: The emulator has two modes of operation, one is to generate the harmonics only for each keyed note and another to generate all of them and tap of those required for whatever keys have been pressed. Both work and have different net results. Firstly, generating each note independently is far more efficient than generating all 90 odd teeth, as only a few are typically required. This does not have totally linked phases between notes and cannot provide for signal damping (see below). The Preacher algorithm generates all harmonics continuously as per the original instrument. It is a better rendition at the expense of large chunks of CPU activity. This is discussed further below. Compress: Time compress the sine wave to produce a slightly sharper leading edge. Bright: Add additional high frequency harmonics to the sine. Click: Level of key click noise Reverb: Amount of reverb added by the Leslie Damping: If the same harmonic was reused by different pressed keys then its net volume would not be a complete sum, the output gain would decay as the pickups would become overloaded. This would dampen the signal strength. This is only available with the Preacher algorithm. The two reverse octaves are presets as per the original, however here they can just be used to recall the first 23 memories of the current bank. The lower manual 12 key is the 'save' key for the current settings and must be double clicked. It should be possible to drive these keys via MIDI, not currently tested though. The default presets are a mixture of settings, the lower manual being typical 'standard' recital settings, the upper manual being a mixture of Smith, Argent, Emerson, Winwood and other settings from the well known Hammond Leslie FAQ. You can overwrite them. As a slight anomaly, which was intentional, loading a memory from the these keys only adjusts the visible parameters - the drawbars, leslie, etc. The unseen ones in the options panel do not change. When you save a memory with a double click on the lower manual last reverse key then in contrast it saves all the parameters. This will not change. The Preacher algorithm supports a diverse set of options for its tonewheel emulation. These are configured in the file $BRISTOL/memory/profiles/tonewheel and there is only one copy. The file is a text file and will remain that way, it is reasonably documented in the file itself. Most settings have two ranges, one representing the normal setting and the other the bright setting for when the 'bright' button is pressed. The following settings are currently available: ToneNormal: each wheel can be given a waveform setting from 0 (square) through to 1.0 (pure sine) to X (sharpening ramp). EQNormal: each wheel can be given a gain level across the whole generator. DampNormal: each wheel has a damping factor (level robbing/damping/stealing) BusNormal: each drawbar can be equalised globally. ToneBright: each wheel can be given a waveform setting from 0 (square) through to 1.0 (pure sine) to X (sharpening ramp) for the bright button. EQBright: each wheel can be given a gain level across the whole generator. DampBright: each wheel has a damping factor (level robbing/damping/stealing) BusBright: each drawbar can be equalised globally. stops: default settings for the eight drawbar gain levels. The default is 8 linear stages. wheel: enables redefining the frequency and phase of any given tonewheel The defaults are the slightly non Even Tempered frequencies of the Hammond tonewheels. The tonewheel file redefines the top 6 frequencies that were slightly more out of tune due to the 192-teeth wheels and a different gear ratio. crosstalk: between wheels in a compartment and adjacent drawbar busses. This is one area that may need extensions for crosstalk in the wiring loom. Currently the level of crosstalk between each of the wheels in the compartment can be individually defined, and drawbar bus crosstalk also. compartment: table of the 24 tonewheel compartments and associated wheels. resistors: tapering resister definitions for equalisation of gains per wheel by note by drawbar. taper: definition of the drawbar taper damping resistor values. Improvements would come with some other alterations to the sine waveforms and some more EQ put into the leslie speaker. The speaker has three speeds, two of which are configurable and the third is 'stopped'. Changes between the different rates is controlled to emulate inertia. The net emulation, at least of the preacher algorithm, is reasonable, it is distinctively a Hammond sound although it does not have quite as much motor or spindle noise. The Bright button gives a somewhat rawer gearbox. It could do with a better amplifier emulation for overdrive. The damping algorithms is not quite correct, it has dependencies on which keys are pressed (upper/lower manual). Options drop shadow is taken from the wrong background bitmap so appears in an inconsistent grey. Vox Continental --------------- This emulates the original mark-1 Continental, popular in its time with the Animals on 'House of the Rising Sun', Doors on 'Light my Fire' and most of their other tracks. Manzarek did use Gibson later, and even played with the Hammond on their final album, 'LA Woman' but this organ in part defined the 60's sound and is still used by retro bands for that fact. The Damned used it in an early revival where Captain Sensible punched the keyboard wearing gloves to quite good effect. After that The Specials began the Mod/Ska revival using one. The sharp and strong harmonic content has the ability to cut into a mix and make its presence known. The organ was a british design, eventually sold (to Crumar?) and made into a number of plastic alternatives. Compared to the Hammond this was a fully electronic instrument, no moving parts, and much simpler. It had a very characteristic sound though, sharper and perhaps thinner but was far cheaper than its larger cousin. It used a master oscillator that was divided down to each harmonic for each key (as did the later Hammonds for price reasons). This oscillator division design was used in the first of the polyphonic synthesisers where the divided note was fead through individual envelope generators and a shared or individual filter (Polymoog et al). The Vox is also a drawbar instrument, but far simplified compared to the Hammond. It has 4 harmonic mixes, 16', 8' and 4' drawbars each with eight positions. The fourth gave a mix of 2 2/3, 2, 1 1/3 and 1 foot pipes. An additional two drawbars controlled the overall volume and waveforms, one for the flute or sine waves and another for the reed or ramp waves. The resulting sound could be soft and warm (flute) or sharp and rich (reed). There are two switches on the modulator panel, one for vibrato effect and one for memories and options. Options give access to an chorus effect rather than the simple vibrato, but this actually detracts from the qualities of the sound which are otherwise very true to the original. Vox is a trade name owned by Korg Inc. of Japan, and Continental is one of their registered trademarks. Bristol does not intend to infringe upon these registered names and Korg have their own remarkable range of vintage emulations available. You are directed to their website for further information of true Korg products. Fender Rhodes ------------- Again not an instrument that requires much introduction. This emulation is the DX-7 voiced synth providing a few electric piano effects. The design is a Mark-1 Stage-73 that the author has, and the emulation is reasonable if not exceptional. The Rhodes has always been widely used, Pink Floyd on 'Money', The Doors on 'Riders on the Storm', Carlos Santana on 'She's not There', everybody else in the 60's. The Rhodes piano generated its sound using a full piano action keyboard where each hammer would hit a 'tine', or metal rod. Next to each rod was a pickup coil as found on a guitar, and these would be linked together into the output. The length of each tine defined its frequency and it was tunable using a tight coiled spring that could be moved along the length of the tine to adjust its moment. The first one was built mostly out of aircraft parts to amuse injured pilots during the second world war. The Rhodes company was eventually sold to Fender and lead to several different versions, the Mark-2 probably being the most widely acclaimed for its slightly warmer sound. There is not much to explain regarding functionality. The emulator has a volume and bass control, and one switch that reveals the memory buttons and algorithm selector. The Rhodes would improve with the addition of small amounts of either reverb or chorus, potentially to be implemented in a future release. The Rhodes Bass was cobbled together largely for a presentation on Bristol. It existed and was used be Manzarek when playing with The Doors in Whiskey-a-GoGo; the owner specified that whilst the music was great they needed somebody playing the bass. Rather than audition for the part Manzarek went out and bought a Rhodes Bass and used it for the next couple of years. Sequential Circuits Prophet-10 ------------------------------ The prophet 10 was the troublesome brother of the Pro-5. It is almost two Prophet-5 in one box, two keyboards and a layering capability. Early models were not big sellers, they were temperamental and liable to be temperature sensitive due to the amount of electronics hidden away inside. The original layering and 'unison' allowed the original to function as two independent synths, a pair of layered synths (both keyboards then played the same sound), as a monophonic synth in 'unison' mode on one keybaord with a second polyphonic unit on the other, or even all 10 voices on a single keyed note for a humongous 20 oscillator monophonic monster. Phil Collins used this synth, and plenty of others who might not admit to it. The emulator uses the same memories as the Prophet-5, shares the same algorithm, but starts two synths. Each of the two synths can be seen by selecting the U/D (Up/Down) button in the programmer section. Each of the two synthesisers loads one of the Pro-5 memories. There was an added parameter - the Pan or balance of the selected layer, used to build stereo synths. The lower control panel was extended to select the playing modes: Dual: Two independent keyboards Poly: Play note from each layer alternatively Layer: Play each layer simultaneously. In Poly and Layer mode, each keyboard plays the same sounds. Mods: Select which of the Mod and Freq wheels control which layers. Sequential Circuits Prophet-5 Sequential Circuits Prophet-52 (the '5' with chorus) ---------------------------------------------------- Sequential circuits released amongst the first truly polyphonic synthesisers where a group of voice circuits (5 in this case) were linked to an onboard computer that gave the same parameters to each voice and drove the notes to each voice from the keyboard. The device had some limited memories to allow for real live stage work. The synth was amazingly flexible regaring the oscillator options and modulation routing, producing some of the fattest sounds around. They also had some of the fattest pricing as well, putting it out of reach of all but the select few, something that maintained its mythical status. David Sylvian of Duran Duran used the synth to wide acclaim in the early 80's as did many of the new wave of bands. The -52 is the same as the -5 with the addition of a chorus as it was easy, it turns the synth stereo for more width to the sound, and others have done it on the Win platform. The design of the Prophet synthesisers follows that of the Mini Moog. It has three oscillators one of them as a dedicated LFO. The second audio oscillator can also function as a second LFO, and can cross modulate oscillator A for FM type effects. The audible oscillators have fixed waveforms with pulse width modulation of the square wave. These are then mixed and sent to the filter with two envelopes, for the filter and amplifier. Modulation bussing is quite rich. There is the wheel modulation which is global, taking the LFO and Noise as a mixed source, and send it under wheel control to any of the oscillator frequency and pulse width, plus the filter cutoff. Poly mods take two sources, the filter envelope and Osc-B output (which are fully polyphonic, or rather, independent per voice), and can route them through to Osc-A frequency and Pulse Width, or through to the filter. To get the filter envelope to actually affect the filter it needs to go through the PolyMod section. Directing the filter envelope to the PW of Osc-A can make wide, breathy scanning effects, and when applied to the frequency can give portamento effects. LFO: Frequency: 0.1 to 50 Hz Shape: Ramp/Triangle/Square. All can be selected, none selected should give a sine wave (*) (*) Not yet implemented. Wheel Mod: Mix: LFO/Noise Dest: Osc-A Freq/Osc-B Freq/Osc-A PW/Osc-B PW/Filter Cutoff Poly Mod: These are affected by key velocity. Filter Env: Amount of filter envelope applied Osc-B: Amount of Osc-B applied: Dest: Osc-A Freq/Osc-A PW/Filter Cutoff Osc-A: Freq: 32' to 1' in octave steps Shape: Ramp or Square Pulse Width: only when Square is active. Sync: synchronise to Osc-B Osc-B: Freq: 32' to 1' in octave steps Fine: +/- 7 semitones Shape: Ramp/Triangle/Square Pulse Width: only when Square is active. LFO: Lowers frequency by 'several' octaves. KBD: enable/disable keyboard tracking. Mixer: Gain for Osc-A, Osc-B, Noise Filter: Cutoff: cuttof frequency Res: Resonance/Q/Emphasis Env: amount of PolyMod affecting to cutoff. Envelopes: One each for PolyMod (filter) and amplifier. Attack Decay Sustain Release Global: Master Volume A440 - stable sine wave at A440 Hz for tuning. Midi: channel up/down Release: release all notes Tune: autotune oscillators. Glide: amount of portamento Unison: gang all voices to a single 'fat' monophonic synthesiser. This is one of the fatter of the Bristol synths and the design of the mods is impressive (not my design, this is as per sequential circuits spec). Some of the cross modulations are noisy, notably 'Osc-B->Freq Osc-A' for square waves as dest and worse as source. The chorus used by the Prophet-52 is a stereo 'Dimension-D' type effect. The signal is panned from left to right at one rate, and the phasing and depth at a separate rate to generate subtle chorus through to helicopter flanging. Memories are loaded by selecting the 'Bank' button and typing in a two digit bank number followed by load. Once the bank has been selected then 8 memories from the bank can be loaded by pressing another memory select and pressing load. The display will show free memories (FRE) or programmed (PRG). Oberheim OB-X ------------- Oberheim was the biggest competitor of Sequential Circuits, having their OB range neck and neck with each SC Prophet. The sound is as fat, the OB-X similar to the Prophet-5 as the OB-Xa to the Prophet-10. The synths were widely used in rock music in the late seventies and early 80s. Their early polyphonic synthesisers had multiple independent voices linked to the keyboard and were beast to program as each voice was configured independently, something that prevented much live usage. The OB-X configured all of the voices with the same parameters and had non-volatile memories for instant recall. Priced at $6000 upwards, this beast was also sold in limited quantities and as with its competition gained and maintained a massive reputation for rich, fat sounds. Considering that it only had 21 continuous controllers they were used wisely to build its distinctive and flexible sound. The general design again follows that of the Mini Moog, three oscillators with one dedicated as an LFO the other two audible. Here there is no mixer though, the two audible oscillators feed directly into the filter and then the amplifier. The richness of the sound came from the oscillator options and filter, the latter of which is not done justice in the emulator. Manual: Volume Auto: autotune the oscillators Hold: disable note off events Reset: fast decay to zero for envelopes, disregards release parameter. Master Tune: up/down one semitone both oscillators. Control: Glide: up to 30 seconds Oscillator 2 detune: Up/down one semitone Unison: gang all voices to a single 'fat' monophonic synthesiser. Modulation: LFO: rate of oscillation Waveform: Sine/Square/Sample&Hold of noise src. Triangle if none selected. Depth: Amount of LFO going to: Freq Osc-1 Freq Osc-2 Filter Cutoff PWM: Amount of LFO going to: PWM Osc-1 PWM Osc-2 Oscillators: Freq1: 32' to 1' in octave increments. PulseWidth: Width of pulse wave (*). Freq2: 16' to 1' in semitone increments. Saw: sawtooth waveform Osc-1 (**) Puls: Pulse waveform Osc-1 XMod: Osc-1 FW to Osc-2 (***) Sync: Osc-2 sync to Osc-1 Saw: sawtooth waveform Osc-2 Puls: Pulse waveform Osc-2 * Although this is a single controller it acts independently on each of the oscillators - the most recent to have its square wave selected will be affected by this parameter allowing each oscillator to have a different pulse width as per the original design. ** If no waveform is selected then a triangle is generated. *** The original synth had Osc-2 crossmodifying Osc-1, this is not totally feasible with the sync options as they are not mutually exclusive here. Cross modulation is noisy if the source or dest wave is pulse, something that may be fixed in a future release. Filter: Freq: cutoff frequency Resonance: emphasis (*) Mod: Amount of modulation to filter cutoff (**) Osc-1: Osc-1 to cutoff at full swing. KDB: Keyboard tracking of cutoff. Half/Full: Oscillator 2 to Cutoff at defined levels (***) Half/Full: Noise to Cutoff at defined levels (***) * In contrast to the original, this filter can self oscillate. ** The original had this parameter for the envelope level only, not the other modifiers. Due to the filter implementation here it affects total depth of the sum of the mods. *** These are not mutually exclusive. The 'Half' button gives about 1/4, the 'Full' button full, and both on gives 1/2. They could be made mutually exclusive, but the same effect can be generated with a little more flexibility here. Envelopes: One each for filter and amplifier. Attack Decay Sustain Release The oscillators appear rather restricted at first sight, but the parametrics allow for a very rich and cutting sound. Improvements would be a fatter filter, but this can be argued of all the Bristol synthesisers as they all share the same design. It will be altered in a future release. The OB-X has its own mod panel (most of the rest share the same frequency and mod controls). Narrow affects the depth of the two controllers, Osc-2 will make frequency only affect Osc-2 rather than both leading to beating, or phasing effects if the oscillators are in sync. Transpose will raise the keyboard by one octave. Memories are quite simple, the first group of 8 buttons is a bank, the second is for 8 memories in that bank. This is rather restricted for a digital synth but is reasonably true to the original. If you want more than 64 memories let me know. Oberheim OB-Xa -------------- This is almost two OB-X in a single unit. With one keyboard they could provide the same sounds but with added voicing for split/layers/poly options. The OB-Xa did at least work with all 10 voices, had a single keyboard, and is renound for the sounds of van Halen 'Jump' and Stranglers 'Strange Little Girl'. The sound had the capability to cut through a mix to upstage even guitar solo's. Oberheim went on to make the most over the top analogue synths before the cut price alternatives and the age of the DX overcame them. Parameters are much the same as the OB-X as the algorithm shares the same code, with a few changes to the mod routing. The main changes will be in the use of Poly/Split/Layer controllers for splitting the keyboard and layering the sounds of the two integrated synthesisers and the choice of filter algorithm. The voice controls apply to the layer being viewed, selected from the D/U button. Manual: Volume Balance Auto: autotune the oscillators Hold: disable note off Reset: fast decay to zero for envelopes, disregards release parameter. Master Tune: up/down one semitone both oscillators. Control: Glide: up to 30 seconds Oscillator 2 detune: Up/down one semitone Unison: gang all voices to a single 'fat' monophonic synthesiser. Modulation: LFO: rate of oscillation Waveform: Sine/Square/Sample&Hold of noise src. Triangle if none selected. Depth: Amount of LFO going to: Freq Osc-1 Freq Osc-2 Filter Cutoff PWM: Amount of LFO going to: PWM Osc-1 PWM Osc-2 Tremelo Oscillators: Freq1: 32' to 1' in octave increments. PulseWidth: Width of pulse wave (*). Freq2: 16' to 1' in semitone increments. Saw: sawtooth waveform Osc-1 (**) Puls: Pulse waveform Osc-1 Env: Application of Filter env to frequency Sync: Osc-2 sync to Osc-1 Saw: sawtooth waveform Osc-2 Puls: Pulse waveform Osc-2 * Although this is a single controller it acts independently on each of the oscillators - the most recent to have its square wave selected will be affected by this parameter allowing each oscillator to have a different pulse width, as per the original design. ** If no waveform is selected then a triangle is generated. Filter: Freq: cutoff frequency Resonance: emphasis (*) Mod: Amount of modulation to filter cutoff (**) Osc-1: Osc-1 to cutoff at full swing. KDB: Keyboard tracking of cutoff. Half/Full: Oscillator 2 to Cutoff at defined levels (***) Noise: to Cutoff at defined levels 4 Pole: Select 2 pole or 4 pole filter * In contrast to the original, this filter will self oscillate. ** The original had this parameter for the envelope level only, not the other modifiers. Due to the filter implementation here it affects total depth of the sum of the mods. *** These are not mutually exclusive. The 'Half' button gives about 1/4, the 'Full' button full, and both on gives 1/2. They could be made mutually exclusive, but the same effect can be generated with a little more flexibility here. Envelopes: One each for filter and amplifier. Attack Decay Sustain Release Mode selection: Poly: play one key from each layer alternatively for 10 voices Split: Split the keyboard. The next keypress specifies split point Layer: Layer each voice on top each other. D/U: Select upper and lower layers for editing. Modifier Panel: Rate: Second LFO frequency or Arpeggiator rate (*) Depth: Second LFO gain Low: Modifiers will affect the lower layer Up: Modifiers will affect the upper layer Multi: Each voice will implement its own LFO Copy: Copy lower layer to upper layer Mod 01: Modify Osc-1 in given layer Mod 02: Modify Osc-2 in given layer PW: Modify Pulse Width AMT: Amount (ie, depth) of mods and freq wheels Transpose: Up or Down one octave. The Arpeggiator code integrated into release 0.20.4 has three main parts, the arpeggiator itself, the arpeggiating sequencer and the chording. All are configured from the left of the main panel. The arpeggiator is governed by the rate control that governs how the code steps through the available keys, an octave selector for 1, 2 or 3 octaves of arpeggiation, and finally the Up/Down/Up+Down keys - the last ones start the arpeggiator. Arpeggiation will only affect the lower layer. When it has been started you press keys on the keyboard (master controller or GUI) and the code will step through each note and octaves of each note in the order they were pressed and according to the direction buttons. The key settings are currently reset when you change the direction and you will have to press the notes again. The sequencer is a modification of the code. Select the Seq button and then a direction. The GUI will program the engine with a series of notes (that can be redefined) and the GUI will sequence them, also only into the lower layer. The sequence will only start when you press a key on the keyboard, this is the starting point for the sequence. You can press multiple notes to have them sequence in unison. Once started you can tweak parameters to control the sound and memory 88 when loaded has the filter envelope closed down, a bit of glide and some heavy mods to give you a starting point for some serious fun. To reprogram the sequence steps you should stop the sequencer, press the PRG button, then the Sequence button: enter the notes you want to use one by one on the keyboard. When finished press the sequence button again, it goes out. Now enable it again - select Seq and a direction and press a note. Press two notes. When you save the memory the OBXa will also save the sequence however there is only one sequence memory - that can be changed if you want to have a sequence memory per voice memory (implemented in 0.20.4). The chord memory is similar to the Unison mode except that Unison plays all voices with the same note. Chording will assign one voice to each notes in the chord for a richer sound. To enable Chording press the 'Hold' button. This is not the same as the original since it used the hold button as a sustain option however that does not function well with a Gui and so it was reused. To reprogram the Chord memory do the following: press the PRG button then the Hold button. You can then press the keys, up to 8, that you want in the chord, and finally hit the Hold button again. The default chord is just two notes, the one you press plus its octave higher. This results in multiple voices per keypress (a total of 3 in Layered mode) and with suitable detune will give a very rich sound. There is only one arpeggiator saved for all the memories, not one per memory as with some of the other implementations. Mail me if you want that changed. The oscillators appear rather restricted at first sight, but the parametrics allow for a very rich and cutting sound. The Copy function on the Mod Panel is to make Poly programming easier - generate the desired sound and then copy the complete parameter set for poly operation. It can also be used more subtly, as the copy operation does not affect balance or detune, so sounds can be copied and immediately panned slightly out of tune to generate natural width in a patch. This is not per the original instrument that had an arpeggiator on the mod panel. The Arpeggiator was first integrated into the OBXa in release 0.20.4 but not widely tested. KORG MONOPOLY ------------- A synth suite would not be complete without some example of a Korg instrument, the company was also pivotal in the early synthesiser developments. This is an implementation of their early attempts at polyphonic synthesis, it was either this one or the Poly-6 (which may be implemented later). Other choices would have been the MS series, MS-20, but there are other synth packages that do a better job of emulating the patching flexibility of that synth - Bristol is more for fixed configurations. As with many of the Korg synths (the 800 worked similarly) this is not really true polyphony, and it is the quirks that make it interesting. The synth had four audio oscillators, each independently configurable but which are bussed into a common filter and envelope pair - these are not per voice but rather per instrument. The unit had different operating modes such that the four oscillators can be driven together for a phat synth, independently for a form of polyphony where each is allocated to a different keypress, and a shared mode where they are assigned in groups depending on the number of keys pressed. For example, if only 2 notes are held then each key is sounded on two different oscillators, one key is sounded on all 4 oscillators, and 3 or more have one each. In addition there are two LFOs for modulation and a basic effects option for beefing up the sounds. To be honest to the original synth, this emulation will only request 1 voice from the engine. Korg is one of the few original manufacturers to have survived the transition to digital synthesis and are still popular. One thing that is immediately visible with this synth is that there are a lot of controllers since each oscillator is configured independently. This is in contrast to the true polyphonic synths where one set of controls are given to configure all the oscillators/filters/envelopes. The synth stages do follow the typical synth design, there are modulation controllers and an FX section feeding into the oscillators and filter. The effects section is a set of controllers that can be configured and then enabled/disabled with a button press. The overall layout is rather kludgy, with some controllers that are typically grouped being dispersed over the control panel. Control: Volume Arpeg: Whether arpegiator steps up, down, or down then up. This works in conjunction with the 'Hold' mode described later. Glide: glissando note to note. Does not operate in all modes Octave: Up/Normal/Down one octave transpose of keyboard Tune: Global tuning of all oscillators +/- 50 cents (*) Detune: Overall detuning of all oscillators +/- 50 cents (*) * There is an abundance of 'Tune' controllers. Global Tuning affects all the oscillators together, then oscillators 2, 3 and 4 have an independent tune controller, and finally there is 'Detune'. The target was to tune all the oscillators to Osc-1 using the independent Tune for each, and then use the global Tune here to have the synth tuned to other instruments. The Detune control can then be applied to introduce some beating between the oscillators to fatten the sound without necessarily losing overall tune of the instrument. Modulation wheels: Bend: Intensity: Depth of modulation Destination: VCF - Filter cutoff Pitch - Frequency of all oscillators VCO - Frequency of selected oscillators (FX selection below). MG1: Mod Group 1 (LFO) Intensity: Depth of modulation Destination: VCF - Filter cutoff Pitch - Frequency of all oscillators VCO - Frequency of selected oscillators (FX selection below). LFO: MG-1: Frequency Waveform - Tri, +ve ramp, -ve ramp, square. MG-2: Frequency (Triangle wave only). Pulse Width Control: Pulse Width Modulation: Source - Env/MG-1/MG-2 Depth Pule Width Width control These controllers affect Osc-1 though 4 with they are selected for either square of pulse waveforms. Mode: The Mono/Poly had 3 operating modes, plus a 'Hold' option that affects each mode: Mono: All oscillators sound same key in unison Poly: Each oscillator is assigned independent key - 4 note poly. Share: Dynamic assignment: 1 key - 4 oscillators = Mono mode 2 key - 2 oscillators per key 3/4 - 1 oscillator per key = Poly mode The Hold function operates in 3 different modes: Mono: First 4 keypresses are memorised, further notes are then chorded together monophonically. Poly: Notes are argeggiated in sequence, new note presses are appended to the chain. Arpeggiation is up, down or up/down. Share: First 4 notes are memorised and are then argeggiated in sequence, new note presses will transpose the arpeggiation. Stepping is up, down or up/down. There are several controllers that affect arpeggation: Arpeg - direction of stepping MG-2 - Frequency of steps from about 10 seconds down to 50 bps. Trigger - Multiple will trigger envelopes on each step. Effects: There are three main effects, or perhaps rather modulations, that are controlled in this section. These are vibrato, crossmodulated frequency and oscillator synchronisation. The application of each mod is configured with the controllers and then all of them can be enabled/disabled with the 'Effects' button. This allows for big differences in sound to be applied quickly and simply as a typical effect would be. Since these mods apply between oscillators it was envisaged they would be applied in Mono mode to further fatten the sound, and the Mono mode is actually enabled when the Effects key is selected (as per the original instrument). The Mode can be changed afterwards for Effects/Poly for example, and they work with the arpeggiation function. X-Mod: frequency crossmodulation between oscillators Freq: frequency modulation by MG-1 (vibrato) or Envlope (sweep) Mode: Syn: Oscillators are synchronised X-M: Oscillators are crossmodulated S-X: Oscillators are crossmodulated and synchronised SNG: Single mode: synth had a master oscillator (1) and three slaves (2/3/4) DBL: Double mode: synth had two master (1/3) and two slaves (2/4) The overall FX routing depends on the SNG/DBL mode and the selection of Effects enabled or not according to the table below. This table affects the FX routing and the modulation wheels discussed in the LFO section above: -------------------------------------------------- | FX OFF | FX ON | | |---------------------------------- | | Single | Double | ---------------+--------------+-----------------+---------------| | VCO-1/Slave | VCO-1 | VCO 2/3/4 | VCO 2/4 | | | | | | | Pitch | VCO 1-4 | VCO 1-4 | VCO 1-4 | | | | | | | VCF | VCF | VCF | VCF | ----------------------------------------------------------------- So, glad that is clear. Application of the modulation wheels to Pitch and VCF is invariable when they are selected. In contrast, VCO/Slave will have different destinations depending on the Effects, ie, when effects are on the modwheels will affect different 'slave' oscillators. Oscillators: Each oscillator had the following controllers: Tune (*) Waveform: Triangle, ramp, pulse, square (**) Octave: Transpose 16' to 2' Level: output gain/mix of oscillators. * Osc-1 tuning is global ** width of pulse and square wave is governed by PW controller. The modulation of the pulse waveform is then also controlled by PWM. Noise: Level: white noise output gain, mixed with oscillators into filter. VCF: Freq: Cutoff frequency Res: Resonance/emphasis. Env: Amount of contour applied to cutoff KBD: Amount of key tracking applied. ADSR: Two: filter/PWM/FX, amplifier Attack Decay Sustain Release Trigger: Single: Trigger once until last key release Multi: Trigger for each key or arpeggiator step. Damp: Off: Notes are held in Poly/Share mode until last key is released. On: Oscillators are released as keys are released. This is more a synth to play with than describe. It never managed to be a true blue synth perhaps largely due to its unusual design: the quasi-poly mode was never widely accepted, and the effects routing is very strange. This does make it a synth to be tweaked though. Some of the mod routings do not conform to the original specification for the different Slave modes. This is the first and probably the only bristol synth that will have an inbuilt arpeggiator. The feature was possible here due to the mono synth specification, and whilst it could be built into the MIDI library for general use it is left up to the MIDI sequencers (that largely came along to replace the 1980s arpeggiators anyway) that are generally availlable on Linux. [Other instruments emulated by bristol that also included arpeggiation but do not have in the emulation were the Juno-6, Prophet-10, Oberheim OB-Xa, Poly6]. As of May 06 this synth was in its final stages of development. There are a few issues with Tune and Detune that need to be fixed, and some of the poly key assignment may be wrong. KORG POLY 6 ----------- Korg in no way endorses this emulation of their classic synthesiser and have their own emulation product that gives the features offered here. Korg, Mono/Poly, Poly-6, MS-20, Vox and Continental are all registered names or trademarks of Korg Inc of Japan. Quite a few liberties were taken with this synth. There were extremely few differences between the original and the Roland Juno 6, they both had one osc with PWM and a suboscillator, one filter and envelope, a chorus effect, and inevitably both competed for the same market space for their given price. To differentiate this algorithm some alterations were made. There are two separate envelopes rather than just one, but the option to have a gated amplifier is still there. In addition glide and noise were added, both of which were not in the original instrument. With respect to the original instrument this was perhaps not a wise move, but there seemed little point in making another Juno with a different layout. The net results is that the two synths do sound quite different. The emulation does not have an arpeggiator. Volume: Master volume of the instrument Glide: length of portamento Tune: Master tuning of instrument Bend: Amount of pitch wheel that is applied to the oscillators frequency. VCO section: Octave: What octave the instrument's keyboard is in. Wave: Waveform selection: Triangle, Saw, Pulse and Pulsewidth PW PWM: Amount of Pulsewidth (when Pulse is selected) and Pulsewidth Modulation (When Pulsewidth is selected). Freq: Frequency of PW/PWM OFF/SUB1/SUB2; Adds a square sub-oscillator either off, 1 or 2 octaves down from a note. MG (Modulation Group): Freq: Frequency of LFO Delay: Amount of time before the LFO affects the destination when a key is pressed. Level: How strongly the LFO affects the destination VCO/VCF/VCA: Destinations that the LFO can go to: VCO: The Voltage Controlled Oscillator: Affects oscillator pitch, producing vibrato VCF: The Voltage Controlled Filter: Affects Filter, producing a wah effect VCA: The Voltage Controlled Amplifier: Affects the Amplifier, producing tremolo VCF section: Freq: Cut off frequency of the filter Res: Resonance of the filter Env: By how much the filter is affected by the envelope. Kbd: How much Keyboard tracking is applied to the envelope. note: A low setting doesn't allow the filter to open, making the notes seem darker the further you go up the keyboard. Hold: prevent key off events Mono Mode: Gang all voices to a single 'fat' monophonic synthesiser. Poly: One voice per note. Envelope Section: Top: Filter envelope: Attack: Amount of time it takes the filter to fully open. A high value can produce a 'sweeping filter' effect. Decay: Amount of time it takes for the filter to close to the sustain level Sustain: Amount of filter that is sustained when a key is held Release: Amount of time it takes for the filter envelope to stop affecting the filter. Combining a low filter release with a high amplitude release time can cause an interesting effect. Bottom: Amplitude envelope: Attack: Amount of time it takes for the signal to reach its peak. Decay: Amount of time it takes for the signal to drop to the sustain level Sustain: How quickly the sound decays to silence. Release: How long it takes the sound to decay to silence after releasing a key. VCA: Env: When on, this causes the Amplitude envelope to affect the sound. I.E, If you have a long attack time, you get a long attack time. Gate: When on, this causes the Amplitude envelope only (not the filter envelope) to be be bypassed. Gain: Gain of signal. Effects Section: 0: No effects 1: Soft Chorus 2: Phaser 3: Ensemble Intensity: How much the effects affect the output. There are some mildly anomolous effects possible from the MG section, especially with the VCA. The MG and the env are summed into the VCA which means if the env decays to zero then the LFO may end up pumping the volume, something that may be unexpected. Similarly, if the LFO is pumping and the voice finally stops its cycle then the closing gate may cause a pop on the MG signal. These can be resolved however the current behavious is probably close to the original. Bristol thanks Andrew Coughlan for patches, bug reports, this manual page and diverse suggestions to help improve the application. Korg in no way endorses this emulation of their classic synthesiser and have their own emulation product that gives the features offered here. Korg, Mono/Poly, Poly-6, MS-20, Vox and Continental are all registered names or trademarks of Korg Inc of Japan. ARP AXXE -------- TBD At the risk of getting flamed, this is potentially the ugliest synth ever made, although the competition is strong. It was implemented as a build up to the far more useful ARP 2600 to understand the ARP components and their implementation. The implementation is a giveaway written during a week long business trip to Athens to keep me busy in the hotel. Its design lead on to the Odyssey and that was the step towards the final big brother, the ARP 2600. ARP ODYSSEY ----------- Ring modulation is correct here, it is a multiplier. This deviates from the original instrument that used an XOR function on the pulsewave outputs of the two oscillators. The implementation has two models, Mark-I and Mark-II. These implement different filters as per the original. Although their characteristics are different it is not suggested they are a particularly close emulation of the original. TBD Memory Moog ----------- TBD. This is actually a lot warmer than the Mini emulator, largely due to being later code. The mini should be revisited but I am saving that pleasure for when some more filters are available. [This was done during the 0.20 stream using the Houvilainen filters and bandwidth limited oscillators to produce a far richer sound. Also incorporate a number of fixes to the emulation stages.]. ARP 2600 -------- This synth will probably never get a writeup, it is kind of beyond the scope of this document. There are some discrepancies with the original: The filters do not self oscillate, they require an input signal. The output stage is global to all voices so cannot be patched back into the signal path. The original did not have a chorus, only a spring reverb. The input stage has not been tested for either signal nor envelope following code. The voltage manipulators were not in the first bristol upload with this emulation (-60), but a future release will include mixing inverters, a lag processor, and possibly also a Hz->V extractor. The unit has an extra LFO where the original had just a clock trigger circuit, it produces a TRI wave, can be used to trigger the AR envelope and be used for modulation. The electroswitch is unidirectional, two inputs switchable to one output. The sample and hold circuit cannot accept an external clock. The Keyboard inputs to the VCO cannot accept and alternative signal other than the MIDI note with tracking of this note either enabled or disabled. The rest works, ie, all the VCO/VCF/VCA/ENV/AMP and any of the 30 or so outputs can be repatched into any of the 50 or so inputs. Patches cause no overhead in the engine as it uses default buffering when not repatched, so feel free to put in as many cables as you can fit. Patches in the GUI still demand a lot of CPU cycles. Release -77 improved this about 5-fold and further improvements are in the pipeline: the 0.10 stream implemented color caching and XImage graphics interface which massively improved GUI performance. REALISTIC MG-1 CONCERTMATE -------------------------- This is a pimpy little synth. It was sold through the Realistic electronics chain, also known as Radio Shack (and as Tandy, in the UK at least). It was relatively cheap but had a design from Moog Music (from after Robert Moog had left?) including the patented ladder filter. It consisted of a monophonic synth, dual oscillator, lfo, noise, filter, env, and a ring modulator. On top of that there was an organ circuit to give 'polyphony'. It was not really polyphonic although different descriptions will tell you it had 10 voices. These write-ups are by people who probably only had 10 fingers, the truth is that the organ circuit was as per any other - it had a master oscillator at about 2MHz and this was divided using binary counters to deliver a frequency for every note. The output of the 'poly' section was lamentable at best, it is a fairly pure square wave passed through the filter and contour. This is fully emulated although in addition to the contour bristol implements a per note envelope just to groom the note - this prevents ticks when new keys are pressed with the mono envelope fully open. There is no access to this env, it just has fast attack and decay times to smooth the signal and is preconfigured by the user interface on startup. The mono section is reasonably fun, the oscillators can be synchronised and there is a ring modulator so the range of sounds is quite wide. The emulator uses a chaimberlain filter so is not as warm as the Moog ladder filters. The list of people who used this is really quite amazing. The promotion for the product had Elton John holding one up in the air, although seeing as he probably already had every other synth known to man, holding it up in the air is likely to be all he ever did with it. Who knows how much they had to pay him to do it - the photo was nice though, from the days when Elton was still bald and wearing ridiculously oversized specs. Tuning: One control each for the poly oscillator and mono oscillators Glide: Only affects the monophonic oscillators. Modulation: One LFO with rate and waveshape selection produces tri, square and S/H signals. can trigger the envelope One noise source. The modulation can be directed to: Oscillators for vibrato Filter for wah-wah effects Oscillator-1: Tri or square wave Octave from -2 to 0 transposition Sync selector (synchronises Osc-2 to Osc-1) Oscillator-2: Tri or pulse wave Detune. This interoperates with the sync setting to alter harmonics Octave from -1 to +1 transposition Contour: This is not an ADSR, rather an AR envelope Sustain: AR or ASR envelope selector. Tracking: controls mono oscillators Envelope control Key tracking (gate, no env) Continuous (always on) Rise (attack time) Fall (release time) Filter: Cutoff frequency Emphasis Contour depth Keyboard tracking off, 1/2, full. Mixer: Levels for Mono Osc-1 Mono Osc-2 Noise RingMod of the mono oscillators (called 'bell'). Poly Osc level. Master Volume control. One extra button was added to save the current settings. For the rest the controls reflect the simplicity of the original. The implementation is a single synth, however due to the engine architecture having a pre-operational routine, a post-operational routine and an operate(polyphonic emulator) the emulation executes the mono synth in the pre- and post- ops to be mono, these are called just once per cycle. The poly synth is executed in the operate() code so is polyphonic. This leads to one minor deviation from the original routing in that if you select continuous tone controls then you will also hear one note from the poly section. This is a minor issue as the poly oscillator can be zeroed out in the mixer. It is noted here that this emulation is just a freebie, the interface is kept simple with no midi channel selection (start it with the -channel option and it stays there) and no real memories (start it with the -load option and it will stay on that memory location). There is an extra button on the front panel (a mod?) and pressing it will save the current settings for next time it is started. I could have done more, and will if people are interested, but I built it since the current developments were a granular synth and it was hard work getting my head around the grain/wave manipulations, so to give myself a rest I put this together one weekend. The Rhodesbass and ARP AXXE were done for similar reasons. I considered adding another mod button, to make the mono section also truly polyphonic but that kind of detracts from the original. Perhaps I should put together a Polymoog sometime that did kind of work like that anyway. This was perhaps a strange choice, however I like the way it highlights the difference between monophonic, polyphonic and 'neopolyphonic' synthesised organs (such as the polymoog). Its a fun synth as well, few people are likely to every bother buying one as they cost more now than when they were produced due to being collectable: for the few hundred dollars they would set you back on eBay you can get a respectable polyphonic unit. So here is an emulator, for free, for those who want to see how they worked. Vox Continental 300 ------------------- There is an additional emulator for the later Mark-II, Super, 300 or whatever model you want to call it. This is probably closest to the 300. It was a dual manual organ, the lower manual is a Continental and the upper manual had a different drawbar configuration, using 8', 4' and 2', another two compound drawbars that represented 5-1/3'+1-3/5', and 2-2/3'+2'+1' respectively. This gave upper manual a wider tonic range, plus it had the ability to apply some percussive controls to two of the drawbars. Now, depending on model, some of these values could be different and bristol does not emulate all the different combinations, it uses the harmonics described above and applies percussive to the 2' and 5-1/3' harmonics (which is arguably incorrect however it gives a wider combination of percussive harmonics). The percussive has 4 controls, these are selectors for the harmonics that will be driven through the percussive decay (and then no longer respond to the drawbars), a decay rate called 'L' which acts as a Longer decay when selected, and a volume selector called 'S' which stands for Soft. The variables are adjustable in the mods section. The mods panel is intended to be hidden as they are just variable parameters. On the original units these were PCB mounted pots that were not generally accessible either. The panel is visible when you turn the power control off, not that I suppress the keyboard or anything when the power is off, but it gave me something useful do to with this button. The transparency layer is fixed here and is used to apply some drop shadow and a few beer spills on the cover. There is an additional Bass section for those who bought the optional Bass pedals (my old one had them). The emulation allow the selection of Flute and Reed strengths, and to select 8' or 8'/16' harmonics. The 'Sustain' control does not currently operate (0.10.9) but that can be fixed if people request the feature. The lower manual responds to the MIDI channel on which the emulation was started. The upper manual responds to notes greater than MIDI key 48 on the next channel up. The Bass section also responds to this second channel on keys lower than #48. Once started you cannot change the midi channel - use the '-channel' option at startup to select the one you want. The actual available max is 15 and that is enforced. The emulation only contains 6 available presets and a 'Save' button that you need to double click to overwrite any preset. The emulation actually uses banks, so if you started it with '-load 23' it would start up by selecting bank 20, and load memory #3 from that bank. Any saved memories are also then written back to bank 20, still with just 6 memories accessible 20-25. You can access more via MIDI bank select and program change operations if suitably linked up. Vox is a trade name owned by Korg Inc. of Japan, and Continental is one of their registered trademarks. Bristol does not intend to infringe upon these registered names and Korg have their own remarkable range of vintage emulations available. You are directed to their website for further information of true Korg products. Roland Jupiter 8 ---------------- This emulator is anticipated in 0.20.4. The Jupiter synthesizers were the bigger brothers of the Juno series: their capabilities, sounds and prices were all considerably larger. This is the larger of the series, the others being the -4 and -6. The -6 and the rack mounted MKS-80 both came out after the Jupiter-8 and had somewhat more flexible features. Several of these have been incorporated into the emulation and that is documented below. A quick rundown of the synth and emulation: The synth runs as two layers, each of which is an independent emulator running the same algorithm, both layers are controlled from the single GUI. The layers are started with a set of voices, effectively 4+4 per default however bristol plays with those numbers to give the split/layer at 4 voices each and the 'All' configuration with 8 voices - it juggles them around depending on the Poly mode you select. You can request a different number of voices and the emulator will effectively allocate half the number to each layer. If you request 32 voices you will end up with 4+4 though since 32 is interpreted as the default. The Poly section is used to select between Dual layers, Split keyboard and the 8voice 'All' mode. You can redefine the split point with a double click on the 'Split' button and then pressing a key. If you have linked the GUI up to the MIDI you should be able to press a key on your master keyboard rather than on the GUI. After that you can select the layer as upper or lower to review the parameter settings of each layer: they are as follows: LFO: Frequency Delay Waveform (tri, saw, square, s&h) VCO Mods: LFO and ENV-1 Destination to modulate frequency of DCO1, DCO2 or both. PWM: PW PWM Modified by Env-1 or LFO DCO-1: Crossmod (FM) from DCO2 to DCO1 Modified by Env-1 Octave range 16' to 2' (all mixable) Waveform: Tri, saw, pulse, square (all mixable) DCO-2: Sync (1->2 or 2->1 or off) Range: 32' to 2' (all mixable) Tuning Waveform: tri, saw, pulse, noise (all mixable) Mix: Osc 1 and Osc 2 HPF: High pass filter of signal Filter: Cutoff Emphasis LPF/BPF/HPF Env modulation Source from Env-1 or Env-2 LFO mod amount Keyboard tracking amount VCA: Env-2 modulation LFO modulation ADSR-1: A/D/S/R Keyboard tracking amount Invert ADSR-2: A/D/S/R Keyboard tracking amount Pan: Stereo panning of layer All of the above 40 or so parameters are part of the layer emulation and are separately configurable. The keyboard can operate in several different modes which are selectable from the Poly and Keyboard mode sections. The first main one is Dual, Split and All. Dual configure the two synth layers to be placed on top of each other. Split configures them to be next to each other and by double clicking the split button you can then enter a new split point by pressing a key. The All setting gives you a single layer with all 8 voices active. These settings are for the whole synth. The Poly section provides different playing modes for each layer independently. There are 3 settings: Solo give the layer access to a single voice for playing lead solos. Unison give the layer however many voices it is allowed (8 if in the All mode, 4 otherwise) and stacks them all on top of each other. This is similar to Solo but with multiple voices layered onto each other. Unison is good for fat lead sounds, Solo better for mono bass lines where Unison might have produced unwanted low frequency signal phasing. The third option is Poly mode 1 where the synth allocates a single voice to each key you press. The original also had Poly mode 2 which was not available at the first bristol release - this mode would apply as many notes as available to the keys you pressed: 1 key = 8 voices as in Unison, with 2 keys pressed each would get 4 voices each, 4 keys pressed would get 2 voices and mixtures in there for other key combinations. This may be implemented in a future release but it is a rather left field option and would have to be put into the MIDI library that controls the voice assignments. The arpeggiator integrated into bristol is a general design and will differ from the original. The default settings are 4 buttons controlling the range of the arpeggiation, from 1 to 4 octaves, 4 buttons controlling the mode as Up, Down, Up+Down or Random sequencing of the notes available, and 4 notes that are preloaded into the sequence. Finally there are two global controls that are outside of the memories - the rate and clock source (however externally driven MTC has not been implemented yet). It is noted that the Arpeggiator settings are separate from the sequence information, ie, Up/Down/Rnd, the range and the arpeggiator clock are not the same as the note memory, this is discussed further in the memory setting section below. It is possible to redefine the arpeggiator sequence: select the function button on the right hand side, then select any of the arpeggiator mode buttons, this will initiate the recording. It does not matter which of the mode is selected since they will all start the recording sequence. When you have finished then select the mode button again (you may want to clear the function key if still active). You can record up to 256 steps, either from the GUI keyboard or from a master controller and the notes are saved into a midi key memory. There is no capability to edit the sequences once they have been entered, that level of control is left up to separate MIDI sequencers for which there are many available on Linux. Also, the note memory is actually volatile and will be lost when the emulation exits. If you want to save the settings then you have to enter them from the GUI keyboard or make sure that the GUI is linked up to the master keyboard MIDI interface - you need to be able to see the GUI keyboard following the notes pressed on the master keyboard since only when the GUI sees the notes can it store them for later recall. If the GUI did view the sequence entered here then it will be saved with the patch in a separate file (so that it can be used with other bristol synths). In addition to the Arpeggiator there is the 'Chord' control. The original synth had two green panel buttons labelled 'Hold', they were actually similar to the sustain pedal on a MIDI keyboard or piano, with one for each layer of the synth. They have been redefined here as Chord memory. When activated the layer will play a chord of notes for every key press. The notes are taken from separate chord memory in the Arpeggiator sequencer. The result is very similar to the Unison mode where every voice is activated for a single key, the difference here is that every voice may be playing a different note to give phat chords. To configure a chord you enable the function key and the target Hold button to put the synth into chord learning mode, play a set of notes (you don't have to hold them down), and click again to finalise the chord. If there are more chord notes than voices available then all voices will activate. If there are more voices than notes then you will be able to play these chord polyphonically, for example, if you have 8 voices and entered just 4 chorded notes then you will have 2 note polyphony left. You should also be able to play arpeggiations of chords. The maximum number of notes in a chord is 8. The synth has a modifier panel which functions as performance options which can be applied selectively to different layers: Bender: This is the depth of the settings and is mapped by the engine to continuous controller 1 - the 'Mod' wheel. The emulation also tracks the pitch wheel separately. Bend to VCO This applies an amount of pitch bend from the Mod wheel selectively to either VCO-1 and/or VCO-2. These settings only affect the Mod layers selected from the main panel. Subtle modifications applied in different amounts to each oscillator can widen the sound considerable by introducing small amounts of oscillator phasing. Bend to VCF Affects the depth of cutoff to the filter with on/off available. Again only applies to layers activate with the Mod setting. LFO to VCO: The mod panel has a second global LFO producing a sine wave. This can be driven in selectable amounts to both VCO simultaneously. Layers are selected from the Mod buttons. LFO to VCF: The LFO can be driven in selectable amounts to both VCO or to the VCF. Layers are selected from the Mod buttons. Delay: This is the rise time of the LFO from the first note pressed. There is no apparent frequency control of the second LFO however bristol allows the frequency and gain of the LFO to track velocity using function B4 (see below for function settings). Since there is only one LFO per emulation then the velocity tracking can be misleading as it only tracks from a single voice and may not track the last note. For this reason it can be disabled. Using a tracking from something like channel pressure is for future study. Glide: Glissando between key frequencies, selectable to be either just to the upper layer, off, or to both layers. Transpose: There are two transpose switches for the lower and upper layers respectively. The range is +/1 one octave. Modifier panel settings are saved in the synth memories and are loaded with the first memory (ie, with dual loaded memories discussed below). The ability to save these settings in memory is an MKS-80 feature that was not available in either the Jupiter-6 or -8. There are several parts to the synth memories. Layer parameters govern sound generation, synth parameters that govern operating modes such Dual/Split, Solo/Unison etc, Function settings that modify internal operations, the parameters for the mod panel and finally the Arpeggiator sequences. These sequences are actually separate from the arpeggiator settings however that was covered in the notes above. When a patch is loaded then only the layer parameters are activated so that the new sound can be played, and the settings are only for the selected layer. This means any chord or arpeggiation can be tried with the new voice active. When a memory is 'dual loaded' by a double click on the Load button then all the memory settings will be read and activated: the current layer settings, synth settings, operational parameters including the peer layer parameters for dual/split configurations. Dual loading of the second layer will only happen if the memory was saved as a split/double with a peer layer active. The emulation adds several recognised Jupiter-6 capabilities that were not a part of the Jupiter-8 product. These are 1. PW setting as well as PWM 2. Cross modulation can be amplified with envelope-1 for FM type sounds 3. Sync can be set in either direction (DCO1 to 2 or DCO2 to 1) 4. The waveforms for DCO 1&2 are not exclusive but mixable 5. The LFO to VCA is a continuous controller rather than stepped 6. The envelope keyboard tracking is continuous rather than on/off 7. The filter option is multimode LP/BP/HP rather than 12/24dB 8. Layer detune is configurable 9. Layer transpose switches are available 10. Arpeggiator is configurable on both layers Beyond these recognised mods it is also possible to select any/all DCO transpositions which further fattens up the sound as it allows for more harmonics. There is some added detune between the waveforms with its depth being a function of the -detune setting. Separate Pan and Balance controls have been implemented, Pan is the stereo positioning and is configurable per layer. Balance is the relative gain between each of the layers. There are several options that can be configured from the 'f' button in the MIDI section. When you push the f(n) button then the patch and bank buttons will not select memory locations but display the on/off status of 16 algorithmic changes to the emulation. Values are saved in the synth memories. These are bristol specific modifications and may change between releases unless otherwise documented. F(n): f(p1): Env-1 retriggers f(p2): Env-1 conditionals f(p3): Env-1 attack sensitivity f(p4): Env-2 retriggers f(p5): Env-2 conditionals f(p6): Env-2 attack sensitivity f(p7): Noise per voice/layer f(p8): Noise white/pink f(b1): LFO-1 per voice/layer f(b2): LFO-1 Sync to Note ON f(b3): LFO-1 velocity tracking f(b4): Arpeggiator retrigger f(b5): LFO-2 velocity tracking f(b6): NRP enable f(b7): Debug MIDI f(b8): Debug GUI controllers The same function key also enables the learning function of the arpeggiator and chord memory, as explained above. When using the arpeggiator you may want to test with f(b4) enabled, it will give better control of the filter envelope. Other differences to the original are the Hold keys on the front panel. These acted as sustain pedals however for the emulation that does not function very well. With the original the buttons were readily available whilst playing and could be used manually, something that does not work well with a GUI and a mouse. For this reason they were re-used for 'Unison Chording' discussed above. Implementing them as sustain pedals would have been an easier if less flexible option and users are advised that the bristol MIDI library does recognise the sustain controller as the logical alternative here. Another difference would be the quality of the sound. The emulation is a lot cleaner and not as phat as the original. You might say it sounds more like something that comes from Uranus rather than Jupiter and consideration was indeed given to a tongue in cheek renaming of the emulation..... The author is allowed this criticism as he wrote the application - as ever, if you want the original sound then buy the original synth (or get Rolands own emulation?). A few notes are required on oscillator sync since by default it will seem to be quite noisy. The original could only product a single waveform at a single frequency at any one time. Several emulators, including this one, use a bitone oscillator which generates complex waveforms. The Bristol Bitone can generate up to 4 waveforms simultaneously at different levels for 5 different harmonics and the consequent output is very rich, the waves can be slightly detuned, the pulse output can be PW modulated. As with all the bristol oscillators that support sync, the sync pulse is extracted as a postive leading zero crossing. Unfortunately if the complex bitone output is used as input to sync another oscillator then the result is far too many zero crossings to extract a good sync. For the time being you will have to simplify the sync source to get a good synchronised output which itself may be complex wave. A future release will add a sync signal from the bitone which will be a single harmonic at the base frequency and allow both syncing and synchronised waveform outputs to be arbitrary. CRUMAR BIT-1, BIT-99, BIT-100 ----------------------------- I was considering the implementation of the Korg-800, a synth I used to borrow without having due respect for it - it was a late low cost analogue having just one filter for all the notes and using the mildly annoying data entry buttons and parameter selectors. Having only one filter meant that with key tracking enabled the filter would open up as different keys were pressed, wildly changing the sound of active notes. Anyway, whilst considering how to implement the entry keys (and having features like the mouse tracking the selectors of the parameter graphics) I was reminded of this synthesizer. It was developed by Crumar but released under the name 'Bit' as the Crumar name was associated with cheesy roadrunner electric pianos at the time (also emulated by Bristol). This came out at the same time as the DX-7 but for half the price, and having the split and layer facilities won it several awards that would otherwise have gone to the incredibly innovative DX. However with the different Crumar models being released as the digital era began they kind of fell between the crack. It has some very nice mod features though, it was fun to emulate and hopefully enjoyable to play with. As a side note, the Korg Poly-800 is now also emulated by bristol A quick rundown of the Bit features are below. The different emulated models have slightly different default parameter values and/or no access to change them: Two DCO with mixed waveforms. VCF with envelope VCA with envelope Two LFO able to mod all other components, controlled by the wheel and key velocity, single waveform, one had ramp and the other sawtooth options. The envelopes were touch sensitive for gain but also for attack giving plenty of expressive capabilities. The bristol envelope, when configured for velocity sensitive parameters (other than just gain) will also affect the attack rate. The front panel had a graphic that displayed all the available parameters and to change then you had to select the "Address" entry point then use the up/down entry buttons to change its value. Bristol uses this with the addition that the mouse can click on a parameter to start entering modifications to it. The emulation includes the 'Compare' and 'Park' features although they are a little annoying without a control surface. They work like this (not quite the same as the original): When you select a parameter and change it's value then the changes are not actually made to the active program, they just change the current sounds. The Compare button can be used to flip between the last loaded value and the current modified one to allow you to see if you prefer the sound before or after the modification. If you do prefer the changes then to keep them you must "Park" them into the running program before saving the memory. At the time of writing the emulation emulated the double click to park&write a memory, however it also has an actual Save button since 'Save to Tape' is not a feature here. You can use park and compare over dual loaded voices: unlike the original, which could only support editing of sounds when not in split/double, this emulation allows you to edit both layers by selecting the upper/lower entry buttons and then using the sensitive panel controls to select the addressed parameters. This is not the default behaviour, you first have to edit address 102 and increment it. Then, each layer can be simultaneously edited and just needs to be parked and saved separately. The Park/Compare cache can be disabled by editing parameter DE 101, changes are then made to the synth memory and not the cache. The memories are organised differently to the original. It had 99 memories, and the ones from 75 and above were for Split and Layered memories. Bristol can have all memories as Split or Layer. When you save a memory it is written to memory with a 'peer' program locator. When you load it with a single push on the Load button it returns to the active program, but if you double click then its 'peer' program is loaded into the other layer: press Load once to get the first program entered, then press it again - the Split/Layer will be set to the value from the first program and the second layer will be loaded. This naturally requires that the first memory was saved with Split/Layer enabled. It is advised (however not required) that this dual loading is done from the lower layer. This sequence will allow the lower layer to configure certain global options that the upper layer will not overwrite, for example the layer volumes will be select from the lower layer when the upper layer is dual loaded. For MIDI program change then since this quirky interface cannot be emulated then the memories above 75 will be dual loaded, the rest will be single loaded. Bristol will also emulate a bit-99 and a Bit-99m2 that includes some parameter on the front panel that were not available on the original. The engine uses the exact same algorithm for all emulations but the GUI presents different sets of parameters on the front panel. Those that are not displayed can only be accessed from the data entry buttons. The -99m2 put in a few extra features (ie, took a few liberties) that were not in the original: DCO adds PWM from the LFO, not in the original DCO-2 adds Sync to DCO-1, also not in the original DCO-2 adds FM from DCO-1 DCO add PWM from Envelope Glide has been added DCO harmonics are not necessarily exclusive Various envelope option for LFO S&H LFO modulation The reason these were added was that bristol could already do them so were quite easy to incorporate, and at least gave two slightly different emulations. The oscillators can work slightly differently as well. Since this is a purely digital emulations then the filters are a bit weak. This is slightly compensated by the ability to configure more complex DCO. The transpose selectors (32', 16', 8' and 2') were exclusive in the original. That is true here also, however if controllers 84 and 85 are set to zero then they can all work together to fatten out the sound. Also, the controllers look like boolean however that is only the case if the data entry buttons are used, if you change the value with the data entry pot then they act more like continuous drawbars, a nice effect however the display will not show the actual value as the display remains boolean, you have to use your ear. The square wave is exclusive and will typically only function on the most recently selected (ie, typically highest) harmonic. The same continuous control is also available on the waveform selectors. You can mix the waveform as per the original however the apparent boolean selectors are again continuous from 0.0 to 1.0. The net result is that the oscillators are quite Voxy having the ability to mix various harmonic levels of different mixable waveforms. The stereo mode should be correctly implemented too. The synth was not really stereo, it had two outputs - one for each layer. As bristol is stereo then each layer is allocated to the left or right channel. In dual or split they came out separate feeds if Stereo was selected. This has the rather strange side effect of single mode with 6 voices. If stereo is not selected then you have a mono synth. If stereo is selected then voices will exit from a totally arbitrary output depending on which voices is allocated to each note. In contrast to the original the Stereo parameter is saved with the memory and if you dual load a split/layer it is taken from the first loaded memory only. The implementation actually uses two different stereo mixes selectable with the Stereo button: Mono is a centre pan of the signal and Stereo pans hardleft and hardright respectively. These mixes can be changed with parameters 110 to 117 using extended data entry documented below. The default emulation takes 6 voices for unison and applies 3+3 for the split and double modes. You can request more, for example if you used '-voices 16' at startup then you would be given 8+8. As a slight anomaly you cant request 32 voices - this is currently interpreted as the default and gives you 3+3. The bit-1 did not have the Stereo control - the controller presented is the Unison button. You can configure stereo from the extended data entry ID 110 and 111 which give the LR channel panning for 'Mono' setting, it should default to hard left and right panning. Similarly the -99 emulations do not have a Unison button, the capability is available from DE 80. The memories for the bit-1 and bit-99 should be interchangeable however the code maintains separate directories. There are three slightly different Bit GUI's. The first is the bit-1 with a limited parameter set as it only had 64 parameters. The second is the bit-99 that included midi and split options in the GUI and has the white design that was an offered by Crumar. The third is a slightly homogenous design that is specific to bristol, similar to the black panelled bit99 but with a couple of extra parameters. All the emulations have the same parameters, some require you use the data entry controls to access them. This is the same as the original, there were diverse parameters that were not in memories that needed to be entered manually every time you wanted the feature. The Bristol Bit-99m2 has about all of the parameters selectable from the front panel however all of the emulations use the same memories so it is not required to configure them at startup (ie, they are saved). The emulation recognises the following parameters: Data Entry 1 LFO-1 triangle wave selector (exclusive switch) Data Entry 2 LFO-1 ramp wave selector (exclusive switch) Data Entry 3 LFO-1 square wave selector (exclusive switch) Data Entry 4 LFO-1 route to DCO-1 Data Entry 5 LFO-1 route to DCO-2 Data Entry 6 LFO-1 route to VCF Data Entry 7 LFO-1 route to VCA Data Entry 8 LFO-1 delay Data Entry 9 LFO-1 frequency Data Entry 10 LFO-1 velocity to frequency sensitivity Data Entry 11 LFO-1 gain Data Entry 12 LFO-1 wheel to gain sensitivity Data Entry 13 VCF envelope Attack Data Entry 14 VCF envelope Decay Data Entry 15 VCF envelope Sustain Data Entry 16 VCF envelope Release Data Entry 17 VCF velocity to attack sensitivity (and decay/release) Data Entry 18 VCF keyboard tracking Data Entry 19 VCF cutoff Data Entry 20 VCF resonance Data Entry 21 VCF envelope amount Data Entry 22 VCF velocity to gain sensitivity Data Entry 23 VCF envelope invert Data Entry 24 DCO-1 32' harmonic Data Entry 25 DCO-1 16' harmonic Data Entry 26 DCO-1 8' harmonic Data Entry 27 DCO-1 4' harmonic Data Entry 28 DCO-1 Triangle wave Data Entry 29 DCO-1 Ramp wave Data Entry 30 DCO-1 Pulse wave Data Entry 31 DCO-1 Frequency 24 semitones Data Entry 32 DCO-1 Pulse width Data Entry 33 DCO-1 Velocity PWM Data Entry 34 DCO-1 Noise level Data Entry 35 DCO-2 32' harmonic Data Entry 36 DCO-2 16' harmonic Data Entry 37 DCO-2 8' harmonic Data Entry 38 DCO-2 4' harmonic Data Entry 39 DCO-2 Triangle wave Data Entry 40 DCO-2 Ramp wave Data Entry 41 DCO-2 Pulse wave Data Entry 42 DCO-2 Frequency 24 semitones Data Entry 43 DCO-2 Pulse width Data Entry 44 DCO-2 Env to pulse width Data Entry 45 DCO-2 Detune Data Entry 46 VCA velocity to attack sensitivity (and decay/release) Data Entry 47 VCA velocity to gain sensitivity Data Entry 48 VCA overall gain ADSR Data Entry 49 VCA Attack Data Entry 50 VCA Decay Data Entry 51 VCA Sustain Data Entry 52 VCA Release Data Entry 53 LFO-2 triangle wave selector (exclusive switch) Data Entry 54 LFO-2 saw wave selector (exclusive switch) Data Entry 55 LFO-2 square wave selector (exclusive switch) Data Entry 56 LFO-2 route to DCO-1 Data Entry 57 LFO-2 route to DCO-2 Data Entry 58 LFO-2 route to VCF Data Entry 59 LFO-2 route to VCA Data Entry 60 LFO-2 delay Data Entry 61 LFO-2 frequency Data Entry 62 LFO-2 velocity to frequency sensitivity Data Entry 63 LFO-2 gain Data Entry 12 LFO-2 wheel to gain sensitivity Data Entry 64 Split Data Entry 65 Upper layer transpose Data Entry 66 Lower Layer gain Data Entry 67 Upper Layer gain The following were visible in the Bit-99 graphics only: Data Entry 68 MIDI Mod wheel depth Data Entry 69 MIDI Velocity curve (0 = soft, 10=linear, 25 = hard) Data Entry 70 MIDI Enable Debug Data Entry 71 MIDI Enable Program Change Data Entry 72 MIDI Enable OMNI Mode Data Entry 73 MIDI Receive channel Data Entry 74 MIDI Mem Search Upwards Data Entry 75 MIDI Mem Search Downwards Data Entry 76 MIDI Panic (all notes off) Most of the MIDI options are not as per the original. This is because they are implemented in the bristol MIDI library and not the emulation. The following were added which were not really part of the Bit specifications so are only visible on the front panel of the bit100. For the other emulations they are accessible from the address entry buttons. Data Entry 77 DCO-1->DCO-2 FM Data Entry 78 DCO-2 Sync to DCO-1 Data Entry 79 Keyboard glide Data Entry 80 Unison Data Entry 81 LFO-1 SH Data Entry 82 LFO-1 PWM routing for DCO-1 Data Entry 83 LFO-1 PWM routing for DCO-2 Data Entry 84 LFO-1 wheel tracking frequency Data Entry 85 LFO-1 velocity tracking gain Data Entry 86 LFO-1 per layer or per voice Data Entry 87 LFO-2 SH Data Entry 88 LFO-2 PWM routing for DCO-1 Data Entry 89 LFO-2 PWM routing for DCO-2 Data Entry 90 LFO-2 wheel tracking frequency Data Entry 91 LFO-2 velocity tracking gain Data Entry 92 LFO-2 per layer or per voice Data Entry 93 ENV-1 PWM routing for DCO-1 Data Entry 94 ENV-1 PWM routing for DCO-2 Data Entry 95 DCO-1 restricted harmonics Data Entry 96 DCO-2 restricted harmonics Data Entry 97 VCF Filter type Data Entry 98 DCO-1 Mix Data Entry 99 Noise per layer Data Entry 00 Extended data entry (above 99) Extended data entry is for all parameters above number 99. Since the displays only have 2 digits it is not totally straightforward to enter these values and they are only available in Single mode, not dual or split - strangely similar to the original specification for editing memories. These are only activated for the lower layer loaded memory, not for dual loaded secondaries or upper layer loaded memories. You can edit the upper layer voices but they will be saved with their original extended parameters. This may seem correct however it is possible to edit an upper layer voice, save it, and have it sound different when next loaded since the extended parameters were taken from a different lower layer. This is kind of intentional but if in doubt then only ever dual load voices from the lower layer and edit them in single mode (not split or layer). Per default the emulation, as per the original, will not allow voice editing in Split or Layer modes however it can be enabled with DE 102. All the Bit emulations recognise extended parameters. They are somewhat in a disorganised list as they were built in as things developed. For the most part they should not be needed. The Bit-100 includes some in its silkscreen, for the others you can access them as follows: 1. deselect split or double 2. select addr entry 3. use 0..9 buttons to enter address 00 4. increment value to '1'. Last display should show EE (Extended Entry) 5. select last two digits of desired address with 0-9 buttons 6. change value (preferably with pot). 7. when finished, select address 00 again (this is now actually 100) to exit Data Entry 100 Exit extended data entry Data Entry 101 enable WriteThru scratchpad (disables park and compare) Data Entry 102 enable layer edits on Split/Double memories. Data Entry 103 LFO-1 Sync to note on Data Entry 104 LFO-2 Sync to note on Data Entry 105 ENV-1 zero retrigger Data Entry 106 ENV-2 zero retrigger Data Entry 107 LFO-1 zero retrigger Data Entry 108 LFO-2 zero retrigger Data Entry 109 Debug enable (0 == none, 5 == persistent) Data Entry 110 Left channel Mono gain, Lower Data Entry 111 Right channel Mono gain, Lower Data Entry 112 Left channel Stereo gain, Lower Data Entry 113 Right channel Stereo gain, Lower Data Entry 114 Left channel Mono gain, Upper Data Entry 115 Right channel Mono gain, Upper Data Entry 116 Left channel Stereo gain, Upper Data Entry 117 Right channel Stereo gain, Upper Data Entry 118 Bit-100 flag Data Entry 119 Temperature sensitivity Data Entry 120 MIDI Channel tracking layer-2 (same/different channel) Data Entry 121 MIDI Split point tracking layer-2 (same/different split) Data Entry 122 MIDI Transpose tracking (layer-2 or both layers) N/A Data Entry 123 MIDI NRP enable Data Entry 130 Free Memory Search Up Data Entry 131 Free Memory Search Down Data Entry 132 ENV-1 Conditional Data Entry 133 ENV-2 Conditional Data Entry 134 LFO-1 ENV Conditional Data Entry 135 LFO-2 ENV Conditional Data Entry 136 Noise white/pink Data Entry 137 Noise pink filter (enable DE 136 Pink) Data Entry 138 Glide duration 0 to 30 seconds Data Entry 139 Emulation gain level Data Entry 140 DCO-1 Square wave gain Data Entry 141 DCO-1 Subharmonic level Data Entry 142 DCO-2 Square wave gain Data Entry 143 DCO-2 Subharmonic level The 150 range will be incorporated when the Arpeggiator code is more stable, currently in development for the Jupiter. This is anticipated in 0.20.4: Data Entry 150 Arpeggiator Start/Stop Data Entry 151 Arpeggiator mode D, U/D, U or Random Data Entry 152 Arpeggiator range 1, 2, 3, 4 octaves Data Entry 153 Arpeggiator rate Data Entry 154 Arpeggiator external clock Data Entry 155 Arpeggiator retrigger envelopes Data Entry 156 Arpeggiator poly-2 mode Data Entry 157 Chord Enable Data Entry 158 Chord Relearn Data Entry 159 Sequencer Start/Stop Data Entry 160 Sequencer mode D, U/D, U or Random Data Entry 161 Sequencer range 1, 2, 3, 4 octaves Data Entry 162 Sequencer rate Data Entry 163 Sequencer external clock Data Entry 164 Sequencer retrigger envelopes Data Entry 165 Sequencer Relearn The following can be manually configured but are really for internal uses only and will be overwritten when memories are saved to disk. The Split/Join flag, for example, is used by dual loading memories to configure the peer layer to load the memory in DE-198, and the stereo placeholder for configuring the stereo status of any single loaded memory. Data Entry 193 Reserved: save bit-1 formatted memory Data Entry 194 Reserved: save bit-99 formatted memory Data Entry 195 Reserved: save bit-100 formatted memory Data Entry 196 Reserved: Split/Join flag - internal use Data Entry 197 Reserved: Stereo placeholder - internal use Data Entry 198 Reserved: Peer memory pointer - internal use Data Entry 199 Reserved: DCO-2 Wheel mod (masks entry 12) - internal use The tuning control in the emulation is on the front panel rather than on the rear panel as in the original. It had a keyboard sensitivity pot however that is achieved separately with bristol using velocity curves from the MIDI control settings. The front panel rotary defaults to 0% tuning and is not saved in the memory. The front panel gain controls are also not saved in the memory and default to 0.8 at startup. The net emulation is pretty intensive as it runs with over 150 operational parameters. A few notes are required on oscillator sync since by default it may seem to be quite noisy. The original could only produce a single waveform at a single frequency at any one time. Several emulators, including this one, use a bitone oscillator which generates complex waveforms. The Bristol Bitone can generate up to 4 waveforms simultaneously at different levels for 5 different harmonics and the consequent output is very rich, the waves can be slightly detuned, the pulse output can be PW modulated. As with all the bristol oscillators that support sync, the sync pulse is extracted as a postive leading zero crossing. Unfortunately if the complex bitone output is used as input to sync another oscillator then the result is far too many zero crossings to extract a good sync. Code has been implemented to generate a second sync source using a side output sync wave which is then fed to a sideband sync input on the oscillator, the results are far better Sequential Circuits Prophet Pro-One ----------------------------------- Sequential circuits released amongst the first truly polyphonic synthesisers where a group of voice circuits (5 to 10 of them) were linked to an onboard computer that gave the same parameters to each voice and drove the notes to each voice from the keyboard. The costs were nothing short of exhorbitant and this lead to Sequential releasing a model with just one voice board as a mono- phonic equivalent. The sales ran up to 10,000 units, a measure of its success and it continues to be recognised alongside the Mini Moog as a fat bass synth. The design of the Prophet synthesisers follows that of the Mini Moog. It has three oscillators one of them as a dedicated LFO. The second audio oscillator can also function as a second LFO, and can cross modulate oscillator A for FM type effects. The audible oscillators have fixed waveforms with pulse width modulation of the square wave. These are then mixed and sent to the filter with two envelopes, for the filter and amplifier. The Pro-1 had a nice bussing matrix where 3 different sources, LFO, Filter Env and Oscillator-B could be mixed in varying amounts to two different modulation busses and each bus could then be chosen as inputs to modulation destinations. One bus was a direct bus from the mixed parameters, the second bus was under the modwheel to give configurable expressive control. LFO: Frequency: 0.1 to 50 Hz Shape: Ramp/Triangle/Square. All can be selected, none selected should give a sine wave Modulations: Source: Filter Env amount to Direct or Wheel Mod busses Oscillator-B amount to Direct or Wheel Mod busses LFO to Direct amount or Wheel Mod busses Dest: Oscillator-A frequency from Direct or Wheel Mod busses Oscillator-A PWM from Direct or Wheel Mod busses Oscillator-B frequency from Direct or Wheel Mod busses Oscillator-B PWM from Direct or Wheel Mod busses Filter Cutoff from Direct or Wheel Mod busses Osc-A: Tune: +/-7 semitones Freq: 16' to 2' in octave steps Shape: Ramp or Square Pulse Width: only when Square is active. Sync: synchronise to Osc-B Osc-B: Tune: +/-7 semitones Freq: 16' to 2' in octave steps Fine: +/- 7 semitones Shape: Ramp/Triangle/Square Pulse Width: only when Square is active. LFO: Lowers frequency by 'several' octaves. KBD: enable/disable keyboard tracking. Mixer: Gain for Osc-A, Osc-B, Noise Filter: Cutoff: cuttof frequency Res: Resonance/Q/Emphasis Env: amount of modulation affecting to cutoff. KBD: amount of keyboard trackingn to cutoff Envelopes: One each for PolyMod (filter) and amplifier. Attack Decay Sustain Release Sequencer: On/Off Record Play Rate configured from LFO Arpeggiator: Up/Off/UpDown Rate configured from LFO Glide: Amount of portamento Auto/Normal - first key will/not glide. Global: Master Tune Master Volume Memories are loaded by selecting the 'Bank' button and typing in a two digit bank number followed by load. Once the bank has been selected then 8 memories from the bank can be loaded by pressing another memory select and pressing load. The display will show free memories (FRE) or programmed (PRG). There is an additional Up/Down which scan for the next program and a 'Find' key which will scan up to the next unused memory location. The original supported two sequences, Seq1 and Seq2, but these have not been implemented. Instead the emulator will save a sequence with each memory location which is a bit more flexible if not totally in the spirit of the original. The Envelope amount for the filter is actually 'Mod Amount'. To get the filter envelope to drive the filter it must be routed to the filter via a mod bus. This may differ from the original. Arpeggiator range is two octaves. The Mode options may not be correctly implemented due to the differences in the original being monophonic and the emulator being polyphonic. The Retrig is actually 'rezero' since we have separate voices. Drone is a Sustain key that emulates a sustain pedal. Osc-B cannot modulate itself in polyphonic mode (well, it could, it's just that it has not been coded that way). The filter envelope is configured to ignore velocity. The default filters are quite expensive. The -lwf option will select the less computationally expensive lightweight Chamberlain filters which have a colder response but require zonks fewer CPU cycles. Moog Voyager (Bristol "Explorer") --------------------------------- This was Robert Moog's last synth, similar in build to the Mini but created over a quarter of a century later and having far, far more flexibility. It was still monophonic, a flashback to a legendary synth but also a bit like Bjorn Borg taking his wooden tennis racket back to Wimbledon long after having retired and carbon fibre having come to pass. I have no idea who uses it and Bjorn also crashed out in the first round. The modulation routing is exceptional if not exactly clear. The Voyager, or Bristol Explorer, is definitely a child of the Mini. It has the same fold up control panel, three and half octave keyboard and very much that same look and feel. It follows the same rough design of three oscillators mixed with noise into a filter with envelopes for the filter and amplifier. In contrast there is an extra 4th oscillator, a dedicated LFO bus also Osc-3 can still function as a second LFO here. The waveforms are continuously selected, changing gradually to each form: bristol uses a form of morphing get get similar results. The envelopes are 4 stage rather than the 3 stage Mini, and the effects routing bears no comparison at all, being far more flexible here. Just because its funny to know, Robert Moog once stated that the most difficult part of building and releasing the Voyager was giving it the title 'Moog'. He had sold his company in the seventies and had to buy back the right to use his own name to release this synthesiser as a Moog, knowing that without that title it probably would not sell quite as well as it didn't. Control: LFO: Frequency Sync: LFO restarted with each keypress. Fine tune +/- one note Glide 0 to 30 seconds. Modulation Busses: Two busses are implemented. Both have similar capabilities but one is controlled by the mod wheel and the other is constantly on. Each bus has a selection of sources, shaping, destination selection and amount. Wheel Modulation: Depth is controller by mod wheel. Source: Triwave/Ramp/Sample&Hold/Osc-3/External Shape: Off/Key control/Envelope/On Dest: All Osc Frequency/Osc-2/Osc-3/Filter/FilterSpace/Waveform (*) Amount: 0 to 1. Constant Modulation: Can use Osc-3 as second LFO to fatten sound. Source: Triwave/Ramp/Sample&Hold/Osc-3/External Shape: Off/Key control/Envelope/On Dest: All Osc Frequency/Osc-2/Osc-3/Filter/FilterSpace/Waveform (*) Amount: 0 to 1. * Destination of filter is the cutoff frequency. Filter space is the difference in cutoff of the two layered filters. Waveform destination affects the continuously variable oscillator waveforms and allows for Pulse Width Modulation type effects with considerably more power since it can affect ramp to triangle for example, not just pulse width. Oscillators: Oscillator 1: Octave: 32' to 1' in octave steps Waveform: Continuous between Triangle/Ramp/Square/Pulse Oscillator 2: Tune: Continuous up/down 7 semitones. Octave: 32' to 1' in octave steps Waveform: Continuous between Triangle/Ramp/Square/Pulse Oscillator 3: Tune: Continuous up/down 7 semitones. Octave: 32' to 1' in octave steps Waveform: Continuous between Triangle/Ramp/Square/Pulse Sync: Synchronise Osc-2 to Osc-1 FM: Osc-3 frequency modulates Osc-1 KBD: Keyboard tracking Osc-3 Freq: Osc-3 as second LFO Mixer: Gain levels for each source: Osc-1/2/3, noise and external input. Filters: There are two filters with different configuration modes: 1. Two parallel resonant lowpass filters. 2. Serialised HPF and resonant LPF Cutoff: Frequency of cutoff Space: Distance between the cutoff of the two filters. Resonance: emphasis/Q. KBD tracking amount Mode: Select between the two operating modes. Envelopes: Attack Decay Sustain Release Amount to filter (positive and negative control) Velocity sensitivity of amplifier envelope. Master: Volume LFO: Single LFO or one per voice (polyphonic operation). Glide: On/Off portamento Release: On/Off envelope release. The Explorer has a control wheel and a control pad. The central section has the memory section plus a panel that can modify any of the synth parameters as a real time control. Press the first mouse key here and move the mouse around to adjust the controls. Default values are LFO frequency and filter cutoff but values can be changed with the 'panel' button. This is done by selecting 'panel' rather than 'midi', and then using the up/down keys to select parameter that will be affected by the x and y motion of the mouse. At the moment the mod routing from the pad controller is not saved to the memories, and it will remain so since the pad controller is not exactly omnipresent on MIDI master keyboards - the capabilities was put into the GIU to be 'exact' to the design. This synth is amazingly flexible and difficult to advise on its best use. Try starting by mixing just oscillator 1 through to the filter, working on mod and filter options to enrich the sound, playing with the oscillator switches for different effects and then slowly mix in oscillator 2 and 3 as desired. Memories are available via two grey up/down selector buttons, or a three digit number can be entered. There are two rows of black buttons where the top row is 0 to 4 and the second is 5 to 9. When a memory is selected the LCD display will show whether it is is free (FRE) or programmed already (PRG). Moog Sonic-6 ------------ This original design was made by an engineer who had previously worked with Moog on the big modular systems, Gene Zumchek. He tried to get Moog Inc to develop a small standalone unit rather than the behemoths however he could not get heard. After leaving he built a synth eventually called a Sonic-5 that did fit the bill but sales volumes were rather small. He had tied up with a business manager who worked out that the volume was largely due to the name not being known, muSonics. This was quickly overcome by accident. Moog managed to run his company into rather large debt and the company folded. Bill Waytena, working with Zumcheck, gathered together the funding needed to buy the remains of the failed company and hence Moog Inc was labled on the rebadged Sonic-6. Zumcheck was eventually forced to leave this company (or agreed to) as he could not work with Moog. After a few modifications Bob Moog actually used this unit quite widely for lecturing on electronic music. For demonstrative purposes it is far more flexible than any of Moog's own non-modular designs and it was housed in a transport case rather than needing a shipping crate as the modular systems required. The emulation features are given below, but first a few of the differences to the original Added a mod wheel that can drive GenX/Y. PWM is implemented on the oscillator B Installed an ADSR rather than AR, selectable. No alternative scalings - use scala file support Not duo or dia phonic. Primarily poly with separated glide. The original was duophonic, kind of. It had a keyboard with high note and low note precedence and the two oscillators could be driven from different notes. Its not really duophony and was reportedly not nice to play but it added some flexibility to the instrument. This features was dropped largley because it is ugly to emulate in a polyphonic environment but the code still has glide only on Osc-B. It has the two LFO that can be mixed, or at full throw of the GenXY mixer they will link X->A and Y->B giving some interesting routing, two osc each with their own LFO driving the LFO from the mod wheel or shaping it with the ADSR. Playing around should give access to X driving Osc-A, then Osc-A and GenY driving Osc-B with Mod and shaping for some investigation of FM synthesis. The gruesome direct output mixer is still there, having the osc and ring-mod bypass the filter and amplifier completely (or can be mixed back into the 'actuated' signal). There is currently no likely use for an external signal even though the graphics are there. The original envelope was AR or ASR. The emulator has a single ADSR and a control switch to select AR (actually AD), ASR, ADSD (MiniMoog envelope) or ADSR. Generator-Y has a S/H function on the noise source for a random signal which replaced the square wave. Generator-X still has a square wave. Modulators: Two LFO, X and Y: Gen X: Tri/Ramp/Saw/Square Tuning Shaping from Envelope or Modwheel Gen Y: Tri/Ramp/Saw/Rand Tuning Shaping from Envelope or Modwheel Master LFO frequency GenXY mixer Two Oscillators, A and B Gen A: Tri/Ramp/Pulse PulseWidth Tuning Transpose 16', 8', 4' (*) Mods: Envelope GenXY(or X) Low frequency, High Frequency (drone), KBD Tracking Gen B: Tri/Ramp/Pulse PulseWidth Tuning Transpose 16' 8', 4' Mods: Osc-B GenXY(or Y) PWM GenAB mix Ring Mod: Osc-B/Ext GenXY/Osc-A Noise Pink/White Mixer GenAB RingMod External Noise Filter (**) Cutoff Emphasis Mods: ADSR Keyboard tracking GenXY Envelope: AR/ASR/ADSD/ADSR Velociy on/off Trigger: GenX GenY Kbd (rezero only) Bypass (key gated audio) Direct Output Mixer Osc-A Osc-B RingMod The keyboard has controls for Glide (Osc-B only) Master Volume PitchWheel ModWheel (gain modifier on LFO) Global Tuning MultiLFO X and Y * The oscillator range was +/-2 octave switch and a +/-1 octave pot. This emulator has +/-1 octave switch and +/-7 note pot. That may change in a future release to be more like the original, probably having a multiway 5 stage octave selector. ** The filter will self oscillate at full emphasis however this is less prominent at lower frequencies (much like the Moog ladder filter). The filter is also 'not quite' in tune when played as an oscillator, this will also change in a future release. There may be a reverb on the emulator. Or there may not be, that depends on release. The PitchWheel is not saved in the memories, the unit is tuned on startup and this will maintain tuning to other instruments. The MultiLFO allow you to configure single LFO per emulation or one per voice, independently. Having polyphony means you can have the extra richness of independent LFO per voice however that does not work well if they are used as triggers, for example, you end up with a very noisy result. With single triggers for all voices the result is a lot more predictable. The Sonic-6 as often described as having bad tuning, that probably depends on model since different oscillators were used at times. Also, different units had different filters (Zumchek used a ladder of diodes to overcome the Moog ladder of transister patent). The original was often described as only being useful for sound effects. Personally I don't think that was true however the design is extremely flexible and the mods are applied with high gains so to get subtle sounds they only have to be applied lightly. Also, this critique was in comparison to the Mini which was not great for sound effects since it, in contrast, had very little in the way of modifiers. The actual mod routing here is very rich. The two LFO can be mixed to provide for more complex waves and have independent signal gain from the ADSR. To go a step further it is possible to take the two mixed LFO into Osc-A, configure that as an LFO and feed it into Osc-B for some very complex mod signals. That way you can get a frequency modulated LFO which is not possible from X or Y. As stated, if these are applied heavily you will get ray guns and car alarms but in small amounts it is possible to just shape sounds. Most of the mod controls have been made into power functions to give more control at small values. The memory panel gives access to 72 banks of 8 memories each. Press the Bank button and two digits for the bank, then just select the memory and press Load. You can get the single digit banks by selecting Bank->number->Bank. There is a save button which should require a double click but does not yet (0.30.0), a pair of buttons for searching up and down the available memories and a button called 'Find' which will select the next available free memory. Midi options include channel, channel down and, er, thats it. CRUMAR TRILOGY -------------- This text is primarily that of the Stratus since the two synths were very similar. This is the bigger brother having all the same features with the added string section. There were some minor differences in the synth circuits for switchable or mixable waveforms. This unit is a hybrid synth/organ/string combo, an early polyphonic using an organ divider circuit rather than independent VCO and having a set of filters and envelope for the synth sounds, most manufacturers came out with similar designs. The organ section was generally regarded as pretty bad here, there were just five controls, four used for the volume of 16, 8, 4 and 2 foot harmonics and a fifth for overall organ volume. The synth section had 6 voices and some quite neat little features for a glide circuitry and legato playing modes. The string section could mix 3 waveforms with vibrato on some so when mixed with the straight waveform would produce phasing. The emulator consists of two totally separate layers, one emulating the organ circuitry and another the synth. The organ has maximum available polyphony as the algorithm is quite lightweight even though diverse liberties have been taken to beef up the sound. The synth section is limited to 6 voices unless otherwise specified at run time. The organ circuitry is used to generate the string section. The legato playing modes affects three sections, the LFO modulation, VCO selection and glide: LFO: this mod has a basic envelope to control the gain of the LFO using delay, slope and gain. In 'multi' mode the envelope is triggered for every note that is played and in the emulator this is actually a separate LFO per voice, a bit fatter than the original. In 'Mono' mode there is only one LFO that all voices will share and the envelope is triggered in Legato style, ie, only once for a sequence of notes - all have to be released for the envelope to recover. VCO: The original allowed for wavaeform selection to alternate between notes, something that is rather ugly to do with the bristol architecture. This is replaced with a VCO selector where each note will only take the output from one of the two avalable oscillators and gives the ntoes a little more separation. The legato mode works whereby the oscillator selection is only made for the first note in a sequence to give a little more sound consistency. Glide: This is probably the coolest feature of the synth. Since it used an organ divider circuit it was not possible to actually glide from one note to another - there are really only two oscillators in the synth section, not two per voice. In contrast the glide section could glide up or down from a selected amount to the real frequency. Selected from down with suitable values would give a nice 'blue note' effect for example. In Legato mode this is done only for the first keypress rather than all of the since the effect can be a bit over the top if applied to each keystroke in a sequence. At the same time it was possible to Sync the two oscillators, so having only one of them glide and be in sync then without legato this gave a big phasing entrance to each note, a very interesting effect. The Glide has 4 modes: A. Both oscillators glide up to the target frequency B. Only oscillator-2 glides up to the target frequency C. Only oscillator-2 glides down to the target frequency D. Both oscillators glide down to the target frequency These glide options with different sync and legato lead to some very unique sounds and are emulated here with only minor differences. The features, then notes on the differences to the original: A. Organ Section 16, 8, 4 and 2 foot harmonic strengths. Volume. B. Synth Section LFO Modulation Rate - 0.1 to 50Hz approx Slope - up to 10 seconds Delay - up to 10 seconds Gain Routing selector: VCO, VCF, VCA Mono/Multi legato mode Shape - Tri/Ramp/Saw/Square Oscillator 1 Tuning Sync 2 to 1 Octave selector Oscillator 2 Tuning Octave trill Octave selector Waveform Ramp and Square mix Alternate on/off Mono/Multi legato mode VCO selection Glide Amount up or down from true frequency Speed of glide Mono/Multi legato mode Direction A, B, C, D Filter Cutoff frequency Resonance Envelope tracking -ve to +ve Pedal tracking on/off Envelope Attack Decay Sustain Release Gain C. String Section 16' 8' mix Subharmonic gain Attack Release Volume Diverse liberties were taken with the reproduction, these are manageable from the options panel by selecting the button next to the keyboard. This opens up a graphic of a PCB, mostly done for humorous effect as it not in the least bit representative of the actual hardware. Here there are a number of surface mounted controllers. These are as below but may change by release: P1 Master volume P2 Organ pan P3 Organ waveform distorts P4 Organ spacialisation P5 Organ mod level J1 Organ key grooming P6 Organ tuning (currently inactive *) P7 Synth pan P8 Synth tuning P9 Synth osc1 harmonics P10 Synth osc2 harmonics J2 Synth velocity sensitivity J3 Synth filter type P11 Synth filter tracking P12 String pan P13 String harmonics P14 String spacialisation P15 String mod level P16 String waveform distorts *: To make the organ tunable the keymap file has to be removed. Master (P1) volume affects both layers simultaneously and each layer can be panned (P2/P7) and tuned (P8) separately to give phasing and spacialisation. The synth layer has the default frequency map of equal temperament however the organ section uses a 2MHz divider frequency map that is a few cents out for each key. The Trilogy actually has this map for both layers and that can easily be done with the emulator, details on request. It is currently not possible to retune the organ divider circuit, it has a private microtonal mapping to emulate the few percent anomalies of the divider circuit and the frequencies are predefined. The pot is still visible in P6 and can be activated by removing the related microtonal mapping file, details from the author on request. Diverse liberties were taken with the Organ section since the original only produced 4 pure (infinite bandwidth) square waves that were mixed together, an overly weak result. The emulator adds a waveform distort (P3), an notched control that produces a pure sine wave at centre point. Going down it will generate gradually increasing 3rd and 5th harmonics to give it a squarey wave with a distinct hammond tone. The distortion actually came from the B3 emulator which models the distort on the shape of the hammond tonewheels themselves. Going up from centre point will produce gradually sharper sawtooth waves using a different phase distortion. Organ spacialisation (P4) will separate out the 4 harmonics to give them slightly different left and right positions to fatten out the sound. This works in conjunction with the mod level (P5) where one of the stereo components of each wave is modified by the LFO to give phasing changes up to vibrato. The organ key grooming (J1) will either give a groomed wave to remove any audible clicks from the key on and off events or when selected will produce something akin to a percussive ping for the start of the note. The result for the organ section is that it can produce some quite nice sounds reminiscent of the farfisa range to not quite hammond, either way far more useful than the flat, honking square waves. The original sound can be made by waveform to a quarter turn or less, spacialisation and mod to zero, key grooming off. The synth has 5 modifications at the first release. The oscillator harmonics can be fattened at the top or bottom using P9 and P10, one control for each oscillator, low is more bass, high is more treble. Some of the additional harmonics will be automatically detuned a little to fatten out the sound as a function of the -detune parameter defaulting to 100. The envelope can have its velocity sensitively to the filter enabled or disabled (J2) and the filter type can be a light weight filter for a thinner sound but at far lower CPU load (J3). The filter keyboard tracking is configurable (P11), this was outside of the spec of the Trilogy however it was implemented here to correct the keyboard tracking of the filter for all the emulations and the filter should now be playable. The envelope touch will affect this depending on J2 since velocity affects the cut off frequency and that is noticeable when playing the filter. This jumper is there so that the envelope does not adversely affect tuning but can still be used to have the filter open up with velocity if desired. The mod application is different from the original. It had a three way selector for routing the LFO to either VCO, VCA or VCF but only a single route. This emulation uses a continuous notched control where full off is VCO only, notch is VCF only and full on is VCA however the intermidiate positions will route proportional amounts to two components. The LFO has more options (Ramp and Saw) than the original (Tri and Square). The extra options are saved with each memory however they are only loaded at initialisation and when the 'Load' button is double-clicked. This allows you to have them as global settings or per memory as desired. The MemUp and MemDown will not load the options, only the main settings. VCO mod routing is a little bit arbitrary in this first release however I could not find details of the actual implementation. The VCO mod routing only goes to Osc-1 which also takes mod from the joystick downward motion. Mod routing to Osc-2 only happens if 'trill' is selected. This seemed to give the most flexibility, directing the LFO to VCF/VCA and controlling vibrato from the stick, then having Osc-2 separate so that it can be modified and sync'ed to give some interesting phasing. As of the first release there are possibly some issues with the oscillator Sync selector, it is perhaps a bit noisy with a high content of square wave. Also, there are a couple of minor improvements that could be made to the legato features but they will be done in a future release. They regard how the glide is applied to the first or all in a sequence of notes. The joystick does not always pick up correctly however it is largely for presentation, doing actual work you would use a real joystick or just use the modwheel (the stick generates and tracks continuous controller 1 - mod). The modwheel tracking is also a bit odd but reflects the original architecture - at midpoint on the wheel there is no net modulation, going down affects VCO in increasing amounts and going up from mid affect the VCF. The control feels like it should be notched however generally that is not the case with mod wheels. A few notes are required on oscillator sync since by default it will seem to be quite noisy. The original could only product a single waveform at a single frequency at any one time. Several emulators, including this one, use a bitone oscillator which generates complex waveforms. The Bristol Bitone can generate up to 4 waveforms simultaneously at different levels for 5 different harmonics and the consequent output is very rich, the waves can be slightly detuned, the pulse output can be PW modulated. As with all the bristol oscillators that support sync, the sync pulse is extracted as a postive leading zero crossing. Unfortunately if the complex bitone output is used as input to sync another oscillator then the result is far too many zero crossings to extract a good sync. For the time being you will have to simplify the sync source to get a good synchronised output which itself may be complex wave. A future release will add a sync signal from the bitone which will be a single harmonic at the base frequency and allow both syncing and synchronised waveform outputs to be arbitrary. For the Trilogy this simplification of the sync waveform is done automatically by the Sync switch, this means the synchronised output sounds correct but the overall waveform may be simpler. CRUMAR STRATUS -------------- This unit is a hybrid synth/organ combo, an early polyphonic synth using an organ divider circuit rather than independent VCO and having a set of filters and envelope for the synth sounds, most manufacturers came out with similar designs. The organ section was generally regarded as pretty bad here, there were just five controls, four used for the volume of 16, 8, 4 and 2 foot harmonics and a fifth for overall organ volume. The synth section had 6 voices and some quite neat little features for a glide circuitry and legato playing modes. The emulator consists of two totally separate layers, one emulating the organ circuitry and another the synth. The organ has maximum available polyphony as the algorithm is quite lightweight even though diverse liberties have been taken to beef up the sound. The synth section is limited to 6 voices unless otherwise specified at run time. The legato playing modes affects three sections, the LFO modulation, VCO selection and glide: LFO: this mod has a basic envelope to control the gain of the LFO using delay, slope and gain. In 'multi' mode the envelope is triggered for every note that is played and in the emulator this is actually a separate LFO per voice, a bit fatter than the original. In 'Mono' mode there is only one LFO that all voices will share and the envelope is triggered in Legato style, ie, only once for a sequence of notes - all have to be released for the envelope to recover. VCO: The original allowed for wavaeform selection to alternate between notes, something that is rather ugly to do with the bristol architecture. This is replaced with a VCO selector where each note will only take the output from one of the two avalable oscillators and gives the ntoes a little more separation. The legato mode works whereby the oscillator selection is only made for the first note in a sequence to give a little more sound consistency. Glide: This is probably the coolest feature of the synth. Since it used an organ divider circuit it was not possible to actually glide from one note to another - there are really only two oscillators in the synth section, not two per voice. In contrast the glide section could glide up or down from a selected amount to the real frequency. Selected from down with suitable values would give a nice 'blue note' effect for example. In Legato mode this is done only for the first keypress rather than all of the since the effect can be a bit over the top if applied to each keystroke in a sequence. At the same time it was possible to Sync the two oscillators, so having only one of them glide and be in sync then without legato this gave a big phasing entrance to each note, a very interesting effect. The Glide has 4 modes: A. Both oscillators glide up to the target frequency B. Only oscillator-2 glides up to the target frequency C. Only oscillator-2 glides down to the target frequency D. Both oscillators glide down to the target frequency These glide options with different sync and legato lead to some very unique sounds and are emulated here with only minor differences. The features, then notes on the differences to the original: A. Organ Section 16, 8, 4 and 2 foot harmonic strengths. Volume. B. Synth Section LFO Modulation Rate - 0.1 to 50Hz approx Slope - up to 10 seconds Delay - up to 10 seconds Gain Routing selector: VCO, VCF, VCA Mono/Multi legato mode Shape - Tri/Ramp/Saw/Square Oscillator 1 Tuning Sync 2 to 1 Octave selector Oscillator 2 Tuning Octave trill Octave selector Waveform Ramp and Square mix Alternate on/off Mono/Multi legato mode VCO selection Glide Amount up or down from true frequency Speed of glide Mono/Multi legato mode Direction A, B, C, D Filter Cutoff frequency Resonance Envelope tracking -ve to +ve Pedal tracking on/off Envelope Attack Decay Sustain Release Gain Diverse liberties were taken with the reproduction, these are manageable from the options panel by selecting the button next to the keyboard. This opens up a graphic of a PCB, mostly done for humorous effect as it not in the least bit representative of the actual hardware. Here there are a number of surface mounted controllers. These are as below but may change by release: P1 Master volume P2 Organ pan P3 Organ waveform distorts P4 Organ spacialisation P5 Organ mod level J1 Organ key grooming P6 Organ tuning (currently inactive *) P7 Synth pan P8 Synth tuning P9 Synth osc1 harmonics P10 Synth osc2 harmonics J2 Synth velocity sensitivity J3 Synth filter type P11 Synth filter tracking *: To make the organ tunable the keymap file has to be removed. Master (P1) volume affects both layers simultaneously and each layer can be panned (P2/P7) and tuned (P8) separately to give phasing and spacialisation. The synth layer has the default frequency map of equal temperament however the organ section uses a 2MHz divider frequency map that is a few cents out for each key. The Stratus actually has this map for both layers and that can easily be done with the emulator, details on request. It is currently not possible to retune the organ divider circuit, it has a private microtonal mapping to emulate the few percent anomalies of the divider circuit and the frequencies are predefined. The pot is still visible in P6 and can be activated by removing the related microtonal mapping file, details from the author on request. Diverse liberties were taken with the Organ section since the original only produced 4 pure (infinite bandwidth) square waves that were mixed together, an overly weak result. The emulator adds a waveform distort (P3), an notched control that produces a pure sine wave at centre point. Going down it will generate gradually increasing 3rd and 5th harmonics to give it a squarey wave with a distinct hammond tone. The distortion actually came from the B3 emulator which models the distort on the shape of the hammond tonewheels themselves. Going up from centre point will produce gradually sharper sawtooth waves using a different phase distortion. Organ spacialisation (P4) will separate out the 4 harmonics to give them slightly different left and right positions to fatten out the sound. This works in conjunction with the mod level (P5) where one of the stereo components of each wave is modified by the LFO to give phasing changes up to vibrato. The organ key grooming (J1) will either give a groomed wave to remove any audible clicks from the key on and off events or when selected will produce something akin to a percussive ping for the start of the note. The result for the organ section is that it can produce some quite nice sounds reminiscent of the farfisa range to not quite hammond, either way far more useful than the flat, honking square waves. The original sound can be made by waveform to a quarter turn or less, spacialisation and mod to zero, key grooming off. The synth has 5 modifications at the first release. The oscillator harmonics can be fattened at the top or bottom using P9 and P10, one control for each oscillator, low is more bass, high is more treble. Some of the additional harmonics will be automatically detuned a little to fatten out the sound as a function of the -detune parameter defaulting to 100. The envelope can have its velocity sensitively to the filter enabled or disabled (J2) and the filter type can be a light weight filter for a thinner sound but at far lower CPU load (J3). The filter keyboard tracking is configurable (P11), this was outside of the spec of the Stratus however it was implemented here to correct the keyboard tracking of the filter for all the emulations and the filter should now be playable. The envelope touch will affect this depending on J2 since velocity affects the cut off frequency and that is noticeable when playing the filter. This jumper is there so that the envelope does not adversely affect tuning but can still be used to have the filter open up with velocity if desired. The mod application is different from the original. It had a three way selector for routing the LFO to either VCO, VCA or VCF but only a single route. This emulation uses a continuous notched control where full off is VCO only, notch is VCF only and full on is VCA however the intermidiate positions will route proportional amounts to two components. The LFO has more options (Ramp and Saw) than the original (Tri and Square). The extra options are saved with each memory however they are only loaded at initialisation and when the 'Load' button is double-clicked. This allows you to have them as global settings or per memory as desired. The MemUp and MemDown will not load the options, only the main settings. VCO mod routing is a little bit arbitrary in this first release however I could not find details of the actual implementation. The VCO mod routing only goes to Osc-1 which also takes mod from the joystick downward motion. Mod routing to Osc-2 only happens if 'trill' is selected. This seemed to give the most flexibility, directing the LFO to VCF/VCA and controlling vibrato from the stick, then having Osc-2 separate so that it can be modified and sync'ed to give some interesting phasing. As of the first release there are possibly some issues with the oscillator Sync selector, it is perhaps a bit noisy with a high content of square wave. Also, there are a couple of minor improvements that could be made to the legato features but they will be done in a future release. They regard how the glide is applied to the first or all in a sequence of notes. The joystick does not always pick up correctly however it is largely for presentation, doing actual work you would use a real joystick or just use the modwheel (the stick generates and tracks continuous controller 1 - mod). The modwheel tracking is also a bit odd but reflects the original architecture - at midpoint on the wheel there is no net modulation, going down affects VCO in increasing amounts and going up from mid affect the VCF. The control feels like it should be notched however generally that is not the case with mod wheels. A few notes are required on oscillator sync since by default it will seem to be quite noisy. The original could only product a single waveform at a single frequency at any one time. Several emulators, including this one, use a bitone oscillator which generates complex waveforms. The Bristol Bitone can generate up to 4 waveforms simultaneously at different levels for 5 different harmonics and the consequent output is very rich, the waves can be slightly detuned, the pulse output can be PW modulated. As with all the bristol oscillators that support sync, the sync pulse is extracted as a postive leading zero crossing. Unfortunately if the complex bitone output is used as input to sync another oscillator then the result is far too many zero crossings to extract a good sync. For the time being you will have to simplify the sync source to get a good synchronised output which itself may be complex wave. A future release will add a sync signal from the bitone which will be a single harmonic at the base frequency and allow both syncing and synchronised waveform outputs to be arbitrary. For the Stratus this simplification of the sync waveform is done automatically by the Sync switch, this means the synchronised output sounds correct but the overall waveform may be simpler. KORG POLY 800 ------------- This is a low cost hybrid synth, somewhere between the Korg PolySix and their Mono/Poly in that is polyphonic but only has one filter rather than one per voice that came with the PolySix. It may have also used organ divider circuits rather than individual oscillators - it did not have glide as a feature which would be indicative of a divider circuit. It featured 8 oscillators that could be applied as either 4 voices with dual osc or 8 voices with a single osc. The architecture was verging on the interesting since each oscillator was fead into an individual envelope generator (described below) and then summed into the single filter, the filter having another envelope generator, 9 in total. This lead to cost reduction over having a filter per voice however the single filter leads to breathing, also discussed below. The envelopes were digitally generated by an on-board CPU. The control panel has a volume, global tuning control and a 'Bend' control that governs the depth of the pitch bend from the joystick and the overall amount of DCO modulation applied by the joystick. There is no sequencer in this emulation largely because there are far better options now available than this had but also due to a shortage of onscreen realestate. The Poly, Chord and Hold keys are emulated, hold being a sustain key. The Chord relearn function works follows: Press the Hold key Press the Chord key with 2 seconds Press the notes on the keyboard (*) Press the Chord key again After that the single chord can be played from a single note as a monophonic instrument. The Chord is saved individually with each memory. * Note that the chord is only saved if (a) it was played from the GUI keyboard or (b) the GUI was linked up to any MIDI device as well as the engine. The reason is that the GUI maintains memories and so if a chord is played on your actual keyboard then both the engine and the GUI needs a copy, the engine to be able to play the notes and the GUI to be able to save them. The keypanel should function very similar to the original. There is a Prog button that selects between Program selection or Parameter selection and an LED should show where the action is. There is the telephone keyboard to enter program or parameters numbers and an up/down selector for parameter value. The Bank/Hold selector also works, it fixes the bank number so programs can be recalled from a single bank with a single button press. The Write function is as per the original - Press Write, then two digits to save a memory. The front panel consists of a data entry panel and a silkscreen of the parameter numbers (this silkscreen is active in the emulation). Fifty parameters are available from the original instrument: DE 11 DCO1 Octave transposition +2 octaves DE 12 DCO1 Waveform Square or Ramp DE 13 DCO1 16' harmonic DE 14 DCO1 8' harmonic DE 15 DCO1 4' harmonic DE 16 DCO1 2' harmonic DE 17 DCO1 level DE 18 DCO Double (4 voice) or Single (8 voice) DE 21 DCO2 Octave transposition +2 octaves DE 22 DCO2 Waveform Square or Ramp DE 23 DCO2 16' harmonic DE 24 DCO2 8' harmonic DE 25 DCO2 4' harmonic DE 26 DCO2 2' harmonic DE 27 DCO2 level DE 31 DCO2 semitone transpose DE 32 DCO2 detune DE 33 Noise level DE 41 Filter cutoff frequency DE 42 Filter Resonance DE 43 Filter Keyboard tracking off/half/full DE 44 Filter Envelope polarity DE 45 Filter Envelope amount DE 46 Filter Envelope retrigger DE 48 Chorus On/Off DE 51 Env-1 DCO1 Attack DE 52 Env-1 DCO1 Decay DE 53 Env-1 DCO1 Breakpoint DE 54 Env-1 DCO1 Slope DE 55 Env-1 DCO1 Sustain DE 56 Env-1 DCO1 Release DE 61 Env-2 DCO2 Attack DE 62 Env-2 DCO2 Decay DE 63 Env-2 DCO2 Breakpoint DE 64 Env-2 DCO2 Slope DE 65 Env-2 DCO2 Sustain DE 66 Env-2 DCO2 Release DE 71 Env-3 Filter Attack DE 72 Env-3 Filter Decay DE 73 Env-3 Filter Breakpoint DE 74 Env-3 Filter Slope DE 75 Env-3 Filter Sustain DE 76 Env-3 Filter Release DE 81 Mod LFO Frequency DE 82 Mod Delay DE 83 Mod DCO DE 84 Mod VCF DE 86 Midi channel DE 87 Midi program change enable DE 88 Midi OMNI Of these 25 pararmeters, the emulation has changed 88 to be OMNI mode rather than the original sequence clock as internal or external. This is because the sequencer function was dropped as explained above. Additional to the original many of the controls which are depicted as on/off are actually continuous. For example, the waveform appears to be either square or ramp. The emulator allows you to use the up/down Value keys to reproduce this however if you use the potentiometer then you can gradually move from one wave to the next. The different harmonics are also not on/off, you can mix each of them together with different amounts and if you configure a mixture of waveforms and a bit of detune the sound should widen due to addition of a bit of phasing within the actual oscillator. The envelope generators are not typical ADSR. There is an initial attack from zero to max gain then decay to a 'Breakpoint'. When this has been reached then the 'Slope' parameter will take the signal to the Sustain level, then finally the release rate. The extra step of breakpoint and slope give plenty of extra flexibility to try and adjust for the loss of a filter per voice and the emulation has a linear step which should be the same as the original. The ninth envelope is applied to the single filter and also as the envelope for the noise signal level. The single filter always responded to the highest note on the keyboard. This gives a weaker overall sound and if playing with two hands then there is a noticible effect with keytracking - left hand held chords will cause filter breathing as the right hand plays solos and the keyboard tracking changes from high to low octaves. Note that the emulator will implement a single filter if you select DE 46 filter envelope retrigger to be single trigger, it will be played legato style. If multiple triggers are selected then the emulator will produce a filter and envelope for each voice. Bristol adds a number of extra parameters to the emulator that are not available from the mouse on the silkscreen and were not a part of the design of the poly800. You have to select Prog such that the LED is lit next to the Param display, then select the two digit parameter from the telephone keyboard: DE 28 DCO Sync 2 to 1 DE 34 DCO-1 PW DE 35 DCO-1 PWM DE 36 DCO-2 PW DE 37 DCO-2 PWM DE 38 DCO temperature sensitivity DE 67 DCO Glide DE 85 Mod - Uni/Multi per voice or globally DE 57 Envelope Touch response DE 47 Chorus Parameter 0 DE 58 Chorus Parameter 1 DE 68 Chorus Parameter 2 DE 78 Chorus Parameter 3 If DataEntry 28 is selected for oscillator sync then LFO MOD to DCO-1 is no longer applied, it only goes to DCO-2. This allows for the interesting sync modulated slow vibrato of DCO-2. The LFO mod is still applied via the joystick. DE 38 global detune will apply both temperature sensitivity to each oscillator but also fatten out the harmonics by detuning them independently. It is only calculated at 'note on' which can be misleading - it has no effect on existing notes which is intentional if misleading. DE 57 is a bitmask for the three envelopes to define which ones will give a response to velocity with a default to '3' for velocity tracking oscillator gain: value DEG1 DEG2 DEG3 DCO1 DCO2 FILT 0 - - - 1 V - - 2 - V - 3 V V - 4 - - V 5 V - V 6 - V V 7 V V V This gives some interesting velocity tracking capabilities where just one osc can track velocity to introduce harmonic content keeping the filter at a fixed cutoff frequence. Having a bit of detune applied globally and locally will keep the sound reasonably fat for each oscillator. The filter envelope does not track velocity for any of the distributed voices, this was intentional since when using high resonance it is not desirable that the filter cutoff changes with velocity, it tends to be inconsistently disonant. If you want to use this synth with controller mappings then map the value entry pot to your easiest to find rotary, then click the mouse on the membrane switch to select which parameter you want to adjust with that control each time. The emulator is naturally not limited to just 4/8 voices, you can request more in which case single oscillator will give you the requested number of voices and double will give you half that amount. The Bristol Poly-800 is dedicated to Mark. Baumann BME-700 --------------- This unusual German synth had a build volume of about 500 units and only one useful source of information could be found on it: a report on repair work for one of the few existing examples at www.bluesynths.com. The BME systems were hand built and judging by some reports on build quality may have been sold in kit form. The unit was produced in the mid 1970's. The synth has a very interesting design, somewhat reminiscent of the Moog Sonic and Explorer synths. It has two modulating LFO with fairly high top frequency, two filter and two envelopes. The envelopes are either AR or ASR but they can be mixed together to generate amongst other features an ADSR, very innovative. There is only one oscillator but the sound is fattened out by the use of two parallel filters, one acting as a pure resonator and the other as a full VCF. The synth has been left with a minimum of overhead. There are just 8 memory locations on the front panel with Load, Save and Increment buttons and one panel of options to adjust a few parameters on the oscillator and filters. It is possible to get extra memories by loading banks with -load: if you request starting in memory #21 the emulator will stuff 20 into the bank and 1 into the memory location. There is no apparant midi channel selector, use -channel and then stay on it. This could have been put into the options panel however having midi channel in a memory is generally a bad idea. A. MOD Two LFO: frequency from 0.1 to 100 Hz Triangle and Square wave outputs Mix control Mod-1/2 into the VCO FM Env-1/Mod-2 into the VCO FM B. Oscillator Single VCO Glide 0 to 10s, on/off. PW Man: 5 to 50% duty cycle Auto depth: Envelope-1 Mod-1, Mod-1/2, Tri/Square Vibrato depth Tuning 8', 4', 16' transposition Shape continuous control from Square to Tri wave. Mix of noise or VCO output C. Res Filter Sharp (24db/Oct), Flat (12dB/Oct) 5 frequency switches D. Envelopes Two envelopes Rise time Fall Time AR/ASR selector Two independent mixes of Env, for VCF and VCA. E. Filter Frequency Resonance Env/Mod selector Modulation KBD tracking Mod-1 or Mod-2, Tri/Square F. Amplifier Mix resonator/filter. Volume Mod depth Mod-1 or Mod-2, Tri/Square The oscillator is implemented as a non-resampling signal generator, this means it uses heuristics to estimate the wave at any given time. The harmonic content is a little thin and although the generation method seems to be correct in how it interprets signal ramps and drains from an analogue circuit this is one area of improvement in the emulator. There are options to produce multiple waveforms described below. The resonant filter is implemented with a single Houvilainen and actually only runs at 24dB/Oct. There are controls for remixing the different taps, a form of feedforward and when in 'Flat' mod there is more remixing of the poles, this does generate a slower roll off but gives the signal a bit more warmth than a pure 12dB/Oct would. There is a selector in the Memory section to access some options: G. Options LFO Synchronise wave to key on events Multi LFO (per voice). Oscillator Detune (temperature sensitivity) Multi - remix 8' with 16' or 4'. Noise Multi Noise (per voice). White/Pink Pink Filter ResFilter Sharp Resonance/Remix Flat Resonance/Remix Envelope Velocity Sensitive Rezero for note on Gain Filter Remix KBD tracking depth The emulator probably gives the best results with the following: startBristol -bme700 -mono -hnp -retrig -channel 1 This gives a monophonic emulation with high note preference and multiple triggers. The options from section G are only loaded under two circumstances: at system start from the first selected memory location and if the Load button is given a DoubleClick. All other memory load functions will inherrit the settings that are currently active. Bristol BassMaker ----------------- The BassMaker is not actually an emulator, it is a bespoke sequencer design but based on the capabilities of some of the early analogue sequencers such as the Korg SQ-10. Supplying this probably leaves bristol open to a lot of feature requests for sequencer functionaliity and it is stated here that the BassMaker is supposed to be simple so excess functionality will probably be declined as there are plenty of other sequencing applications that can provide a richer feature set. The main page gives access to a screen of controls for 16 steps and a total of 4 pages are available for a total of 64 steps. The pages are named 'A' through 'D'. Each step has 5 options: Note: one octave of note selection Transpose: +/- one octave transposition of the note. Volume: MIDI note velocity Controller: MIDI modulation, discussed further below Triggers: Note On/Off enablers The trigger button gives 4 options indicated by the LED: off: note on/off are sent red: only send note_on green: only send note_off yellow: do not send note on/off The 'Controllers' setting has multiple functions which can be selected from the menu as explained below. The options available are as follows: Send semitone tuning Send glide rate Send modwheel Send expression pedal (controller value) Send Note: the controller will be 12 discrete steps as per the 'Note' setting and this note will be sent on the Secondary MIDI channel. The semitone tuning and glide work for the majority of the emulations. Some do not support fine tune controls (Vox, Hammond, others). If you are missing these capabilities for specific emulators raise a change request on Sourceforge.net. At the top of the window there is a panel to manage the sequencer. It has the following functions: Speed: step rate through the notes DutyCycle: ratio of note-on to note-off Start/Pause Stop: stop and return to first step/page Direction: Up Down Up/Down Random Select: which of the pages to include in the sequence. Edit: which page is currently displayed to be edited. Memory: 0..9 key entry buttons, 1000 memories available Load Save: doubleclick to save current sequence Menu Panel Up, Down menu Function (return to previous level) Enter: enter submenu or enter value if in submenu The menu consists of several tables, these can be stepped through using the Up and Down arrows to move through the menu and the 'Enter' arrow to select a sub menu or activate any option. The 'Fn' button returns one level: Memory: Find next free memory upwards Find next memory upwards Find next memory downwards Copy: Copy current edit page to 'A', 'B', 'C' or 'D'. Control - Set the control value to send: semitone tuning glide rate modwheel expression pedal (controller value) note events First midi channel Primary midi channel for note events Second midi channel Secondary midi channel when 'Control' configured to 'Note' events. Global Transpose Transpose the whole sequence up or down 12 semitones Clear - configure default value for all of the: Notes to zero Transpose to zero (midpoint) Volume to 0.8 Control to midpoint Triggers to on/off As of the first release in 0.30.8 large parts of the Controllers functionality was only lightly tested. If you do not get the results you anticipate you may require a fix. Bristol SID ----------- In release 0.40 bristol introduced a piece of code that emulated the Commodore C64 6581 SID chip. The interface uses byte settings of the 31 chip registers to be close to the original plus some floating point IO for extracting the audio signal and configuring some analogue parameters and the 'softSID' is clocked by the sample extraction process. The chip uses integer maths and logic for the oscillators, ring mod, sync and envelopes and emulates the analogue components of the 6581 with floating point code, for the filter and S/N generation. The oscillators will run as per the original using a single phase accumulator and 16 bit frequency space. All the waveforms are extracted logically from the ramp waveform generated by the phase accumulation. Sync and RingMod are also extracted with the same methods. The noise generation is exor/add as per the original however the noise signal will not degenerate when mixing waveforms. The output waves are ANDed together. The bristol control register has an option for Multi waveforms and when selected each oscillator will have its own phase accumulator, can have a detune applied and will be mixed by summation rather than using an AND function. The envelope is an 8 bit up/down counter with a single gate bit. All the 4 bit parameters give rates taken from the chip specifications including the slightly exponential decay and release. Attack is a linear function and the sustain level can only be decreased when active as the counter also refuses to count back up when passed its peak. The filter implements a 12dB/Octave multimode chamberlain filter providing LP, BP and HP signals. This is not the best filter in the world however neither was the original. An additional 24dB/Octave LP filter has been added, optionally available and with feedforward to provide 12/18dB signals. Between them the output can be quite rich. The emulator provides some control over the 'analogue' section. The S/N ratio can be configured from inaudible (just used to prevent denormal of the filter) up to irritating levels. Oscillator leakage is configurable from none up to audible levels and the oscillator detune is configurable in cents although this is a digital parameter and was not a part of the original. Voice-3 provides an 8 bit output of its oscillator and envelope via the normal output registers and the otherwise unused X and Y Analogue registers contain the Voice-1 and Voice-2 oscillator output. The bristol -sid emulator uses two softSID, one generating three audio voices and a second one providing modulation signals by sampling the voice-3 osc and env outputs and also by configuring voice-1 to generate noise to the output, resampling this noise and gating it from voice-3 to get sample and hold. This would have been possible with the original as well if the output signal were suitably coupled back on to one of the X/Y_Analogue inputs. The emulator has several key assignment modes. The emulator is always just monophonic but uses internal logic to assign voices. It can be played as a big mono synth with three voices/oscillators, polyphonically with all voices either sounding the same or optionally configured individually, and as of this release a single arpeggiating mode - Poly-3. Poly-3 will assign Voice-1 to the lowest note, voice-3 to the highest note and will arpeggiate Voice-2 through all other keys that are pressed with a very high step rate. This is to provide some of the sounds of the original C64 where fast arpeggiation was used to sounds chords rather than having to use all the voices. This first implementation does not play very well in Poly-3, a subsequent release will probably have a split keyboard option where one half will arpeggiate and the other half will play notes. This is NOT a SID player, that would require large parts of the C64 to also be emulated and there are plenty of SID players already available. Bristol again thanks Andrew Coughlan, here for proposing the implementation of a SID chip which turned out to be a very interesting project. For the sake of being complete, given below is the verbose help output A synthesiser emulation package. You should start this package with the startBristol script. This script will start up the bristol synthesiser binaries evaluating the correct library paths and executable paths. There are emulation, synthesiser, operational and GUI parameters: Emulation: -mini - moog mini -explorer - moog voyager -voyager - moog voyager electric blue -memory - moog memory -sonic6 - moog sonic 6 -mg1 - moog/realistic mg-1 concertmate -hammond - hammond module (deprecated, use -b3) -b3 - hammond B3 (default) -prophet - sequential circuits prophet-5 -pro52 - sequential circuits prophet-5/fx -pro10 - sequential circuits prophet-10 -pro1 - sequential circuits pro-one -rhodes - fender rhodes mark-I stage 73 -rhodesbass - fender rhodes bass piano -roadrunner - crumar roadrunner electric piano -bitone - crumar bit 01 -bit99 - crumar bit 99 -bit100 - crumar bit + mods -stratus - crumar stratus synth/organ combo -trilogy - crumar trilogy synth/organ/string combo -obx - oberheim OB-X -obxa - oberheim OB-Xa -axxe - arp axxe -odyssey - arp odyssey -arp2600 - arp 2600 -solina - arp/solina string ensemble -polysix - korg polysix -poly800 - korg poly-800 -monopoly - korg mono/poly -ms20 - korg ms20 (unfinished: -libtest only) -vox - vox continental -voxM2 - vox continental super/300/II -juno - roland juno-60 -jupiter - roland jupiter-8 -bme700 - baumann bme-700 -bm - bristol bassmaker sequencer -dx - yamaha dx-7 -cs80 - yamaha cs-80 (unfinished) -sidney - commodore-64 SID chip synth -melbourne - commodore-64 SID polyphonic synth (unfinished) -granular - granular synthesiser (unfinished) -aks - ems synthi-a (unfinished) -mixer - 16 track mixer (unfinished: -libtest only) Synthesiser: -voices - operate with a total of 'n' voices (32) -mono - operate with a single voice (-voices 1) -lnp - low note preference (-mono) -hnp - high note preference (-mono) -nnp - no/last note preference (-mono) -retrig - monophonic note logic legato trigger (-mono) -lvel - monophonic note logic legato velocity (-mono) -channel - initial midi channel selected to 'c' (default 1) -lowkey - minimum MIDI note response (0) -highkey - maximum MIDI note response (127) -detune <%> - 'temperature sensitivity' of emulation (0) -gain - emulator output signal gain (default 1) -pwd - pitch wheel depth (2 semitones) -velocity - MIDI velocity mapping curve (510) (-mvc) -glide - MIDI glide duration (5) -emulate - search for the named synth or exit -register - name used for jack and alsa device regisration -lwf - emulator lightweight filters -nwf - emulator default filters -wwf - emulator welterweight filters -hwf - emulator heavyweight filters -blo - maximum # band limited harmonics (31) -blofraction - band limiting nyquist fraction (0.8) -scala - read the scala .scl tonal mapping table User Interface: -quality - color cache depth (bbp 2..8) (6) -grayscale - color or BW display (0..5) (0 = color) -antialias - antialias depth (0..100%) (30) -aliastype - antialias type (pre/texture/all) -opacity - opacity of the patch layer 20..100% (50) -scale - initial windowsize, fs = fullscreen (1.0) -width - the pixel width of the GUI window -autozoom - flip between min and max window on Enter/Leave -raise - disable auto raise on max resize -lower - disable auto lower on min resize -rud - constrain rotary tracking to up/down -pixmap - use the pixmap interface rather than ximage -dct - double click timeout (250 ms) -tracking - disable MIDI keyboard tracking in GUI -load - load memory number 'm' (default 0) -import - import memory from file into synth -mbi - master bank index (0) -activesense - active sense rate (2000 ms) -ast - active sense timeout (15000 ms) -mct - midi cycle timeout (50 ms) -ar|-aspect - ignore emulator requested aspect ratio -iconify - start with iconified window -window - toggle switch to enable X11 window interfacen -cli - enable command line interface -libtest - gui test option, engine not invoked Gui keyboard shortcuts: 's' - save settings to current memory 'l' - (re)load current memory 'x' - exchange current with previous memory '+' - load next memory '-' - load previous memory '?' - show emulator help information 'h' - show emulator help information 'r' - show application readme information 'k' - show keyboard shortcuts 'p' - screendump to /tmp/.xpm 't' - toggle opacity 'o' - decrease opacity of patch layer 'O' - increase opacity of patch layer 'w' - display warranty 'g' - display GPL (copying conditions) '+' - increase window size '-' - decrease window size 'Enter'- toggle window between full screen size 'UpArrow' - controller motion up (shift key accelerator) 'DownArrow' - controller motion down (shift key accelerator) 'RightArrow' - more controller motion up (shift key accelerator) 'LeftArrow' - more controller motion down (shift key accelerator) Operational: General: -engine - don't start engine (connect to existing engine) -gui - don't start gui (only start engine) -server - run engine as a permanant server -daemon - run engine as a detached permanant server -log - redirect diagnostic to $HOME/.bristol/log -syslog - redirect diagnostic to syslog -console - log all messages to console (must be 1st option) -cache - memory and profile cache location (~/.bristol) -exec - run all subprocesses in background -debug <1-16> - debuging level (0) -readme [-] - show readme [for emulator ] to console -glwf - global lightweight filters - no overrides -host - connect to engine on host 'h' (localhost) -port

- connect to engine on TCP port 'p' (default 5028) -quiet - redirect diagnostic output to /dev/null -gmc - open a MIDI connection to the brighton GUI -oss - use OSS defaults for audio and MIDI -alsa - use ALSA defaults for audio and MIDI (default) -jack - use Jack defaults for audio and MIDI -jsmuuid - jack session unique identifier -jsmfile - jack session setting path -jsmd - jack session file load delay (5000) -session - disable session management -jdo - use separate Jack clients for audio and MIDI -osc - use OSC for control interface (unfinished) -forward - disable MIDI event forwarding globally -localforward - disable emulator gui->engine event forwarding -remoteforward - disable emulator engine->gui event forwarding -o - Duplicate raw audio output data to file -nrp - enable NPR support globally -enrp - enable NPR/DE support in engine -gnrp - enable NPR/RP/DE support in GUI -nrpcc - size of NRP controller table (128) Audio driver: -audio [oss|alsa|jack] - audio driver selection (alsa) -audiodev - audio device selection -count - sample period count (256) -outgain - digital output signal gain (default 4) -ingain - digital input signal gain (default 4) -preload - configure preload buffer count (default 4) -rate - sample rate (44100) -priority

- audio RT priority, 0=no realtime (75) -autoconn - attempt jack port auto-connect -multi - register 'c' IO channels (jack only) -migc - multi IO input gain scaling (jack only) -mogc - multi IO output gain scaling (jack only) Midi driver: -midi [oss|[raw]alsa|jack] - midi driver selection (alsa) -mididev - midi device selection -seq - use the ALSA SEQ interface (default) -mididbg - midi debug-1 enable -mididbg2 - midi debug-2 enable -sysid - MIDI SYSEX system identifier LADI driver (level 1 compliant): -ladi brighton - only execute LADI in GUI -ladi bristol - only execute LADI in engine -ladi - LADI state memory index (1024) Audio drivers are PCM/PCM_plug or Jack. Midi drivers are either OSS/ALSA rawmidi interface, or ALSA SEQ. Multiple GUIs can connect to the single audio engine which then operates multitimbrally. The LADI interfaces does not use a state file but a memory in the normal memory locations. This should typically be outside of the range of the select buttons for the synth and the default of 1024 is taken for this reason. Examples: startBristol Print a terse help message. startBristol -v -h Hm, if you're reading this you found these switches already. startBristol -mini Run a minimoog using ALSA interface for audio and midi seq. This is equivalent to all the following options: -mini -alsa -audiodev plughw:0,0 -midi seq -count 256 -preload 8 -port 5028 -voices 32 -channel 1 -rate 44100 -gain 4 -ingain 4 startBristol -alsa -mini Run a minimoog using ALSA interface for audio and midi. This is equivalent to all the following options: -mini -audio alsa -audiodev plughw:0,0 -midi alsa -mididev hw:0 -count 256 -preload 8 -port 5028 -voices 32 -channel 1 -rate 44100 startBristol -explorer -voices 1 -oss Run a moog explorer as a monophonic instrument, using OSS interface for audio and midi. startBristol -prophet -channel 3 Run a prophet-5 using ALSA for audio and midi on channel 3. startBristol -b3 -count 512 -preload 2 Run a hammond b3 with a buffer size of 512 samples, and preload two such buffers before going active. Some Live! cards need this larger buffer size with ALSA drivers. startBristol -oss -audiodev /dev/dsp1 -vox -voices 8 Run a vox continental using OSS device 1, and default midi device /dev/midi0. Operate with just 8 voices. startBristol -b3 -audio alsa -audiodev plughw:0,0 -seq -mididev 128.0 Run a B3 emulation over the ALSA PCM plug interface, using the ALSA sequencer over client 128, port 0. startBristol -juno & startBristol -prophet -channel 2 -engine Start two synthesisers, a juno and a prophet. Both synthesisers will will be executed on one engine (multitimbral) with 32 voices between them. The juno will be on default midi channel (1), and the prophet on channel 2. Output over the same default ALSA audio device. startBristol -juno & startBristol -port 5029 -audio oss -audiodev /dev/dsp1 -mididev /dev/midi1 Start two synthesisers, a juno on the first ALSA soundcard, and a mini on the second OSS soundcard. Each synth is totally independent and runs with 32 voice polyphony (looks nice, not been tested). The location of the bristol binaries can be specified in the BRISTOL environment variable. Private memory and MIDI controller mapping files can be found in the directory BRISTOL_CACHE and defaults to $HOME/.bristol Setting the environment variable BRISTOL_LOG_CONSOLE to any value will result in the bristol logging output going to your console window without formatted timestamps Korg Inc. of Japan is the rightful owner of the Korg and Vox trademarks, and the Polysix, Mono/Poly, Poly-800, MS-20 and Continental tradenames. Their own Vintage Collection provides emulations for a selection of their classic synthesiser range, this product is in no manner related to Korg other than giving homage to their great instruments. Bristol is in no manner associated with any of the original manufacturers of any of the emulated instruments. All names and trademarks are property of their respective owners. author: Nick Copeland email: nickycopeland@hotmail.com http://bristol.sourceforge.net bristol-0.60.11/INSTALL0000644000175000017500000003660012073601233011311 00000000000000Installation Instructions ************************* Copyright (C) 1994-1996, 1999-2002, 2004-2011 Free Software Foundation, Inc. Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. This file is offered as-is, without warranty of any kind. Basic Installation ================== Briefly, the shell commands `./configure; make; make install' should configure, build, and install this package. The following more-detailed instructions are generic; see the `README' file for instructions specific to this package. Some packages provide this `INSTALL' file but do not implement all of the features documented below. The lack of an optional feature in a given package is not necessarily a bug. More recommendations for GNU packages can be found in *note Makefile Conventions: (standards)Makefile Conventions. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a `Makefile' in each directory of the package. It may also create one or more `.h' files containing system-dependent definitions. Finally, it creates a shell script `config.status' that you can run in the future to recreate the current configuration, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). It can also use an optional file (typically called `config.cache' and enabled with `--cache-file=config.cache' or simply `-C') that saves the results of its tests to speed up reconfiguring. Caching is disabled by default to prevent problems with accidental use of stale cache files. If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the `README' so they can be considered for the next release. If you are using the cache, and at some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.ac' (or `configure.in') is used to create `configure' by a program called `autoconf'. You need `configure.ac' if you want to change it or regenerate `configure' using a newer version of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type `./configure' to configure the package for your system. Running `configure' might take a while. While running, it prints some messages telling which features it is checking for. 2. Type `make' to compile the package. 3. Optionally, type `make check' to run any self-tests that come with the package, generally using the just-built uninstalled binaries. 4. Type `make install' to install the programs and any data files and documentation. When installing into a prefix owned by root, it is recommended that the package be configured and built as a regular user, and only the `make install' phase executed with root privileges. 5. Optionally, type `make installcheck' to repeat any self-tests, but this time using the binaries in their final installed location. This target does not install anything. Running this target as a regular user, particularly if the prior `make install' required root privileges, verifies that the installation completed correctly. 6. You can remove the program binaries and object files from the source code directory by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. There is also a `make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. 7. Often, you can also type `make uninstall' to remove the installed files again. In practice, not all packages have tested that uninstallation works correctly, even though it is required by the GNU Coding Standards. 8. Some packages, particularly those that use Automake, provide `make distcheck', which can by used by developers to test that all other targets like `make install' and `make uninstall' work correctly. This target is generally not run by end users. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the `configure' script does not know about. Run `./configure --help' for details on some of the pertinent environment variables. You can give `configure' initial values for configuration parameters by setting variables in the command line or in the environment. Here is an example: ./configure CC=c99 CFLAGS=-g LIBS=-lposix *Note Defining Variables::, for more details. Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you can use GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. This is known as a "VPATH" build. With a non-GNU `make', it is safer to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use `make distclean' before reconfiguring for another architecture. On MacOS X 10.5 and later systems, you can create libraries and executables that work on multiple system types--known as "fat" or "universal" binaries--by specifying multiple `-arch' options to the compiler but only a single `-arch' option to the preprocessor. Like this: ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ CPP="gcc -E" CXXCPP="g++ -E" This is not guaranteed to produce working output in all cases, you may have to build one architecture at a time and combine the results using the `lipo' tool if you have problems. Installation Names ================== By default, `make install' installs the package's commands under `/usr/local/bin', include files under `/usr/local/include', etc. You can specify an installation prefix other than `/usr/local' by giving `configure' the option `--prefix=PREFIX', where PREFIX must be an absolute file name. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you pass the option `--exec-prefix=PREFIX' to `configure', the package uses PREFIX as the prefix for installing programs and libraries. Documentation and other data files still use the regular prefix. In addition, if you use an unusual directory layout you can give options like `--bindir=DIR' to specify different values for particular kinds of files. Run `configure --help' for a list of the directories you can set and what kinds of files go in them. In general, the default for these options is expressed in terms of `${prefix}', so that specifying just `--prefix' will affect all of the other directory specifications that were not explicitly provided. The most portable way to affect installation locations is to pass the correct locations to `configure'; however, many packages provide one or both of the following shortcuts of passing variable assignments to the `make install' command line to change installation locations without having to reconfigure or recompile. The first method involves providing an override variable for each affected directory. For example, `make install prefix=/alternate/directory' will choose an alternate location for all directory configuration variables that were expressed in terms of `${prefix}'. Any directories that were specified during `configure', but not in terms of `${prefix}', must each be overridden at install time for the entire installation to be relocated. The approach of makefile variable overrides for each directory variable is required by the GNU Coding Standards, and ideally causes no recompilation. However, some platforms have known limitations with the semantics of shared libraries that end up requiring recompilation when using this method, particularly noticeable in packages that use GNU Libtool. The second method involves providing the `DESTDIR' variable. For example, `make install DESTDIR=/alternate/directory' will prepend `/alternate/directory' before all installation names. The approach of `DESTDIR' overrides is not required by the GNU Coding Standards, and does not work on platforms that have drive letters. On the other hand, it does better at avoiding recompilation issues, and works well even when some directory options were not specified in terms of `${prefix}' at `configure' time. Optional Features ================= If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving `configure' the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE is something like `gnu-as' or `x' (for the X Window System). The `README' should mention any `--enable-' and `--with-' options that the package recognizes. For packages that use the X Window System, `configure' can usually find the X include and library files automatically, but if it doesn't, you can use the `configure' options `--x-includes=DIR' and `--x-libraries=DIR' to specify their locations. Some packages offer the ability to configure how verbose the execution of `make' will be. For these packages, running `./configure --enable-silent-rules' sets the default to minimal output, which can be overridden with `make V=1'; while running `./configure --disable-silent-rules' sets the default to verbose, which can be overridden with `make V=0'. Particular systems ================== On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC is not installed, it is recommended to use the following options in order to use an ANSI C compiler: ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" and if that doesn't work, install pre-built binaries of GCC for HP-UX. HP-UX `make' updates targets which have the same time stamps as their prerequisites, which makes it generally unusable when shipped generated files such as `configure' are involved. Use GNU `make' instead. On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot parse its `' header file. The option `-nodtk' can be used as a workaround. If GNU CC is not installed, it is therefore recommended to try ./configure CC="cc" and if that doesn't work, try ./configure CC="cc -nodtk" On Solaris, don't put `/usr/ucb' early in your `PATH'. This directory contains several dysfunctional programs; working variants of these programs are available in `/usr/bin'. So, if you need `/usr/ucb' in your `PATH', put it _after_ `/usr/bin'. On Haiku, software installed for all users goes in `/boot/common', not `/usr/local'. It is recommended to use the following options: ./configure --prefix=/boot/common Specifying the System Type ========================== There may be some features `configure' cannot figure out automatically, but needs to determine by the type of machine the package will run on. Usually, assuming the package is built to be run on the _same_ architectures, `configure' can figure that out, but if it prints a message saying it cannot guess the machine type, give it the `--build=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name which has the form: CPU-COMPANY-SYSTEM where SYSTEM can have one of these forms: OS KERNEL-OS See the file `config.sub' for the possible values of each field. If `config.sub' isn't included in this package, then this package doesn't need to know the machine type. If you are _building_ compiler tools for cross-compiling, you should use the option `--target=TYPE' to select the type of system they will produce code for. If you want to _use_ a cross compiler, that generates code for a platform different from the build platform, you should specify the "host" platform (i.e., that on which the generated programs will eventually be run) with `--host=TYPE'. Sharing Defaults ================ If you want to set default values for `configure' scripts to share, you can create a site shell script called `config.site' that gives default values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. A warning: not all `configure' scripts look for a site script. Defining Variables ================== Variables not defined in a site shell script can be set in the environment passed to `configure'. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set them in the `configure' command line, using `VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc causes the specified `gcc' to be used as the C compiler (unless it is overridden in the site shell script). Unfortunately, this technique does not work for `CONFIG_SHELL' due to an Autoconf bug. Until the bug is fixed you can use this workaround: CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash `configure' Invocation ====================== `configure' recognizes the following options to control how it operates. `--help' `-h' Print a summary of all of the options to `configure', and exit. `--help=short' `--help=recursive' Print a summary of the options unique to this package's `configure', and exit. The `short' variant lists options used only in the top level, while the `recursive' variant lists options also present in any nested packages. `--version' `-V' Print the version of Autoconf used to generate the `configure' script, and exit. `--cache-file=FILE' Enable the cache: use and save the results of the tests in FILE, traditionally `config.cache'. FILE defaults to `/dev/null' to disable caching. `--config-cache' `-C' Alias for `--cache-file=config.cache'. `--quiet' `--silent' `-q' Do not print messages saying which checks are being made. To suppress all normal output, redirect it to `/dev/null' (any error messages will still be shown). `--srcdir=DIR' Look for the package's source code in directory DIR. Usually `configure' can determine that directory automatically. `--prefix=DIR' Use DIR as the installation prefix. *note Installation Names:: for more details, including other options available for fine-tuning the installation locations. `--no-create' `-n' Run the configure checks, but stop before creating any output files. `configure' also accepts some other, not widely useful, options. Run `configure --help' for more details. bristol-0.60.11/config.sub0000755000175000017500000010532712073601233012246 00000000000000#! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # 2011, 2012 Free Software Foundation, Inc. timestamp='2012-04-18' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. # # 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 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, 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. # Please send patches to . Submit a context # diff and a properly formatted GNU ChangeLog entry. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -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.sub ($timestamp) Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 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" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | \ kopensolaris*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; android-linux) os=-linux-android basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray | -microblaze) os= basic_machine=$1 ;; -bluegene*) os=-cnk ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*178) os=-lynxos178 ;; -lynx*5) os=-lynxos5 ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | aarch64 | aarch64_be \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ | be32 | be64 \ | bfin \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ | epiphany \ | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ | mips64r5900 | mips64r5900el \ | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ | nios | nios2 \ | ns16k | ns32k \ | open8 \ | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pyramid \ | rl78 | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu \ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | we32k \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; c54x) basic_machine=tic54x-unknown ;; c55x) basic_machine=tic55x-unknown ;; c6x) basic_machine=tic6x-unknown ;; m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown ;; strongarm | thumb | xscale) basic_machine=arm-unknown ;; xgate) basic_machine=$basic_machine-unknown os=-none ;; xscaleeb) basic_machine=armeb-unknown ;; xscaleel) basic_machine=armel-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | hexagon-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ | mips64r5900-* | mips64r5900el-* \ | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nds32-* | nds32le-* | nds32be-* \ | nios-* | nios2-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pyramid-* \ | rl78-* | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile*-* \ | tron-* \ | ubicom32-* \ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | vax-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-* | z80-*) ;; # Recognize the basic CPU types without company name, with glob match. xtensa*) basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aros) basic_machine=i386-pc os=-aros ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; blackfin) basic_machine=bfin-unknown os=-linux ;; blackfin-*) basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; bluegene*) basic_machine=powerpc-ibm os=-cnk ;; c54x-*) basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c55x-*) basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c6x-*) basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c90) basic_machine=c90-cray os=-unicos ;; cegcc) basic_machine=arm-unknown os=-cegcc ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16 | cr16-*) basic_machine=cr16-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dicos) basic_machine=i686-pc os=-dicos ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; microblaze) basic_machine=microblaze-xilinx ;; mingw32) basic_machine=i386-pc os=-mingw32 ;; mingw32ce) basic_machine=arm-unknown os=-mingw32ce ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; msys) basic_machine=i386-pc os=-msys ;; mvs) basic_machine=i370-ibm os=-mvs ;; nacl) basic_machine=le32-unknown os=-nacl ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; neo-tandem) basic_machine=neo-tandem ;; nse-tandem) basic_machine=nse-tandem ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; parisc) basic_machine=hppa-unknown os=-linux ;; parisc-*) basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc | ppcbe) basic_machine=powerpc-unknown ;; ppc-* | ppcbe-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sde) basic_machine=mipsisa32-sde os=-elf ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh5el) basic_machine=sh5le-unknown ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; strongarm-* | thumb-*) basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tile*) basic_machine=$basic_machine-unknown os=-linux-gnu ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; xscale-* | xscalee[bl]-*) basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; z80-*-coff) basic_machine=z80-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -auroraux) os=-auroraux ;; -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -sym* | -kopensolaris* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -openbsd* | -solidbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -kaos*) os=-kaos ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; -nacl*) ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in score-*) os=-elf ;; spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; hexagon-*) os=-elf ;; tic54x-*) os=-coff ;; tic55x-*) os=-coff ;; tic6x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 ;; m68*-cisco) os=-aout ;; mep-*) os=-elf ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-haiku) os=-haiku ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -cnk*|-aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: bristol-0.60.11/COPYING0000755000175000017500000000012511233572000011303 00000000000000Files in this distribution are licensed under the GPL, as noted in the file headers. bristol-0.60.11/HOWTO0000644000175000017500000004673011650531656011123 00000000000000 Installing Bristol Summary (x.y.z = 0.60.8, for example): a. tar -zxvf bristol-x.y.z.tar.gz b. cd bristol-x.y.z c. ./configure d. make e. sudo make install f. /usr/local/bin/startBristol -mini Table of Contents: 1. About Bristol 2. Installation 3. Command line options 4. ALSA Interface Configuration 5. Jack Interface Configuration 6. Bristol runcom file 7. Integration with MIDI Control Surfaces 8. Keyboard Accelerators 9. Basics of Subtractive Synthesis 10. Basics of FM Synthesis This document is intended to help get bristol running with a minimum of fuss or effort. The first steps above, a through f, are the shortest possible path but there are a lot more options and capabilities discussed below that may change the way bristol operates. 1. About Bristol. 1.1 What is it? Bristol Audio Synthesis is a synth emulation package for a diverse range of vintage synthesisers, electric pianos and organs. The application consists of a synthesiser backend and a GUI frontend called Brighton. 1.2 Who is it by? Bristol is written by Nick Copeland with additional contributions by others. 2. Installation 2.1. System requirements Bristol does not place a high requirement on the underlying system installation, the DSP code is all packaged into the engine and the GUI was written for bristol. There are a number of optional extra packages that bristol can use to give a more complete set of binaries. Also refer to section 1.3 below. libx11-dev Bristol GUI requires this package libasound2-dev ALSA support requires this package jackd Jack support requires this package libjack-dev Jack support requires this package The system will also need libm.so to be installed as well as the build utils however this is a part of a normal distribution. The build utility requirements is a little outside the scope of this document, it is assumed that make/gcc/as are previously installed. 2.2. Unpack the archive. To do this, use the command below, replacing x.y.z with the version number of the downloaded source code. tar -zxvf bristol-x.y.z.tar.gz This will create a subdirectory called bristol-x.y.z 2.3. cd into the directory and do a 'configure' cd bristol-x.y.z ./configure Do bear in mind that if you have another version of Bristol installed, either through your distribution's package manager or locally installed before, the configure script will stop and refuse to continue. You can either use the package manager to remove the version of Bristol installed or just ignore it and add the --disable-version-check option to the end of configure on the command-line. At the end of the configure process there will be a short report on the driver interfaces that have been auto-detected. Here is an extract of the output: | Build with OSS support ......................... : true | Build with ALSA support ........................ : true | Build with JACK support ........................ : false | Bristol needs jackd and libjack-dev to be installed for JACK support. | Build with JACK MIDI support ................... : false | Build with JACK Session support ................ : false | Default audio drivers .......................... : alsa | Default MIDI drivers ........................... : alsa | X11 include file availability .................. : true As is visible here it was not possible to find the relevant header files for the jack audio interface drivers so support will not be included in the eventual compilation. There is an indication provided as to which packages would be required to enable that support. For audio drivers there is a minimum of ALSA required (OSS is also possible) however if the X11 header files could not be found then there will be no graphical support in the binaries - a command line interface only. In this event there will also be a report on which packages are required to provide that support. 2.4. Execute a 'make'. To build Bristol type: make This process will produce all the usual verbose output. It will contain some warnings about unused variables and some potential coding changes however it should proceed to completion. If you get errors such as the following then you will need to contact the author or raise a bug report. gcc -DHAVE_CONFIG_H -I. -I.. -I/usr/X11R6/include -pthread -Wall -g -I./../include/slab -I./../include/bristol -I. -DBRISTOL_VOICECOUNT=32 -DBRISTOL_JACK_MULTI_CLOSE -D_BRISTOL_DRAIN -DBRISTOL_HAS_ALSA=1 -I/usr/include/alsa -ffast-math -fomit-frame-pointer -O2 -g -O2 -I/usr/X11R6/include -MT bristol.o -MD -MP -MF .deps/bristol.Tpo -c -o bristol.o bristol.c bristol.c:62: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘asdf’ make[2]: *** [bristol.o] Error 1 make[2]: Leaving directory `/opt/bristol/bristol-0.60.7/bristol' make[1]: *** [all-recursive] Error 1 make[1]: Leaving directory `/opt/bristol/bristol-0.60.7' make: *** [all] Error 2 How to contact the author or log a bug are given in the last few lines of the output from ./configure above. It is fortunately unusual that such compilation errors will occur on any Linux distribution, the above was forced to fail just for providing an example. 2.5. install the application typically requires root permissions If you get no errors from the 'make' process then the application is ready to be installed. sudo make install This step need to be run as root as, unless you have been very selective with the ./configure options then parts of bristol will be written to parts of the /usr filesystem which is typically read-only for user accounts. By default this should install bristol and associated apps to /usr/local/ with data commponets into /usr/local/share. To run the application you should now be able to use the startBristol script however that does depend on /usr/local/bin being in your path. 2.6. Run the application If the binary is placed in a directory in your path then you can typically start it directly: startBristol -mini If this is not in your path then try the following, this is the default location for the binaries and may differ if you use alternative --prefix for configure. /usr/local/bin/startBristol -mini 3. Some Useful options for starting bristol: -voices Sets the number of voices the synth starts with. The default for most of the synths is to start with as many voices as their hardware counterparts have. In the case of the mini moog, this would be 1 voice. -mono Starts the synth with 1 voice (-hnp -lnp can be used to select high/low note priority respectively) -hnp Selects High Note Priority, any notes played higher than the currently held note will sound and bounce back to the held when released. Notes lower will be ignored by the engine. Vice versa with -lnp. -register Changes the jack and alsa names to the text after it, so it can make more sense when connecting devices etc. -ar Ignores the emulator default aspect ratio. In tiling window managers, bristol can fight with the tiling for so long that active sensing will close the emulator. This option stops that behaviour. Note: Active Sensing is a 'ping' between the GUI frontend and the synth backend, to ensure that the synth engine hasn't crashed. -debug [1-16] Produces debug output to the terminal. 1 is very little debug. 16 is very verbose debug. Many more options, along with the full list of synths can be found by doing 'startBristol --help' or 'man bristol'. 4. ALSA Interface Configuration To see the MIDI connections that can be built you need to look at aconnect commmand: aconnect -io Here is a sammple of its output: client 0: 'System' [type=kernel] 0 'Timer ' 1 'Announce ' client 14: 'Midi Through' [type=kernel] 0 'Midi Through Port-0' client 20: 'USB Oxygen 61' [type=kernel] 0 'USB Oxygen 61 MIDI 1' client 24: 'USB Keystation 88es' [type=kernel] 0 'USB Keystation 88es MIDI 1' client 129: 'bristol' [type=user] 0 'bristol input Here we can see two MIDI controllers and the bristol engine. The following command will link them together so that you can play bristol from your MIDI master controller: aconnect 20 129 aconnect 'USB Oxygen 61' bristol It is possible to connect two master controllers to bristol and this is not unusual for something like the B3. This emulator also has two manuals and can accept multiple controllers on different MIDI channels to allow control of both them. If ALSA is the default interface (ie, you have not given any flags that imply another interface type) then bristol will use ALSA for both audio and MIDI. The default is the 'seq' MIDI interface. It is also possible to use a raw MIDI interface with the option '-midi raw', the type really depends on your soundcard and driver options. 5. Jack Interface Configuration JACK is a low-latency sound server, similar to ASIO on windows. Any apps that are 'jack-aware' are able send audio information to one another seamlessly. Bristol is just one such application that supports JACK. More information can be found at http://jackaudio.org/ Using the jack audio driver is as simple as appending '-jack' to the startBristol command. As of 0.60.7, the following can disable the 'bristoljackstats' app, which can cause startBristol to fail: startBristol -jack -jackstats -count -rate The count and rate have to match the settings given to the jack daemon. In the event of mismatch you will get an error condition from bristol with some level of diagnostic output to indicate the cause. Unless specifically told otherwise, bristol will use jack drivers for both audio and midi. 5.1 Using qjackctl Using qjackctl you can easily connect midi controlloers by clicking on either the 'Midi' tab or 'Alsa' tab, depending on which midi driver you've selected to use with bristol and then clicking the controller you want on the left pane and the 'Bristol' input on the right and clicking 'connect'. 6. The Bristol runcom file Bristol itself has a large range of parameters, each tuning the operation to suit specific needs. Having to give so many parameters to get the synth to work in a specific environment gives it flexibility but also makes it sometimes difficult to use. To quote one person, "It can be an inspiration killer". There are a few third party apps such as monoBristol that provide graphical front ends to the commandline options to make starting bristol easier. Bristol itself supports a runcom file where a user can specify common preferred params that are then included with every invocation. The bristol runcom file can be found, per default, in $HOME/.bristol/bristolrc and its function depends on the bristol version. 6.1 Bristol prior to 0.60.8 The file needs to be created as it does not exist per default. When it exists then the complete contents are prepended before the command line options. As an example, consider the following contents: -jack -jackstats -count 256 -rate 48000 or -jack -jackstats -count 256 -rate 48000 Both of these will have the same affect as they are all summed together. If bristol is started as 'startBristol -mini' then the actual commmandline will be startBristol -jack -jackstats -count 256 -rate 48000 -mini 6.2 Bristol from 0.60.8 There were some limitations of the initial runcom implementation. A number of parameters are implied by each emulator: voices, detune, pitchbend and others. If the runcom includes a -pwd (pitch wheel depth) of 7 it might be lost when the emulator is selected as the emulator will configure its own desired pitch wheel sensitivity as most of the emulators will default this value to '2'. To support such features the runcom was changed to support pre and post parameters. Consider the following contents: PREARGS=-jack -jackstats -count 128 -rate 48000 -as 0 -priority 65 -debug 1 POSTARGS=-multi 2 -lnp -pwd 7 -glide 10 -rud -lnp -log -gain 2 -host unix: If bristol is now started with 'startBristol -mini' the final options taken by the program will be startBristol $PREARGS -mini $POSTARGS This is all expanded out to give a complete command line that, if it was typed in, would read as follows: startBristol -jack -jackstats -count 128 -rate 48000 -as 0 -priority 65 -debug 1 -mini -multi 2 -lnp -pwd 7 -glide -rud -lnp -log -gain 2 -host unix: Here there are some initial parameter settings, then the emulator is selected. The emulator will default the pitch wheel depth to '2'. Then the post arguments are added and they reset the pitchwheel depth to the value '7'. This whole ugly line of parameters is now called with just startBristol -mini The goal of the runcom file is to reduce to a minimum the number of parameters that need to be given on the command line whilst still maintaining a completely customised local configuration. Questions regarding parameter ordering should be sent to LAU mailing list, the author, or raised on the bristol sourceforge forum. 7. Controlling the GUI from a MIDI master controller It is possible to get the GUI to be controlled from faders on a master controller. First connect up the MIDI as described above. Place the mouse cursor over the GUI control you want to track and push the Middle Mouse Button. Now move the MIDI control, the GUI should now track that control. Devices can be unregistered using the same method. The settings will be saved when you save a memory. The settings themselves are in the directory listed below, and they can be edited with a text editor. /home/username/.bristol/memory/profiles/ Most of the synths come with a standard GM midi mapping for controlling filter cutoff/resonance, etc. 8. Keyboard accelerators 8.1 Keyboard Mappings. Bristol supports GUI shortcuts and playing the synths via a QWERTY keyboard. Playing bristol via the QWERTY on the B3 has C2 starting on '\' and going up to F3 on '/' on the bottom manual, while the top manual goes from C4 on Q to G5 on ']'. On a single keyboard synth, such as the polysix, C1 starts on '\' and goes up F2 on '/' and C3 starts on Q and ends at G4 on ']'. For alternative mappings such as AZERTY it is necessary to manually edit the emulator profile files. 8.2 Keyboard Accelerators Useful shortcuts are: Ctrl + Load next memory Ctrl - Load previous memory Ctrl l Load/reload current memory Ctrl s Save settings to current memory. Arrow keys can control pot/slider movement with Shift being an accelerator. The GUI devices also support VI style j/k up/down with Shift and Control options. 9. Basics of Subtractive Synthesis. Subtractive synths generally have 5 parts to them: 1. Oscillators 2. Filters 3. Low Frequency Oscillators (LFOs) 4. ADSR Envelopes 5. Amplification output Subtractive synthesis works by taking the waveforms generated by oscillators, filtering them (or not) to remove specific frequencies, using a LFO to modulate the sound, applying an ADSR Envelope to them and then sending the sound out the synth. 9.1. Oscillators Oscillators use basic waveforms (saw, square, triangle, sine) to produce sound. On some synths, these can be combined to produce harmonically rich sounds (saw and square for example). The more oscillators a synth has, the greater number of waveforms that can be layered together to create a quite 'phat' sound. 9.2. Filters Filters are used to remove specific frequencies from the oscillators. Filters generally come in 3 types in the bristol synths: Low Pass Filter High Pass Band Reject Low Pass filters remove high frequencies (i.e they pass low freqencies). High Pass filters remove low freqencies Band Reject filters remove both low and high filters in a specific range and allow a certain 'mid-range' of frequencies through. On all filters, there are 2 main controls: Frequency Cutoff. Frequency Resonance. Frequency Cutoff allows you to control how much of the sound gets filtered. Resonance amplifies the narrow band of frequencies that are close to the cutoff point. 9.3.Low Frequency Oscillators (LFOs) LFOs are exactly like normal oscillators (they have waveforms, like sine, square and triangle), but they sound below what a human can hear. In this way, they can modulate various parameters on the synths, without being heard. The parameters that an LFO modulates is called the destination. LFOs usually have 2 controls: Rate Delay Rate determines how quickly the LFO oscillates at, low levels modulates the destination slowly, while high levels will modulate quickly. Delay determines how quickly the LFO should start modulating the destination. Common modulation destinations are: Audible Oscillator's frequency (Vibrato effect) Filter Cutoff frequency (wah-wah effect) Amplification output (tremolo effect) On most of the bristol synths, the LFO 'depth' (how much the LFO affects the destination) is controlled by the mod-wheel. 9.4. ADSR Envelopes. ADSR envelopes shape the sound of the oscillators and filter (where available). ADSR stands for the 4 parameters that can shape the sound: Attack - How quickly the sound reaches full volume. Decay - How quickly the sound falls down to the sustain level Sustain - Volume of the sound while the key is held Release - How quickly the sound fades to silence 9.5. Amplification output There is usually a control here that controls the overall volume of the synth. 10. Basics of FM Synthesis. FM Synthesis stands for Frequency Modulation synthesis. This means that one oscillator (called a Modulator) modulates the frequency of another oscillator (called a Carrier). In Bristol there are 3 FM emulators, 2 Rhodes Electric Pianos and a Yamaha DX 6 Operator synth. FM synthesis works by feeding one signal from one oscillator (a modulator) into another signal from another oscillator (a carrier). The interesting part is when a modulator is audible, detuning the modulator will produce bell-like tones in the output as the carrier's frequency is modulated by an audible signal. It should be noted that all of the oscillators are sine waves so stacking them together can produce some nice hammond-esque sounds. The DX emulation has got 24 different "algorithms" for all 6 of it's operators. These control which oscillators are modulators and which are carriers (modulators can be fed into other modulators as well). All operators have their own ADSR envelope, so sound shaping is possible in a variety of ways. The ADSR is a 7-stage envelope. This means that it has 7 parts to it: L1 - First audible stage Attack1 - Rate at which the operator goes from silence to L1 L2 - Second audible stage Attack2 - Rate at which the operator goes from L1 to L2 Decay - Rate at which L2 falls to the Sustain stage Sustain - How loud the sound will be through steady state Release - Rate at which the sound falls to silence Input gain - How much the modulator affects the carrier for this specific operator. Output gain - How loud the operator is (when it's a carrier) and how much modulation is sent out (when it's a modulator). Each operator has three buttons: LFO, IGC and OGC. LFO drops the oscillator by a few octaves and removes pitch tracking. IGC controls whether the input gain for that operator is affected by velocity. OGC controls whether the output gain for that operator is affected by velocity. Initial draft by Andrew Coughlan. Editing, additional information and suggestions by Nick Copeland. bristol-0.60.11/Makefile.in0000644000175000017500000006532212073601233012330 00000000000000# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = . DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(srcdir)/config.h.in \ $(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \ config.guess config.sub depcomp install-sh ltmain.sh missing ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ distdir dist dist-all distcheck ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ if test -d "$(distdir)"; then \ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -rf "$(distdir)" \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ ALSA_CFLAGS = @ALSA_CFLAGS@ ALSA_LIBS = @ALSA_LIBS@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BRIGHTON_HAS_AUTOZOOM = @BRIGHTON_HAS_AUTOZOOM@ BRIGHTON_HAS_SHMIMAGE = @BRIGHTON_HAS_SHMIMAGE@ BRIGHTON_HAS_X11 = @BRIGHTON_HAS_X11@ BRIGHTON_HAS_XIMAGE = @BRIGHTON_HAS_XIMAGE@ BRIGHTON_LIBB11 = @BRIGHTON_LIBB11@ BRIGHTON_LIBX11 = @BRIGHTON_LIBX11@ BRIGHTON_LIBXEXT = @BRIGHTON_LIBXEXT@ BRIGHTON_LIBXLIBS = @BRIGHTON_LIBXLIBS@ BRIGHTON_X11_DIR = @BRIGHTON_X11_DIR@ BRISTOL_BARRIER = @BRISTOL_BARRIER@ BRISTOL_DIR = @BRISTOL_DIR@ BRISTOL_HAS_ALSA = @BRISTOL_HAS_ALSA@ BRISTOL_HAS_DRAIN = @BRISTOL_HAS_DRAIN@ BRISTOL_HAS_JACK = @BRISTOL_HAS_JACK@ BRISTOL_HAS_JACK_MIDI = @BRISTOL_HAS_JACK_MIDI@ BRISTOL_HAS_JACK_SESSION = @BRISTOL_HAS_JACK_SESSION@ BRISTOL_HAS_LIBLO = @BRISTOL_HAS_LIBLO@ BRISTOL_HAS_OSS = @BRISTOL_HAS_OSS@ BRISTOL_HAS_PA = @BRISTOL_HAS_PA@ BRISTOL_JACK_DEFAULT = @BRISTOL_JACK_DEFAULT@ BRISTOL_JACK_DEFAULT_MIDI = @BRISTOL_JACK_DEFAULT_MIDI@ BRISTOL_JACK_MULTI_CLOSE = @BRISTOL_JACK_MULTI_CLOSE@ BRISTOL_LIBPALIBS = @BRISTOL_LIBPALIBS@ BRISTOL_LIB_PA = @BRISTOL_LIB_PA@ BRISTOL_LIN_ATTACK = @BRISTOL_LIN_ATTACK@ BRISTOL_MAJOR_VERSION = @BRISTOL_MAJOR_VERSION@ BRISTOL_MICRO_VERSION = @BRISTOL_MICRO_VERSION@ BRISTOL_MINOR_VERSION = @BRISTOL_MINOR_VERSION@ BRISTOL_PA_DIR = @BRISTOL_PA_DIR@ BRISTOL_SEMAPHORE = @BRISTOL_SEMAPHORE@ BRISTOL_SEM_OPEN = @BRISTOL_SEM_OPEN@ BRISTOL_SO_VERSION = @BRISTOL_SO_VERSION@ BRISTOL_VERSION = @BRISTOL_VERSION@ BRR = @BRR@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFAULT_AUDIO_FLAG = @DEFAULT_AUDIO_FLAG@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JACK_CFLAGS = @JACK_CFLAGS@ JACK_LIBS = @JACK_LIBS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBLO_CFLAGS = @LIBLO_CFLAGS@ LIBLO_LIBS = @LIBLO_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ _BRISTOL_VOICES = @_BRISTOL_VOICES@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = libbristolaudio libbristolmidi libbvg @BRIGHTON_X11_DIR@ libbrightonC11 libbristolic libbrighton libbristol brighton bristol bin #SUBDIRS= libbristolaudio libbristolmidi libbrightonX11 libbrightonC11 libbristolic libbrighton libbristol brighton bristol bin ACLOCAL_AMFLAGS = -I m4 bristoldir = ${BRISTOL_DIR} EXTRA_DIST = include bitmaps memory HOWTO COPYING COPYING.GPL bristol.1 bristoljackstats.1 all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: am--refresh: Makefile @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): config.h: stamp-h1 @if test ! -f $@; then rm -f stamp-h1; else :; fi @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status config.h $(srcdir)/config.h.in: $(am__configure_deps) ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f config.h stamp-h1 mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs distclean-libtool: -rm -f libtool config.lt # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 $(am__remove_distdir) dist-lzip: distdir tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz $(am__remove_distdir) dist-lzma: distdir tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma $(am__remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__remove_distdir) dist-tarZ: distdir tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__remove_distdir) dist-shar: distdir shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__remove_distdir) dist dist-all: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lzma*) \ lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ *.tar.lz*) \ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir); chmod u+w $(distdir) mkdir $(distdir)/_build mkdir $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build \ && ../configure --srcdir=.. --prefix="$$dc_install_base" \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 $(am__remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @test -n '$(distuninstallcheck_dir)' || { \ echo 'ERROR: trying to run $@ with an empty' \ '$$(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ $(am__cd) '$(distuninstallcheck_dir)' || { \ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-recursive all-am: Makefile config.h installdirs: installdirs-recursive installdirs-am: install-exec: install-exec-recursive install-data: install-data-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile distclean-am: clean-am distclean-generic distclean-hdr \ distclean-libtool distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all \ ctags-recursive install-am install-strip tags-recursive .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am am--refresh check check-am clean clean-generic \ clean-libtool ctags ctags-recursive dist dist-all dist-bzip2 \ dist-gzip dist-lzip dist-lzma dist-shar dist-tarZ dist-xz \ dist-zip distcheck distclean distclean-generic distclean-hdr \ distclean-libtool distclean-tags distcleancheck distdir \ distuninstallcheck dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-recursive uninstall uninstall-am install-man: $(INSTALL) -d $(DESTDIR)$(mandir)/man1 $(INSTALL) -m 0644 $(srcdir)/bristol.1 $(DESTDIR)$(mandir)/man1/ $(INSTALL) -m 0644 $(srcdir)/bristoljackstats.1 $(DESTDIR)$(mandir)/man1/ gzip -9fn $(DESTDIR)$(mandir)/man1/bristol.1 gzip -9fn $(DESTDIR)$(mandir)/man1/bristoljackstats.1 cd $(DESTDIR)$(mandir)/man1 && ln -sf bristol.1.gz brighton.1.gz && ln -sf bristol.1.gz startBristol.1.gz installdb: mkdir -p -m 0755 $(DESTDIR)$(bristoldir) tar cfp - $(srcdir)/bitmaps $(srcdir)/memory | (cd $(DESTDIR)$(bristoldir) ; tar xfp -) find $(DESTDIR)$(bristoldir)/. -type d -exec chmod 0755 {} \; -o -type f -exec chmod 0644 {} \; uninstalldb: rm -rf $(DESTDIR)$(bristoldir)/bitmaps $(DESTDIR)$(bristoldir)/memory rm -f $(DESTDIR)${bindir}/startBristol installbristolbin: mkdir -p -m 0755 $(DESTDIR)$(bindir) $(install_sh) -c -m 0755 bin/startBristol $(DESTDIR)$(bindir) install: install-recursive installdb installbristolbin install-man uninstall: uninstall-recursive uninstalldb rm -rf $(DESTDIR)$(bristoldir)/memory rm -rf $(DESTDIR)$(bristoldir)/bitmaps rm -rf $(DESTDIR)$(bristoldir) rm -rf $(DESTDIR)$(mandir)/man1/bristol.1 $(DESTDIR)$(mandir)/man1/brighton.1 $(DESTDIR)$(mandir)/man1/startBristol.1 $(DESTDIR)$(mandir)/man1/bristoljackstats.1 rm -rf $(DESTDIR)$(mandir)/man1/bristol.1.gz $(DESTDIR)$(mandir)/man1/brighton.1.gz $(DESTDIR)$(mandir)/man1/startBristol.1.gz $(DESTDIR)$(mandir)/man1/bristoljackstats.1.gz # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: bristol-0.60.11/Makefile.am0000755000175000017500000000350211703613413012314 00000000000000SUBDIRS= libbristolaudio libbristolmidi libbvg @BRIGHTON_X11_DIR@ libbrightonC11 libbristolic libbrighton libbristol brighton bristol bin #SUBDIRS= libbristolaudio libbristolmidi libbrightonX11 libbrightonC11 libbristolic libbrighton libbristol brighton bristol bin ACLOCAL_AMFLAGS=-I m4 bristoldir=${BRISTOL_DIR} install-man: $(INSTALL) -d $(DESTDIR)$(mandir)/man1 $(INSTALL) -m 0644 $(srcdir)/bristol.1 $(DESTDIR)$(mandir)/man1/ $(INSTALL) -m 0644 $(srcdir)/bristoljackstats.1 $(DESTDIR)$(mandir)/man1/ gzip -9fn $(DESTDIR)$(mandir)/man1/bristol.1 gzip -9fn $(DESTDIR)$(mandir)/man1/bristoljackstats.1 cd $(DESTDIR)$(mandir)/man1 && ln -sf bristol.1.gz brighton.1.gz && ln -sf bristol.1.gz startBristol.1.gz installdb: mkdir -p -m 0755 $(DESTDIR)$(bristoldir) tar cfp - $(srcdir)/bitmaps $(srcdir)/memory | (cd $(DESTDIR)$(bristoldir) ; tar xfp -) find $(DESTDIR)$(bristoldir)/. -type d -exec chmod 0755 {} \; -o -type f -exec chmod 0644 {} \; uninstalldb: rm -rf $(DESTDIR)$(bristoldir)/bitmaps $(DESTDIR)$(bristoldir)/memory rm -f $(DESTDIR)${bindir}/startBristol installbristolbin: mkdir -p -m 0755 $(DESTDIR)$(bindir) $(install_sh) -c -m 0755 bin/startBristol $(DESTDIR)$(bindir) install: install-recursive installdb installbristolbin install-man uninstall: uninstall-recursive uninstalldb rm -rf $(DESTDIR)$(bristoldir)/memory rm -rf $(DESTDIR)$(bristoldir)/bitmaps rm -rf $(DESTDIR)$(bristoldir) rm -rf $(DESTDIR)$(mandir)/man1/bristol.1 $(DESTDIR)$(mandir)/man1/brighton.1 $(DESTDIR)$(mandir)/man1/startBristol.1 $(DESTDIR)$(mandir)/man1/bristoljackstats.1 rm -rf $(DESTDIR)$(mandir)/man1/bristol.1.gz $(DESTDIR)$(mandir)/man1/brighton.1.gz $(DESTDIR)$(mandir)/man1/startBristol.1.gz $(DESTDIR)$(mandir)/man1/bristoljackstats.1.gz EXTRA_DIST=include bitmaps memory HOWTO COPYING COPYING.GPL bristol.1 bristoljackstats.1 bristol-0.60.11/missing0000755000175000017500000002415212073601233011656 00000000000000#! /bin/sh # Common stub for a few missing GNU programs while installing. scriptversion=2012-01-06.13; # UTC # Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006, # 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. # Originally by Fran,cois Pinard , 1996. # 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, 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. if test $# -eq 0; then echo 1>&2 "Try \`$0 --help' for more information" exit 1 fi run=: sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' sed_minuso='s/.* -o \([^ ]*\).*/\1/p' # In the cases where this matters, `missing' is being run in the # srcdir already. if test -f configure.ac; then configure_ac=configure.ac else configure_ac=configure.in fi msg="missing on your system" case $1 in --run) # Try to run requested program, and just exit if it succeeds. run= shift "$@" && exit 0 # Exit code 63 means version mismatch. This often happens # when the user try to use an ancient version of a tool on # a file that requires a minimum version. In this case we # we should proceed has if the program had been absent, or # if --run hadn't been passed. if test $? = 63; then run=: msg="probably too old" fi ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an error status if there is no known handling for PROGRAM. Options: -h, --help display this help and exit -v, --version output version information and exit --run try to run the given command, and emulate it if it fails Supported PROGRAM values: aclocal touch file \`aclocal.m4' autoconf touch file \`configure' autoheader touch file \`config.h.in' autom4te touch the output file, or create a stub one automake touch all \`Makefile.in' files bison create \`y.tab.[ch]', if possible, from existing .[ch] flex create \`lex.yy.c', if possible, from existing .c help2man touch the output file lex create \`lex.yy.c', if possible, from existing .c makeinfo touch the output file yacc create \`y.tab.[ch]', if possible, from existing .[ch] Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and \`g' are ignored when checking the name. Send bug reports to ." exit $? ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" exit $? ;; -*) echo 1>&2 "$0: Unknown \`$1' option" echo 1>&2 "Try \`$0 --help' for more information" exit 1 ;; esac # normalize program name to check for. program=`echo "$1" | sed ' s/^gnu-//; t s/^gnu//; t s/^g//; t'` # Now exit if we have it, but it failed. Also exit now if we # don't have it and --version was passed (most likely to detect # the program). This is about non-GNU programs, so use $1 not # $program. case $1 in lex*|yacc*) # Not GNU programs, they don't have --version. ;; *) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 elif test "x$2" = "x--version" || test "x$2" = "x--help"; then # Could not run --version or --help. This is probably someone # running `$TOOL --version' or `$TOOL --help' to check whether # $TOOL exists and not knowing $TOOL uses missing. exit 1 fi ;; esac # If it does not exist, or fails to run (possibly an outdated version), # try to emulate it. case $program in aclocal*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." touch aclocal.m4 ;; autoconf*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." touch configure ;; autoheader*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`acconfig.h' or \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` test -z "$files" && files="config.h" touch_files= for f in $files; do case $f in *:*) touch_files="$touch_files "`echo "$f" | sed -e 's/^[^:]*://' -e 's/:.*//'`;; *) touch_files="$touch_files $f.in";; esac done touch $touch_files ;; automake*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." find . -type f -name Makefile.am -print | sed 's/\.am$/.in/' | while read f; do touch "$f"; done ;; autom4te*) echo 1>&2 "\ WARNING: \`$1' is needed, but is $msg. You might have modified some files without having the proper tools for further handling them. You can get \`$1' as part of \`Autoconf' from any GNU archive site." file=`echo "$*" | sed -n "$sed_output"` test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo "#! /bin/sh" echo "# Created by GNU Automake missing as a replacement of" echo "# $ $@" echo "exit 0" chmod +x $file exit 1 fi ;; bison*|yacc*) echo 1>&2 "\ WARNING: \`$1' $msg. You should only need it if you modified a \`.y' file. You may need the \`Bison' package in order for those modifications to take effect. You can get \`Bison' from any GNU archive site." rm -f y.tab.c y.tab.h if test $# -ne 1; then eval LASTARG=\${$#} case $LASTARG in *.y) SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` if test -f "$SRCFILE"; then cp "$SRCFILE" y.tab.c fi SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` if test -f "$SRCFILE"; then cp "$SRCFILE" y.tab.h fi ;; esac fi if test ! -f y.tab.h; then echo >y.tab.h fi if test ! -f y.tab.c; then echo 'main() { return 0; }' >y.tab.c fi ;; lex*|flex*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a \`.l' file. You may need the \`Flex' package in order for those modifications to take effect. You can get \`Flex' from any GNU archive site." rm -f lex.yy.c if test $# -ne 1; then eval LASTARG=\${$#} case $LASTARG in *.l) SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` if test -f "$SRCFILE"; then cp "$SRCFILE" lex.yy.c fi ;; esac fi if test ! -f lex.yy.c; then echo 'main() { return 0; }' >lex.yy.c fi ;; help2man*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a dependency of a manual page. You may need the \`Help2man' package in order for those modifications to take effect. You can get \`Help2man' from any GNU archive site." file=`echo "$*" | sed -n "$sed_output"` test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo ".ab help2man is required to generate this page" exit $? fi ;; makeinfo*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a \`.texi' or \`.texinfo' file, or any other file indirectly affecting the aspect of the manual. The spurious call might also be the consequence of using a buggy \`make' (AIX, DU, IRIX). You might want to install the \`Texinfo' package or the \`GNU make' package. Grab either from any GNU archive site." # The file to touch is that specified with -o ... file=`echo "$*" | sed -n "$sed_output"` test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -z "$file"; then # ... or it is the one specified with @setfilename ... infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` file=`sed -n ' /^@setfilename/{ s/.* \([^ ]*\) *$/\1/ p q }' $infile` # ... or it is derived from the source name (dir/f.texi becomes f.info) test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info fi # If the file does not exist, the user really needs makeinfo; # let's fail without touching anything. test -f $file || exit 1 touch $file ;; *) echo 1>&2 "\ WARNING: \`$1' is needed, and is $msg. You might have modified some files without having the proper tools for further handling them. Check the \`README' file, it often tells you about the needed prerequisites for installing this package. You may also peek at any GNU archive site, in case some other package would contain this missing \`$1' program." exit 1 ;; esac exit 0 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: bristol-0.60.11/NEWS0000755000175000017500000001264112100257340010756 00000000000000 0.60.11 24 Jan 2013 Maintenance release 0.60.10 27 Apr 2012 Maintenance release 0.60.9 25 Oct 2011 Maintenance release, fanning linear potentiometers 0.60.8 23 Dec 2010 Maintenance release, Hammond optimisations. 0.60.7 22 Oct 2010 Maintenance release, minor features 0.60.6 11 Aug 2010 Geometry configuration options, maintenance release 0.60.5 08 Jun 2010 Maintenance release 0.60.4 23 May 2010 Maintenance release 0.60.3 12 May 2010 Maintenance release 0.60.2 28 Apr 2010 Command Line Interface Changes, maintenance release 0.60.1 23 Apr 2010 Command Line Interface Changes 0.60.0 19 Apr 2010 Command Line Interface 0.50.8 05 May 2010 Maintenance updates 0.50.7 22 Apr 2010 CV Keyboard Tracking Frequency Control for ARP 0.50.6 08 Apr 2010 Multiple IO Channels for audio/CV, more NRP Controller Support, Jack Session Manager maintenance 0.50.5 03 Apr 2010 Jack Session Manager Immediate fixes 0.50.4 02 Apr 2010 Jack Session Manager Support 0.50.3 17 Mar 2010 Band limited oscillator corrections, filter optimisation, GUI enhancements. 0.50.2 06 Feb 2010 Real time processing enhancements 0.50.1 22 Jan 2010 Usability enhancments, LADI level 1 compliance, process distribution 0.40.8 22 Jan 2010 Maintenance release 0.40.7 22 Nov 2009 Maintenance release 0.40.6 28 Sep 2009 Maintenance release 0.40.5 23 Jul 2009 Distributed processing maintenance release 0.40.4 06 Jun 2009 Audio Driver Mainenance Release 0.40.3 25 May 2009 Maintenance release, B3 stuck notes. 0.40.2 05 May 2009 Maintenance release, usability improvements. 0.40.1 25 Apr 2009 Commodore C64 SID emulator 0.30.9 02 Apr 2009 Bristol BassMaker, massive filter optimisations. 0.30.8 20 Mar 2009 Maintenance release, ARP 2600 fixes. 0.30.7 02 Mar 2009 Baumann BME-700 0.30.6 22 Feb 2009 Monophonic note precedence key logic. 0.30.5 01 Feb 2009 Maintenance release? 0.30.4 20 Jan 2009 Korg Poly-800 0.30.3 19 Dec 2008 Crumar Trident, PWM and Sync fixes, Polysix improvements 0.30.2 15 Dec 2008 Crumar Stratus 0.30.1 03 Dec 2008 Voyager Electric Blue, Moog Sonic 6. 0.20.10 27 Nov 2008 Maintenance release. 0.20.9 14 Nov 2008 Maintenance release. 0.20.8 28 Sep 2008 New filters, normalised gains, diverse fixes 0.20.7 29 Aug 2008 Sequential Circuits Pro-One, Scala tonal mapping tables, overhaul of the Prophet-10 0.20.6 13 Jun 2008 Bandwidth limited oscllators. UI Heartbeats, GUI scaling. 0.20.5 20 Apr 2008 First release of the Jupiter-8 emulation, GUI prealiasing, Vasiliy Basic's Mini memory suite. 0.20.4 26 Mar 2008 Arpeggiating OBXa, fixes, synchronised threads. 0.20.3 05 Mar 2008 Integrated a new Crumar Bit-100 emulation 0.20.2 25 Feb 2008 Integrated a few Crumar Bit emulations. 0.20.1 20 Jan 2008 First release of the 0.20 stream 0.10.13 19 Jan 2008 Maintenance release. 0.10.12 03 Dec 2007 Maintenance release. 0.10.11 27 Oct 2007 Arpeggiator written into the MIDI library. Added arpeggiation (actually an arpeggiating sequencer) into MIDI library. 0.10.10 XX Oct 2007 Bass pedalboard integration for Hammond. Added a third manual to the hammond. Built in the GM-2 MIDI controller mappings to a range of the emulations. 0.10.9 16 Sept 2007 Reworked installation procedures, Vox-300 Vox dual manual 300. 0.10.8 01 Sept 2007 Realistic Concertmate, recolorations, fixes Developed a Realistic/Moog Concertmate MG1. Diverse fixes and recolorations. 0.10.7 29 July 2007 added roadrunner electric piano Two rounds of GUI optimisation have improved the CPU load by a couple of orders of magnitude. Added a grey scale option. Added antialiasing features (that had been previously dropped as too CPU intensive, now quite reasonable). 0.10.5 06 June 2007 added roadrunner electric piano The Roadrunner is an emulated organ circuit electric piano, many of these were released in the 70's and complemented the string machines. They used clock divided organ circuitry and simple envelope generators per key to groom to something approaching a piano envelope. Diverse minor bugfixes. 0.10.4 24 May 2007 added Solina string machine Potentials: Some of the diverse synth memories are damaged. ARP 2600 has damaged vertical patch cables. Move the key mappings and controller mappings to .mcm file as they are static. Removed clipping in new keyclick generation. 0.10.3 18 May 2007 added the following Modifications to configure.ac and Makefile.am to correct autotools errors. Corrected use of --exec_prefix for configure process. Note velocity, Poly and Channel Pressure curve mappings from file. Global. Note integer index mapping in same configuration file. Global. Note Microtonal tunings. Global settings - affects the whole engine. Note velocity map - per emulation. Note microtonal map - per emulation. B3 key noise generated per bus with configurable delays and gain per contact. Reverse controller motion of hammond drawbars (mappings?). Controller mapped value curves for lin/log/exp/parabolic with inverse table. Resolved issues with use of '-jack' flag as opposed to '-audio jack'. More keyboard velocity curves of which one mapping per emulation. Pitch bend damaged by microtonal mapping implementation, fixed. 0.10.2: 10 May 2007 Changes to automake configuration files for installation prefixes. 0.10.1: 4 May 2007 Probable first distribution of the bristol version using GNU autotools. bristol-0.60.11/brighton/0000755000175000017500000000000012100257365012153 500000000000000bristol-0.60.11/brighton/brightonMixer.h0000644000175000017500000000347711746476475015124 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #define MIXER_VERSION 0 #define MAX_CHAN_COUNT 60 #define MAX_BUS_COUNT 16 #define MAX_VBUS_COUNT 16 #define CHAN_COUNT 16 /* This should be a parameter to the mixer. */ #define DEF_BUS_COUNT 8 /* This should be a parameter to the mixer. */ #define DEF_VBUS_COUNT 8 /* This should be a parameter to the mixer. */ #define FXP_COUNT 30 #define BUS_COUNT (FXP_COUNT * DEF_BUS_COUNT + 12) #define MASTER_COUNT 17 #define FUNCTION_COUNT 33 #define FIRST_DEV 0 #define PARAM_COUNT 80 #define MEM_COUNT 512 /* This is memory bytes per channel, for expansion */ #define ACTIVE_DEVS \ (MEM_COUNT * MAX_CHAN_COUNT + BUS_COUNT + FUNCTION_COUNT + FIRST_DEV) #define DISPLAY_DEV 0 #define DISPLAY_PANEL 7 #define FUNCTION_PANEL 2 #define VBUS_PANEL FUNCTION_PANEL #define BUS_PANEL (FUNCTION_PANEL + 1) #define CHAN_PANEL (BUS_PANEL + 1) #define DEVICE_COUNT (ACTIVE_DEVS) #define MM_INIT 0 #define MM_SAVE 1 #define MM_LOAD 2 #define MM_GET 3 #define MM_SET 4 #define MM_GETLIST 0 #define MM_S_GLOBAL 0 #define MM_S_BUS 1 #define MM_S_VBUS 2 #define MM_S_CHAN 2 bristol-0.60.11/brighton/brightonHammondB3.c0000644000175000017500000016024311746476475015576 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include #include "brighton.h" #include "brightonMini.h" #include "brightoninternals.h" static int hammondB3Init(); static int hammondB3Configure(); static int hammondB3MidiCallback(brightonWindow *, int, int, float); static int hammondB3Callback(brightonWindow *, int, int, float); static int hammondB3destroy(); /*static int keyCallback(void *, int, int, float); */ /*static int modCallback(void *, int, int, float); */ static void doClick(); static int dc = 0, shade_id; extern guimain global; static guimain manual; #include "brightonKeys.h" #define FIRST_DEV 0 #define C_COUNT (35 + FIRST_DEV) #define MEM_COUNT 16 #define VOL_COUNT 1 #define LESLIE_COUNT 2 #define OPTS_COUNT 40 #define ACTIVE_DEVS (C_COUNT + OPTS_COUNT + VOL_COUNT + LESLIE_COUNT - 1) #define DEVICE_COUNT (C_COUNT + OPTS_COUNT + VOL_COUNT + LESLIE_COUNT + MEM_COUNT) #define OPTS_PANEL 1 #define DRAWBAR_START 9 #define DEVICE_START FIRST_DEV #define OPTS_START (DEVICE_START + C_COUNT) #define VOL_START (OPTS_START + OPTS_COUNT) #define LESLIE_START (VOL_START + VOL_COUNT) #define MEM_START (LESLIE_START + LESLIE_COUNT) #define DISPLAY_PAN 4 #define DISPLAY_DEV (MEM_COUNT - 1) #define KEY_PANEL1 6 #define KEY_PANEL2 7 #define RADIOSET_1 MEM_START /* * This structure is for device definition. The structure is defined in * include/brighton.h, further definitions in brighton/brightonDevtable.h and * include/brightoninternals.h * * typedef int (*brightonCallback)(int, float); * typedef struct BrightonLocations { * int device; 0=rotary, 1=scale, etc. * float relx, rely; relative position with regards to 1000 by 1000 window * float relw, relh; relative height. * int from, to; * brightonCallback callback; specific to this dev * char *image; bitmap. If zero take a device default. * int flags; * } brightonLocations; * * This example is for a hammondB3Bristol type synth interface. */ #define SD1 28 #define SD2 50 #define W1 20 #define L1 770 #define R1 0 #define Cm1 225 #define Cm2 (Cm1 + SD1) #define C1 290 #define C2 (C1 + SD1) #define C3 (C2 + SD1) #define C4 (C3 + SD1) #define C5 (C4 + SD1) #define C6 (C5 + SD1) #define C7 (C6 + SD1) #define C8 (C7 + SD1) #define C9 (C8 + SD1) #define C11 556 #define C12 (C11 + SD1) #define C13 (C12 + SD1) #define C14 (C13 + SD1) #define C15 (C14 + SD1) #define C16 (C15 + SD1) #define C17 (C16 + SD1) #define C18 (C17 + SD1) #define C19 (C18 + SD1) #define MC1 9 #define MC2 55 #define MC3 183 #define MC4 810 #define MC5 (MC4 + SD2) #define MC6 (MC5 + SD2) #define MC7 (MC6 + SD2) #define MR1 360 #define MR2 650 #define MR3 700 #define MW1 36 #define MW2 50 #define MH1 525 #define MH2 200 #include /* * Drawbars were 0 to 7 due to encoding them in a single 7bit value - 3 bits * were for gain and 4 bits required for the drawbar. This was always in need * of a change and will implement it finally. It's actually quite trivial, it * uses sequential encoding rather than reserving bits, the latter is too * lossy. */ static brightonLocations locations[C_COUNT] = { {"Lower Drawbar 16", BRIGHTON_HAMMOND, C1, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondbrown.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, {"Lower Drawbar 5 1/3", BRIGHTON_HAMMOND, C2, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondbrown.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, {"Lower Drawbar 8", BRIGHTON_HAMMOND, C3, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondwhite.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, {"Lower Drawbar 4", BRIGHTON_HAMMOND, C4, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondwhite.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, {"Lower Drawbar 2 2/3", BRIGHTON_HAMMOND, C5, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondblack.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, {"Lower Drawbar 2", BRIGHTON_HAMMOND, C6, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondwhite.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, {"Lower Drawbar 1 3/5", BRIGHTON_HAMMOND, C7, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondblack.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, {"Lower Drawbar 1 1/3", BRIGHTON_HAMMOND, C8, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondblack.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, {"Lower Drawbar 1", BRIGHTON_HAMMOND, C9, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondwhite.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, {"Upper Drawbar 16", BRIGHTON_HAMMOND, C11, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondbrown.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, {"Upper Drawbar 5 1/3", BRIGHTON_HAMMOND, C12, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondbrown.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, {"Upper Drawbar 8", BRIGHTON_HAMMOND, C13, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondwhite.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, {"Upper Drawbar 4", BRIGHTON_HAMMOND, C14, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondwhite.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, {"Upper Drawbar 2 2/3", BRIGHTON_HAMMOND, C15, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondblack.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, {"Upper Drawbar 2", BRIGHTON_HAMMOND, C16, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondwhite.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, {"Upper Drawbar 1 3/5", BRIGHTON_HAMMOND, C17, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondblack.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, {"Upper Drawbar 1 1/3", BRIGHTON_HAMMOND, C18, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondblack.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, {"Upper Drawbar 1", BRIGHTON_HAMMOND, C19, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondwhite.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, /* 18 - switches, etc */ {"Leslie", 2, MC1, MR1, MW1, MH1, 0, 1, 0, "bitmaps/buttons/rockersmooth.xpm", "bitmaps/buttons/rockersmoothd.xpm", 0}, {"Reverb", 2, MC2, MR1, MW1, MH1, 0, 1, 0, "bitmaps/buttons/rockersmooth.xpm", "bitmaps/buttons/rockersmoothd.xpm", 0}, {"VibraChorus", 0, MC2 + 57, MR1 + 70, MW1 + 10, MH1, 0, 6, 0, 0, 0, 0}, {"Bright", 2, MC3, MR1, MW1, MH1, 0, 1, 0, "bitmaps/buttons/rockersmooth.xpm", "bitmaps/buttons/rockersmoothd.xpm", 0}, /* 22 - perc switches, etc */ {"Perc 4", 2, MC4, MR1, MW1, MH1, 0, 1, 0, "bitmaps/buttons/rockersmooth.xpm", "bitmaps/buttons/rockersmoothd.xpm", 0}, {"Perc 2 2/3", 2, MC5, MR1, MW1, MH1, 0, 1, 0, "bitmaps/buttons/rockersmooth.xpm", "bitmaps/buttons/rockersmoothd.xpm", 0}, {"Perc Slow", 2, MC6, MR1, MW1, MH1, 0, 1, 0, "bitmaps/buttons/rockersmooth.xpm", "bitmaps/buttons/rockersmoothd.xpm", 0}, {"Perc Soft", 2, MC7, MR1, MW1, MH1, 0, 1, 0, "bitmaps/buttons/rockersmooth.xpm", "bitmaps/buttons/rockersmoothd.xpm", 0}, /* 26 - Bass drawbars */ {"Bass Drawbar 16", BRIGHTON_HAMMOND, Cm1, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondbrown.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, {"Bass Drawbar 8", BRIGHTON_HAMMOND, Cm2, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondbrown.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, /* * 28 - Dummies. May one day extend the bass drawbar configuration as per * some other emulations. It is extremely easy to do, just not convinved it * really make sense. */ {"", BRIGHTON_HAMMOND, Cm2, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondbrown.xpm", 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", BRIGHTON_HAMMOND, Cm1, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondbrown.xpm", 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", BRIGHTON_HAMMOND, Cm2, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondbrown.xpm", 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", BRIGHTON_HAMMOND, Cm1, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondbrown.xpm", 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", BRIGHTON_HAMMOND, Cm2, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondbrown.xpm", 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", BRIGHTON_HAMMOND, Cm1, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondbrown.xpm", 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", BRIGHTON_HAMMOND, Cm2, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondbrown.xpm", 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, }; static brightonLocations volume[1] = { {"MasterVolume", 0, 125, 125, 750, 750, 0, 1, 0, 0, 0, 0}, }; static brightonLocations leslie[2] = { {"Leslie On/Off", 2, 100, 600, 800, 200, 0, 1, 0, "bitmaps/buttons/sw3.xpm", "bitmaps/buttons/sw5.xpm", BRIGHTON_VERTICAL|BRIGHTON_NOSHADOW}, {"", 2, 100, 100, 800, 200, 0, 1, 0, /* * Use a slighly older rocker than the plastic white, looks mildly more * authentic. "bitmaps/buttons/rockerwhite.xpm", 0, 0} */ "bitmaps/buttons/sw3.xpm", "bitmaps/buttons/sw5.xpm", BRIGHTON_VERTICAL|BRIGHTON_NOSHADOW} }; #define mR1 100 #define mR2 300 #define mR3 550 #define mR4 800 #define mC1 50 #define mC2 213 #define mC3 376 #define mC4 539 #define mC5 705 #define S4 100 #define S5 150 static brightonLocations mem[MEM_COUNT] = { /* memories */ {"", 2, mC5, mR4, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, {"", 2, mC1, mR3, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, {"", 2, mC2, mR3, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, {"", 2, mC3, mR3, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, {"", 2, mC4, mR3, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, {"", 2, mC5, mR3, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, {"", 2, mC1, mR4, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, {"", 2, mC2, mR4, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, {"", 2, mC3, mR4, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, {"", 2, mC4, mR4, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, /* midi U, D, Load, Save */ {"", 2, mC1, mR2, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, mC2, mR2, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, mC4, mR2, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, mC3, mR2, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoffo.xpm", "bitmaps/buttons/pressono.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, mC5, mR2, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, /* display */ {"", 3, mC1, mR1, 750, 125, 0, 1, 0, 0, 0, 0}, }; #define OD1 90 #define OD2 92 #define OD3 70 #define OC1 65 #define OC2 (OC1 + OD1 + 50) #define OC3 (OC2 + OD1) #define OC4 (OC3 + OD1) #define OC5 (OC4 + OD1) #define OC6 (OC5 + OD1) #define OC7 (OC6 + OD1) #define OC8 (OC7 + OD1) #define OC9 (OC8 + OD1) #define OC10 (OC9 + OD1) #define OR1 23 #define OR2 (OR1 + OD2) #define OR3 (OR2 + OD2) #define OR4 (OR3 + OD2) #define OR5 (OR1 + 250) #define OR6 (OR5 + 250) #define OR7 (OR6 + 250) #define OS1 20 #define OS2 88 #define OS3 150 static brightonLocations opts[OPTS_COUNT] = { /* Leslie type - 26 */ {"Leslie Separate", 2, OC1, OR1, OS1, OS2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"Leslie Sync", 2, OC1, OR2, OS1, OS2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"Leslie NoBass", 2, OC1, OR3, OS1, OS2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"Leslie Break", 2, OC1, OR4, OS1, OS2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, /* Leslie global - 30 */ {"Leslie X-Over", 0, OC2, OR1, OS3, OS3, 0, 1, 0, "bitmaps/knobs/knobgreynew.xpm", 0, BRIGHTON_NOSHADOW}, {"Leslie Inertia", 0, OC3, OR1, OS3, OS3, 0, 1, 0, "bitmaps/knobs/knobgreynew.xpm", 0, BRIGHTON_NOSHADOW}, /* Leslie HS - 32 */ {"Leslie HighFreq", 0, OC5, OR1, OS3, OS3, 0, 1, 0, "bitmaps/knobs/knobgreennew.xpm", 0, BRIGHTON_NOSHADOW}, {"Leslie HighDepth", 0, OC6, OR1, OS3, OS3, 0, 1, 0, "bitmaps/knobs/knobgreennew.xpm", 0, BRIGHTON_NOSHADOW}, {"Leslie HighPhase", 0, OC7, OR1, OS3, OS3, 0, 1, 0, "bitmaps/knobs/knobgreennew.xpm", 0, BRIGHTON_NOSHADOW}, /* Leslie global - 35 */ {"Leslie Overdrive", 0, OC4, OR1, OS3, OS3, 0, 1, 0, "bitmaps/knobs/knobrednew.xpm", 0, BRIGHTON_NOSHADOW}, /* Leslie LS - 37 */ {"Leslie LowFreq", 0, OC8, OR1, OS3, OS3, 0, 1, 0, "bitmaps/knobs/knobyellownew.xpm", 0, BRIGHTON_NOSHADOW}, {"Leslie LowDepth", 0, OC9, OR1, OS3, OS3, 0, 1, 0, "bitmaps/knobs/knobyellownew.xpm", 0, BRIGHTON_NOSHADOW}, {"Leslie LowPhase", 0, OC10, OR1, OS3, OS3, 0, 1, 0, "bitmaps/knobs/knobyellownew.xpm", 0, BRIGHTON_NOSHADOW}, /* VC Params - 40 */ {"VibraChorus Phase", 0, OC2, OR5, OS3, OS3, 0, 1, 0, "bitmaps/knobs/knobbluenew.xpm", 0, BRIGHTON_NOSHADOW}, {"VibraChorus LC", 0, OC3, OR5, OS3, OS3, 0, 1, 0, "bitmaps/knobs/knobbluenew.xpm", 0, BRIGHTON_NOSHADOW}, {"VibraChorus Depth", 0, OC4, OR5, OS3, OS3, 0, 1, 0, "bitmaps/knobs/knobbluenew.xpm", 0, BRIGHTON_NOSHADOW}, /* Envelopes 43 */ {"Perc Fast Decay", 0, OC2, OR6, OS3, OS3, 0, 1, 0, "bitmaps/knobs/knobgreynew.xpm", 0, BRIGHTON_NOSHADOW}, {"Perc Slow Decay", 0, OC3, OR6, OS3, OS3, 0, 1, 0, "bitmaps/knobs/knobgreynew.xpm", 0, BRIGHTON_NOSHADOW}, {"Perc Fast Attack", 0, OC5, OR6, OS3, OS3, 0, 1, 0, "bitmaps/knobs/knobgreynew.xpm", 0, BRIGHTON_NOSHADOW}, {"Perc Slow Attack", 0, OC6, OR6, OS3, OS3, 0, 1, 0, "bitmaps/knobs/knobgreynew.xpm", 0, BRIGHTON_NOSHADOW}, /* Diverse - 47 */ {"Preacher", 2, OC1, OR7 - 10, OS1, OS2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"Compression", 2, OC1, OR7 + OD2 - 10, OS1, OS2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, {"Bright", 0, OC2, OR7, OS3, OS3, 0, 7, 0, "bitmaps/knobs/knobyellownew.xpm", 0, BRIGHTON_NOSHADOW}, {"Click", 0, OC3, OR7, OS3, OS3, 0, 1, 0, "bitmaps/knobs/knobrednew.xpm", 0, BRIGHTON_NOSHADOW}, {"Leslie T Phase", 0, OC10, OR5, OS3, OS3, 0, 1, 0, "bitmaps/knobs/knobyellownew.xpm", 0, BRIGHTON_NOSHADOW}, {"Damping", 0, OC4, OR7, OS3, OS3, 0, 1, 0, "bitmaps/knobs/knobyellownew.xpm", 0, BRIGHTON_NOSHADOW}, /* Hammond chorus phase delay 53 */ {"VibraChorus PD", 0, OC5, OR5, OS3, OS3, 0, 1, 0, "bitmaps/knobs/knobgreynew.xpm", 0, BRIGHTON_NOSHADOW}, /* Five reverb controls from 27 */ {"Reverb Decay", 0, OC6, OR7, OS3, OS3, 0, 1, 0, "bitmaps/knobs/knobbluenew.xpm", 0, BRIGHTON_NOSHADOW}, {"Reverb Drive", 0, OC7, OR7, OS3, OS3, 0, 1, 0, "bitmaps/knobs/knobbluenew.xpm", 0, BRIGHTON_NOSHADOW}, {"Reverb Crossover", 0, OC8, OR7, OS3, OS3, 0, 1, 0, "bitmaps/knobs/knobbluenew.xpm", 0, BRIGHTON_NOSHADOW}, {"Reverb Feedback", 0, OC9, OR7, OS3, OS3, 0, 1, 0, "bitmaps/knobs/knobbluenew.xpm", 0, BRIGHTON_NOSHADOW}, {"Reverb Wet", 0, OC10, OR7, OS3, OS3, 0, 1, 0, "bitmaps/knobs/knobbluenew.xpm", 0, BRIGHTON_NOSHADOW}, {"", 0, OC10, OR7, OS3, OS3, 0, 1, 0, "bitmaps/knobs/knobbluenew.xpm", 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, OC10, OR7, OS3, OS3, 0, 1, 0, "bitmaps/knobs/knobbluenew.xpm", 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, OC10, OR7, OS3, OS3, 0, 1, 0, "bitmaps/knobs/knobbluenew.xpm", 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, OC10, OR7, OS3, OS3, 0, 1, 0, "bitmaps/knobs/knobbluenew.xpm", 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, OC10, OR7, OS3, OS3, 0, 1, 0, "bitmaps/knobs/knobbluenew.xpm", 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, OC10, OR7, OS3, OS3, 0, 1, 0, "bitmaps/knobs/knobbluenew.xpm", 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, OC10, OR7, OS3, OS3, 0, 1, 0, "bitmaps/knobs/knobbluenew.xpm", 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, OC10, OR7, OS3, OS3, 0, 1, 0, "bitmaps/knobs/knobbluenew.xpm", 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, }; static int commonPreset = -1; static void commonPresets(brightonWindow *win, guiSynth *synth, int index, float value) { if (value == 0.0) { if (index != 23) commonPreset = -1; return; } if (commonPreset != -1) { brightonEvent event; event.command = BRIGHTON_PARAMCHANGE; event.type = BRIGHTON_FLOAT; event.value = 0; /* printf("commonPresets(): %i %i\n", index, commonPreset); */ if (index == 23) { if (brightonDoubleClick(dc)) saveMemory(synth, "hammondB3", 0, synth->bank + synth->location, FIRST_DEV); brightonParamChange(synth->win, KEY_PANEL2, index - 12, &event); return; } if (commonPreset < 12) /* Key release upper manual */ brightonParamChange(synth->win, KEY_PANEL1, commonPreset, &event); else /* Key release lower manual, commonPreset - 12 */ brightonParamChange(synth->win, KEY_PANEL2, commonPreset - 12, &event); } synth->location = commonPreset = index; loadMemory(synth, "hammondB3", 0, synth->bank + synth->location, C_COUNT, FIRST_DEV, 0); } static int umCallback(brightonWindow * win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); if (global.libtest) return(0); if (synth->flags & REQ_MIDI_DEBUG) printf("umCallback(%i, %i, %f)\n", global.libtest, index, value); /* * If the code from 0 to 11 then this will become the preset section and * be used to load the first 24 memories. */ if (index < 12) { /* printf("umCallback(%x, %i, %i, %f): %i %i\n", synth, panel, index, */ /* value, synth->transpose, global.controlfd); */ commonPresets(win, synth, index, value); return(0); } /* * Want to send a note event, on or off, for this index + transpose. */ if (value) bristolMidiSendMsg(manual.controlfd, synth->midichannel, BRISTOL_EVENT_KEYON, 0, index + synth->transpose); else bristolMidiSendMsg(manual.controlfd, synth->midichannel, BRISTOL_EVENT_KEYOFF, 0, index + synth->transpose); return(0); } static int lmCallback(brightonWindow * win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); if (global.libtest) return(0); if (synth->flags & REQ_MIDI_DEBUG) printf("lmCallback(%i, %i, %f)\n", panel, index, value); /* * If the code from 0 to 11 then this will become the preset section and * be used to load the first 24 memories. */ if (index < 12) { /* printf("lmCallback(%x, %i, %i, %f): %i %i\n", synth, panel, index, */ /* value, synth->transpose, global.controlfd); */ commonPresets(win, synth, index + 12, value); return(0); } /* * Want to send a note event, on or off, for this index + transpose. */ if (value) bristolMidiSendMsg(manual.controlfd, synth->midichannel + 1, BRISTOL_EVENT_KEYON, 0, index + synth->transpose); else bristolMidiSendMsg(manual.controlfd, synth->midichannel + 1, BRISTOL_EVENT_KEYOFF, 0, index + synth->transpose); return(0); } static int hammondB3destroy(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); printf("hammondB3destroy(%p): %i\n", win, synth->midichannel); /* * Since we registered two synths, we now need to remove the upper * manual. */ bristolMidiSendMsg(manual.controlfd, synth->sid2, 127, 0, BRISTOL_EXIT_ALGO); bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_EXIT_ALGO); return(0); } int b3PedalCallback(brightonWindow *win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); if ((synth->flags & OPERATIONAL) == 0) return(0); /* * Want to send a note event, on or off, for this index + transpose. */ if (value > 0) bristolMidiSendMsg(global.controlfd, synth->midichannel + 1, BRISTOL_EVENT_KEYON, 0, index); else bristolMidiSendMsg(global.controlfd, synth->midichannel + 1, BRISTOL_EVENT_KEYOFF, 0, index); return(0); } /* * This is a set of globals for the main window rendering. Again taken from * include/brighton.h */ brightonApp hammondB3App = { "hammondB3", 0, /* no blueprint on wood background. */ "bitmaps/textures/wood3.xpm", 0, /* BRIGHTON_STRETCH, //flags */ hammondB3Init, hammondB3Configure, /* 3 callbacks, unused? */ hammondB3MidiCallback, hammondB3destroy, {-1, 0, 2, 2, 5, 175, 0, 0}, 765, 400, 0, 0, 15, { { "HammondB3", "bitmaps/blueprints/hammondB3.xpm", "bitmaps/textures/metal5.xpm", 0, /*BRIGHTON_STRETCH, // flags */ 0, 0, hammondB3Callback, 25, 122, 950, 238, C_COUNT, locations }, { "Opts", "bitmaps/blueprints/hammondB3opts.xpm", "bitmaps/textures/wood3.xpm", 0x020, /*BRIGHTON_STRETCH, // flags */ 0, 0, hammondB3Callback, 74, 357, 632, 440, /*70, 440, 470, 500, */ OPTS_COUNT, opts }, { "volume", 0, "bitmaps/textures/metal5.xpm", 0, /*BRIGHTON_STRETCH, // flags */ 0, 0, hammondB3Callback, 25, 427, 47, 89, 1, volume }, { "leslie", 0, "bitmaps/textures/metal5.xpm", 0, /*BRIGHTON_STRETCH, // flags */ 0, 0, hammondB3Callback, 30, 707, 40, 89, 2, leslie }, { "Memory", "bitmaps/blueprints/hammondB3mem.xpm", "bitmaps/textures/wood3.xpm", 0x020, /*BRIGHTON_STRETCH, // flags */ 0, 0, hammondB3Callback, 704, 358, 270, 440, /*70, 440, 470, 500, */ MEM_COUNT, mem }, { "HammondB3bar", 0, "bitmaps/textures/metal5.xpm", 0, /*flags */ 0, 0, 0, 25, 561, 950, 29, 0, 0 }, { "Keyboard", 0, "bitmaps/newkeys/hkbg.xpm", /* flags */ BRIGHTON_STRETCH, 0, 0, umCallback, 70, 357, 878, 211, KEY_COUNT_6_OCTAVE, keys6hammond }, { "Keyboard", 0, "bitmaps/newkeys/hkbg.xpm", /* flags */ BRIGHTON_STRETCH, 0, 0, lmCallback, 74, 589, 870, 211, KEY_COUNT_6_OCTAVE, keys6hammond }, { "Pedalboard", 0, "bitmaps/textures/wood6.xpm", BRIGHTON_STRETCH, 0, 0, b3PedalCallback, 260, 823, 500, 167, KEY_COUNT_PEDAL, pedalBoard }, { "Wood Edge", 0, "bitmaps/textures/wood.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 0, 0, 25, 813, 0, 0 }, { "Wood Edge", 0, "bitmaps/textures/wood.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /*flags */ 0, 0, 0, 975, 0, 25, 813, 0, 0 }, { "Wood", 0, "bitmaps/textures/wood4.xpm", 0, 0, 0, 0, 25, 24, 950, 57, 0, 0 }, { "Wood", 0, "bitmaps/textures/wood4.xpm", BRIGHTON_STRETCH, 0, 0, 0, 25, 49, 950, 73, 0, 0 }, { "Wood", 0, "bitmaps/textures/wood5.xpm", BRIGHTON_STRETCH, /*flags */ 0, 0, 0, 25, 49, 950, 122, 0, 0 }, { "Pedalboard", 0, "bitmaps/keys/vkbg.xpm", BRIGHTON_STRETCH, 0, 0, 0, 0, 813, 1000, 187, 0, 0 }, } }; static void b3SendMsg(int fd, int chan, int c, int o, int v) { /*printf("b3SendMsg(%i, %i, %i, %i, %i) [%i, %i]\n", fd, chan, c, o, v, */ /*global.controlfd, manual.controlfd); */ bristolMidiSendMsg(global.controlfd, chan, c, o, v); bristolMidiSendMsg(manual.controlfd, chan + 1, c, o, v); } static void hammondB3Memory(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; /*printf("hammondB3Memory(%i, %i)\n", c, o); */ if (synth->dispatch[RADIOSET_1].other2) { synth->dispatch[RADIOSET_1].other2 = 0; return; } switch (c) { default: case 0: /* * We want to make these into memory buttons. To do so we need to * know what the last active button was, and deactivate its * display, then send any message which represents the most * recently configured value. Since this is a memory button we do * not have much issue with the message, but we are concerned with * the display. */ if (synth->dispatch[RADIOSET_1].other1 != -1) { synth->dispatch[RADIOSET_1].other2 = 1; if (synth->dispatch[RADIOSET_1].other1 != o) event.value = 0; else event.value = 1; brightonParamChange(synth->win, DISPLAY_PAN, synth->dispatch[RADIOSET_1].other1, &event); } synth->dispatch[RADIOSET_1].other1 = o; if (synth->flags & BANK_SELECT) { if ((synth->bank * 10 + o * 10) >= 1000) { synth->location = o; synth->flags &= ~BANK_SELECT; if (loadMemory(synth, "hammondB3", 0, synth->bank + synth->location, synth->mem.active, FIRST_DEV, BRISTOL_STAT) < 0) displayPanelText(synth, "FRE", synth->bank + synth->location, DISPLAY_PAN, DISPLAY_DEV); else displayPanelText(synth, "PRG", synth->bank + synth->location, DISPLAY_PAN, DISPLAY_DEV); } else { synth->bank = synth->bank * 10 + o * 10; if (loadMemory(synth, "hammondB3", 0, synth->bank + synth->location, synth->mem.active, FIRST_DEV, BRISTOL_STAT) < 0) displayPanelText(synth, "FRE", synth->bank + synth->location, DISPLAY_PAN, DISPLAY_DEV); else displayPanelText(synth, "BANK", synth->bank + synth->location, DISPLAY_PAN, DISPLAY_DEV); } } else { synth->location = o; if (loadMemory(synth, "hammondB3", 0, synth->bank + synth->location, synth->mem.active, FIRST_DEV, BRISTOL_STAT) < 0) displayPanelText(synth, "FRE", synth->bank + synth->location, DISPLAY_PAN, DISPLAY_DEV); else displayPanelText(synth, "PRG", synth->bank + synth->location, DISPLAY_PAN, DISPLAY_DEV); } break; case 1: synth->flags |= MEM_LOADING; if (loadMemory(synth, "hammondB3", 0, synth->bank + synth->location, synth->mem.active, FIRST_DEV, 0) < 0) displayPanelText(synth, "FRE", synth->bank + synth->location, DISPLAY_PAN, DISPLAY_DEV); else displayPanelText(synth, "PRG", synth->bank + synth->location, DISPLAY_PAN, DISPLAY_DEV); synth->flags &= ~MEM_LOADING; synth->flags &= ~BANK_SELECT; break; case 2: saveMemory(synth, "hammondB3", 0, synth->bank + synth->location, FIRST_DEV); displayPanelText(synth, "PRG", synth->bank + synth->location, DISPLAY_PAN, DISPLAY_DEV); synth->flags &= ~BANK_SELECT; break; case 3: if (synth->flags & BANK_SELECT) { synth->flags &= ~BANK_SELECT; if (loadMemory(synth, "hammondB3", 0, synth->bank + synth->location, synth->mem.active, FIRST_DEV, BRISTOL_STAT) < 0) displayPanelText(synth, "FRE", synth->bank + synth->location, DISPLAY_PAN, DISPLAY_DEV); else displayPanelText(synth, "PRG", synth->bank + synth->location, DISPLAY_PAN, DISPLAY_DEV); } else { synth->bank = 0; displayPanelText(synth, "BANK", synth->bank, DISPLAY_PAN, DISPLAY_DEV); synth->flags |= BANK_SELECT; } break; } /* printf(" hammondB3Memory(B: %i L %i: %i)\n", */ /* synth->bank, synth->location, o); */ } static void hammondB3Midi(guiSynth *synth, int fd, int chan, int c, int o, int v) { int newchan; /* printf("hammondB3Midi(%i %i %i %i %i)\n", fd, chan, c, o, v); */ if ((synth->flags & OPERATIONAL) == 0) return; if (c == 1) { if ((newchan = synth->midichannel - 1) < 0) { synth->midichannel = 0; return; } } else { /* * On the upper side we need to reserve two midi channels */ if ((newchan = synth->midichannel + 1) >= 15) { synth->midichannel = 14; return; } } /* * Lower manual midi channel selection first */ bristolMidiSendMsg(manual.controlfd, synth->sid2, 127, 0, (BRISTOL_MIDICHANNEL|newchan) + 1); bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_MIDICHANNEL|newchan); synth->midichannel = newchan; displayPanelText(synth, "MIDI", synth->midichannel + 1, DISPLAY_PAN, DISPLAY_DEV); } /* * For the sake of ease of use, links have been placed here to be called * by any of the devices created. They would be better in some other file, * perhaps with this as a dispatch. * * Param refers to the device index in the locations table given below. */ static int hammondB3Callback(brightonWindow * win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); int sendvalue; /*printf("hammondB3Callback(%i, %i, %f): %x\n", panel, index, value, synth); */ if (synth == 0) return(0); if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0)) return(0); if (hammondB3App.resources[panel].devlocn[index].to == 1.0) sendvalue = value * (CONTROLLER_RANGE - 1); else sendvalue = value; switch (panel) { default: case 0: break; case 1: index += OPTS_START; break; case 2: index += VOL_START; break; case 3: index += LESLIE_START; break; case 4: index += MEM_START; break; } /*printf("index is now %i, %i %i\n", index, DEVICE_COUNT, ACTIVE_DEVS); */ synth->mem.param[index] = value; if ((!global.libtest) || (index >= ACTIVE_DEVS) || (index == 18)) synth->dispatch[index].routine(synth, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #ifdef DEBUG else printf("dispatch[%x,%i](%i, %i, %i, %i, %i)\n", synth, index, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #endif return(0); } static void hammondB3Passthrough(float value) { /* printf("hammondB3Passthrough\n"); */ } static void doVolume(guiSynth *synth) { b3SendMsg(global.controlfd, synth->sid, 0, 4, (int) (synth->mem.param[VOL_START] * C_RANGE_MIN_1)); b3SendMsg(global.controlfd, synth->sid2, 0, 4, (int) (synth->mem.param[VOL_START] * C_RANGE_MIN_1)); b3SendMsg(global.controlfd, synth->sid2, 3, 4, (int) (synth->mem.param[VOL_START] * C_RANGE_MIN_1)); } static void doLMSlider(guiSynth *synth, int fd, int chan, int cont, int op, int value) { int slidervalue; /*printf("doLMSlider(%x, %i, %i, %i, %i, %i)\n", */ /*synth, fd, chan, cont, op, value); */ slidervalue = cont * 9 + value; bristolMidiSendMsg(manual.controlfd, synth->sid2, 0, 2, slidervalue); } static void doPedalSlider(guiSynth *synth, int fd, int chan, int cont, int op, int value) { int slidervalue; slidervalue = cont * 9 + value; bristolMidiSendMsg(manual.controlfd, synth->sid2, 3, 2, slidervalue); } static void doDrawbar(guiSynth *synth, int fd, int chan, int cont, int op, int value) { int slidervalue; /*printf("doDrawbar(%x, %i, %i, %i, %i, %i)\n", */ /* synth, fd, chan, cont, op, value); */ slidervalue = cont * 9 + value; bristolMidiSendMsg(global.controlfd, synth->sid, 0, 2, slidervalue); } static void hammondB3Switch(guiSynth *id, int fd, int chan, int cont, int op, int value) { brightonEvent event; /* printf("hammondB3Switch(%x, %i, %i, %i, %i, %i)\n", */ /* id, fd, chan, cont, op, value); */ id->flags &= ~OPERATIONAL; /* * If the sendvalue is zero, then withdraw the opts window, draw the * keyboard window, and vice versa. */ if (value == 0) { event.type = BRIGHTON_EXPOSE; event.intvalue = 0; brightonParamChange(id->win, 1, -1, &event); event.intvalue = 0; brightonParamChange(id->win, 4, -1, &event); event.intvalue = 1; brightonParamChange(id->win, 5, -1, &event); event.intvalue = 1; brightonParamChange(id->win, 6, -1, &event); event.intvalue = 1; brightonParamChange(id->win, 7, -1, &event); shade_id = brightonPut(id->win, "bitmaps/blueprints/hammondB3shade.xpm", 0, 0, id->win->width, id->win->height); } else { brightonRemove(id->win, shade_id); event.type = BRIGHTON_EXPOSE; event.intvalue = 0; brightonParamChange(id->win, 5, -1, &event); event.intvalue = 0; brightonParamChange(id->win, 6, -1, &event); event.intvalue = 0; brightonParamChange(id->win, 7, -1, &event); event.intvalue = 1; brightonParamChange(id->win, 1, -1, &event); event.intvalue = 1; brightonParamChange(id->win, 4, -1, &event); } id->flags |= OPERATIONAL; } static void doVibra(guiSynth *synth, int fd, int chan, int cont, int op, int v) { /* printf("doVibra(%i, %i, %i)\n", cont, op, v); * We get a value from 0 to 6. * 0 1 2 are vibra only, with speeds from the opts panel. * 3 is off * 4 5 6 are vibrachorus, with same respective speeds */ switch (op) { case 0: /* Tap delay */ bristolMidiSendMsg(global.controlfd, synth->sid, 6, 0, v); break; case 1: /* Delay line progressive filtering */ bristolMidiSendMsg(global.controlfd, synth->sid, 6, 1, v); break; case 2: doClick(synth); if (v == 3) { bristolMidiSendMsg(global.controlfd, synth->sid, 126, 0, 0); return; } /* * Turn it on, set a depth and a VC. */ bristolMidiSendMsg(global.controlfd, synth->sid, 126, 0, 1); if (v < 3) { bristolMidiSendMsg(global.controlfd, synth->sid, 6, 2, 3 - v); bristolMidiSendMsg(global.controlfd, synth->sid, 6, 4, 0); return; } bristolMidiSendMsg(global.controlfd, synth->sid, 6, 2, v - 3); bristolMidiSendMsg(global.controlfd, synth->sid, 6, 4, 1); break; case 3: /* Direct signal gain */ bristolMidiSendMsg(global.controlfd, synth->sid, 6, 3, v); break; case 4: /* Rate */ bristolMidiSendMsg(global.controlfd, synth->sid, 6, 5, v); break; } } #define LESLIE_ONOFF 18 static void doLeslieSpeed(guiSynth *synth) { int speed, depth, phase; if (synth->mem.param[LESLIE_ONOFF] == 0) { bristolMidiSendMsg(global.controlfd, synth->sid, 100, 7, 0); return; } bristolMidiSendMsg(global.controlfd, synth->sid, 100, 4, (int) (synth->mem.param[OPTS_START + 24] * C_RANGE_MIN_1)); /* * If we do not yet have another option, configure this as default */ if (synth->dispatch[OPTS_START + 1].other1 == 0) synth->dispatch[OPTS_START + 1].other1 = 1; bristolMidiSendMsg(global.controlfd, synth->sid, 100, 7, (int) (synth->dispatch[OPTS_START + 1].other1)); if (synth->mem.param[LESLIE_START] == 0) { speed = synth->mem.param[OPTS_START + 6] * C_RANGE_MIN_1; depth = synth->mem.param[OPTS_START + 7] * C_RANGE_MIN_1; phase = synth->mem.param[OPTS_START + 8] * C_RANGE_MIN_1; } else { speed = synth->mem.param[OPTS_START + 10] * C_RANGE_MIN_1; depth = synth->mem.param[OPTS_START + 11] * C_RANGE_MIN_1; phase = synth->mem.param[OPTS_START + 12] * C_RANGE_MIN_1; } bristolMidiSendMsg(global.controlfd, synth->sid, 100, 0, speed); bristolMidiSendMsg(global.controlfd, synth->sid, 100, 3, depth); bristolMidiSendMsg(global.controlfd, synth->sid, 100, 2, phase); bristolMidiSendMsg(global.controlfd, synth->sid, 100, 6, (int) (synth->mem.param[OPTS_START + 4] * C_RANGE_MIN_1)); bristolMidiSendMsg(global.controlfd, synth->sid, 100, 1, (int) (synth->mem.param[OPTS_START + 5] * C_RANGE_MIN_1)); } static void doReverbParam(guiSynth *synth, int fd, int chan, int cont, int op, int value) { /*printf("doReverbParam(%i, %i, %i)\n", cont, op, value); */ if (op == 4) bristolMidiSendMsg(global.controlfd, synth->sid, 101, 5, value); bristolMidiSendMsg(global.controlfd, synth->sid, 101, op, value); } static void doReverb(guiSynth *synth) { if (synth->mem.param[DEVICE_START + 19] == 0) bristolMidiSendMsg(global.controlfd, synth->sid, 101, 3, 0); else bristolMidiSendMsg(global.controlfd, synth->sid, 101, 3, (int) (synth->mem.param[OPTS_START + 30] * C_RANGE_MIN_1)); } static void doDamping(guiSynth *synth, int fd, int chan, int cont, int op, int value) { bristolMidiSendMsg(global.controlfd, synth->sid, 0, 1, value); bristolMidiSendMsg(global.controlfd, synth->sid2, 0, 1, value); } static void doClick(guiSynth *synth) { float scale = 1.0; if (synth->mem.param[DEVICE_START + 20] != 3) scale = 0.1; /* * If we have VC enabled then reduce the click volume by half, otherwise * it is full strength. */ b3SendMsg(global.controlfd, synth->sid, 0, 6, (int) (synth->mem.param[OPTS_START + 23] * C_RANGE_MIN_1 * scale)); b3SendMsg(global.controlfd, synth->sid2, 0, 6, (int) (synth->mem.param[OPTS_START + 23] * C_RANGE_MIN_1 * scale)); } static void doPreacher(guiSynth *synth) { if (synth->mem.param[OPTS_START + 20] == 0) { b3SendMsg(global.controlfd, synth->sid, 126, 3, 0); b3SendMsg(global.controlfd, synth->sid, 0, 7, 0); b3SendMsg(global.controlfd, synth->sid2, 0, 7, 0); b3SendMsg(global.controlfd, synth->sid2, 3, 7, 0); } else { b3SendMsg(global.controlfd, synth->sid, 126, 3, 1); b3SendMsg(global.controlfd, synth->sid, 0, 7, 1); b3SendMsg(global.controlfd, synth->sid2, 0, 7, 1); b3SendMsg(global.controlfd, synth->sid2, 3, 7, 1); } } static void doBright(guiSynth *synth) { /*printf("doBright()\n"); */ if (synth->mem.param[DEVICE_START + 21] == 0) { /* * Once to the hammond manager */ b3SendMsg(global.controlfd, synth->sid, 126, 1, 0); /* * And to the sine oscillator */ b3SendMsg(global.controlfd, synth->sid, 0, 0, 0); b3SendMsg(global.controlfd, synth->sid, 0, 0, 8); b3SendMsg(global.controlfd, synth->sid, 0, 0, 16); b3SendMsg(global.controlfd, synth->sid, 0, 0, 24); b3SendMsg(global.controlfd, synth->sid, 0, 0, 32); b3SendMsg(global.controlfd, synth->sid, 0, 0, 40); b3SendMsg(global.controlfd, synth->sid, 0, 0, 48); b3SendMsg(global.controlfd, synth->sid, 0, 0, 56); b3SendMsg(global.controlfd, synth->sid, 0, 0, 64); } else { b3SendMsg(global.controlfd, synth->sid, 126, 1, (int) (synth->mem.param[OPTS_START + 22])); b3SendMsg(global.controlfd, synth->sid, 0, 0, 0 + (int) (synth->mem.param[OPTS_START + 22])); b3SendMsg(global.controlfd, synth->sid, 0, 0, 8 + (int) (synth->mem.param[OPTS_START + 22])); b3SendMsg(global.controlfd, synth->sid, 0, 0, 16 + (int) (synth->mem.param[OPTS_START + 22])); b3SendMsg(global.controlfd, synth->sid, 0, 0, 24 + (int) (synth->mem.param[OPTS_START + 22])); b3SendMsg(global.controlfd, synth->sid, 0, 0, 32 + (int) (synth->mem.param[OPTS_START + 22])); b3SendMsg(global.controlfd, synth->sid, 0, 0, 40 + (int) (synth->mem.param[OPTS_START + 22])); b3SendMsg(global.controlfd, synth->sid, 0, 0, 48 + (int) (synth->mem.param[OPTS_START + 22])); b3SendMsg(global.controlfd, synth->sid, 0, 0, 56 + (int) (synth->mem.param[OPTS_START + 22])); b3SendMsg(global.controlfd, synth->sid, 0, 0, 64 + (int) (synth->mem.param[OPTS_START + 22])); } } static void doCompress(guiSynth *synth) { /*printf("doCompress()\n"); */ if (synth->mem.param[OPTS_START + 21] == 0) { b3SendMsg(global.controlfd, synth->sid, 126, 2, 0); } else { b3SendMsg(global.controlfd, synth->sid, 126, 2, 1); } } static void doGrooming(guiSynth *synth) { /*printf("doGrooming()\n"); */ if (synth->mem.param[DEVICE_START + 25] != 0) { b3SendMsg(global.controlfd, synth->sid, 1, 0, (int) (synth->mem.param[OPTS_START + 18] * C_RANGE_MIN_1)); } else { b3SendMsg(global.controlfd, synth->sid, 1, 0, (int) (synth->mem.param[OPTS_START + 19] * C_RANGE_MIN_1)); } } static void doPerc(guiSynth *synth) { /*printf("doPerc()\n"); */ /* * 4 foot percussive */ if (synth->mem.param[DEVICE_START + 22] == 0) bristolMidiSendMsg(global.controlfd, synth->sid, 0, 3, 24); else bristolMidiSendMsg(global.controlfd, synth->sid, 0, 3, 25); /* * 2 1/3 foot percussive */ if (synth->mem.param[DEVICE_START + 23] == 0) bristolMidiSendMsg(global.controlfd, synth->sid, 0, 3, 32); else bristolMidiSendMsg(global.controlfd, synth->sid, 0, 3, 33); /* * Slow fast decay */ if (synth->mem.param[DEVICE_START + 24] == 0) bristolMidiSendMsg(global.controlfd, synth->sid, 4, 1, (int) (synth->mem.param[OPTS_START + 16] * C_RANGE_MIN_1)); else bristolMidiSendMsg(global.controlfd, synth->sid, 4, 1, (int) (synth->mem.param[OPTS_START + 17] * C_RANGE_MIN_1)); } static void hammondOption(guiSynth *synth, int fd, int chan, int cont, int op, int value) { brightonEvent event; /*printf("hammondOption(%x, %i, %i, %i, %i, %i)\n", */ /* synth, fd, chan, cont, op, value); */ switch (cont) { case OPTS_START: /* * Rotation type. Send 100.7 becomes op; */ if ((synth->flags & MEM_LOADING) == 0) { if (synth->dispatch[OPTS_START].other2) { synth->dispatch[OPTS_START].other2 = 0; return; } synth->dispatch[OPTS_START].other2 = 1; if (synth->dispatch[OPTS_START].other1 >= 0) { event.command = BRIGHTON_PARAMCHANGE; if (synth->dispatch[OPTS_START].other1 != (op - 1)) event.value = 0; else event.value = 1; brightonParamChange(synth->win, OPTS_PANEL, synth->dispatch[OPTS_START].other1, &event); } } if (synth->mem.param[OPTS_START + op - 1] != 0) { synth->dispatch[OPTS_START].other1 = op - 1; synth->dispatch[OPTS_START + 1].other1 = op; if (synth->mem.param[LESLIE_ONOFF] == 0) bristolMidiSendMsg(global.controlfd, chan, 100, 7, 0); else { bristolMidiSendMsg(global.controlfd, chan, 100, 7, op); bristolMidiSendMsg(global.controlfd, chan, 100, 1, (int) (synth->mem.param[OPTS_START + 5] * C_RANGE_MIN_1)); } } break; case OPTS_START + 3: /* * Rotor break. Send 100.7 = 4 off, 100.7 = 5 on. */ if (value == 0) bristolMidiSendMsg(global.controlfd, chan, 100, 7, 4); else bristolMidiSendMsg(global.controlfd, chan, 100, 7, 5); break; case OPTS_START + 4: case OPTS_START + 5: case OPTS_START + 6: case OPTS_START + 7: case OPTS_START + 8: case OPTS_START + 10: case OPTS_START + 11: case OPTS_START + 12: doLeslieSpeed(synth); break; case OPTS_START + 9: /* overdrive */ bristolMidiSendMsg(global.controlfd, synth->sid, 100, 5, (int) (synth->mem.param[OPTS_START + 9] * C_RANGE_MIN_1)); break; case OPTS_START + 13: case OPTS_START + 14: case OPTS_START + 15: doVibra(synth, fd, chan, cont, op, value); break; case OPTS_START + 16: case OPTS_START + 17: doPerc(synth); break; case OPTS_START + 18: case OPTS_START + 19: doGrooming(synth); break; case OPTS_START + 20: doPreacher(synth); break; case OPTS_START + 21: doCompress(synth); break; case OPTS_START + 22: doBright(synth); break; case OPTS_START + 23: doClick(synth); break; case OPTS_START + 24: doLeslieSpeed(synth); break; case OPTS_START + 25: doDamping(synth, fd, chan, cont, op, value); break; /* case OPTS_START + 26: */ default: break; } } /* * Any location initialisation required to run the callbacks. For bristol, this * will connect to the engine, and give it some base parameters. * May need to generate some application specific menus. * Will also then make specific requests to some of the devices to alter their * rendering. */ static int hammondB3Init(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); dispatcher *dispatch; int i; if (synth == 0) { synth = findSynth(global.synths, 0); if (synth == 0) { printf("cannot init\n"); return(0); } } synth->win = win; printf("Initialise the hammondB3 link to bristol: %p\n", synth->win); synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float)); synth->mem.count = DEVICE_COUNT; synth->mem.active = ACTIVE_DEVS; synth->dispatch = (dispatcher *) brightonmalloc(DEVICE_COUNT * sizeof(dispatcher)); dispatch = synth->dispatch; if (!global.libtest) { if (synth->synthtype == BRISTOL_HAMMONDB3) { bcopy(&global, &manual, sizeof(guimain)); manual.home = 0; synth->synthtype = BRISTOL_HAMMOND; if ((synth->sid = initConnection(&global, synth)) < 0) return(-1); /* * send a hello, with a voice count, then request starting of the * synthtype. All of these will require an ACK, and we should wait * here and read that ack before proceeding with each next step. */ manual.flags |= BRISTOL_CONN_FORCE|BRIGHTON_NOENGINE; manual.port = global.port; manual.host = global.host; synth->midichannel++; synth->synthtype = BRISTOL_HAMMONDB3; if ((synth->sid2 = initConnection(&manual, synth)) < 0) return(-1); synth->midichannel--; global.manualfd = manual.controlfd; global.manual = &manual; manual.manual = &global; } else { if ((synth->sid2 = initConnection(&manual, synth)) < 0) return(-1); } } for (i = 0; i < DEVICE_COUNT; i++) { synth->dispatch[i].routine = (synthRoutine) hammondB3Passthrough; } /* * Put in the drawbar configurations, upper manual */ dispatch[0].routine = dispatch[1].routine = dispatch[2].routine = dispatch[3].routine = dispatch[4].routine = dispatch[5].routine = dispatch[6].routine = dispatch[7].routine = dispatch[8].routine = (synthRoutine) doLMSlider; dispatch[0].controller = 0; dispatch[1].controller = 1; dispatch[2].controller = 2; dispatch[3].controller = 3; dispatch[4].controller = 4; dispatch[5].controller = 5; dispatch[6].controller = 6; dispatch[7].controller = 7; dispatch[8].controller = 8; /* * Put in the drawbar configurations, upper manual */ dispatch[DRAWBAR_START].routine = dispatch[DRAWBAR_START + 1].routine = dispatch[DRAWBAR_START + 2].routine = dispatch[DRAWBAR_START + 3].routine = dispatch[DRAWBAR_START + 4].routine = dispatch[DRAWBAR_START + 5].routine = dispatch[DRAWBAR_START + 6].routine = dispatch[DRAWBAR_START + 7].routine = dispatch[DRAWBAR_START + 8].routine = (synthRoutine) doDrawbar; dispatch[DRAWBAR_START].controller = 0; dispatch[DRAWBAR_START + 1].controller = 1; dispatch[DRAWBAR_START + 2].controller = 2; dispatch[DRAWBAR_START + 3].controller = 3; dispatch[DRAWBAR_START + 4].controller = 4; dispatch[DRAWBAR_START + 5].controller = 5; dispatch[DRAWBAR_START + 6].controller = 6; dispatch[DRAWBAR_START + 7].controller = 7; dispatch[DRAWBAR_START + 8].controller = 8; /* Options controllers */ dispatch[OPTS_START].routine = (synthRoutine) hammondOption; dispatch[OPTS_START].controller = OPTS_START; dispatch[OPTS_START].operator = 1; dispatch[OPTS_START + 1].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 1].controller = OPTS_START; dispatch[OPTS_START + 1].operator = 2; dispatch[OPTS_START + 2].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 2].controller = OPTS_START; dispatch[OPTS_START + 2].operator = 3; dispatch[OPTS_START].other1 = -1; dispatch[OPTS_START].other2 = 0; dispatch[OPTS_START + 3].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 3].controller = OPTS_START + 3; dispatch[OPTS_START + 4].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 4].controller = OPTS_START + 4; dispatch[OPTS_START + 5].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 5].controller = OPTS_START + 5; dispatch[OPTS_START + 6].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 6].controller = OPTS_START + 6; dispatch[OPTS_START + 7].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 7].controller = OPTS_START + 7; dispatch[OPTS_START + 8].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 8].controller = OPTS_START + 8; dispatch[OPTS_START + 9].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 9].controller = OPTS_START + 9; dispatch[OPTS_START + 10].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 10].controller = OPTS_START + 10; dispatch[OPTS_START + 11].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 11].controller = OPTS_START + 11; dispatch[OPTS_START + 12].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 12].controller = OPTS_START + 12; /* vibra */ dispatch[OPTS_START + 13].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 13].controller = OPTS_START + 13; dispatch[OPTS_START + 13].operator = 0; dispatch[OPTS_START + 14].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 14].controller = OPTS_START + 14; dispatch[OPTS_START + 14].operator = 1; dispatch[OPTS_START + 15].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 15].controller = OPTS_START + 15; dispatch[OPTS_START + 15].operator = 3; dispatch[DEVICE_START + 20].controller = 6; dispatch[DEVICE_START + 20].operator = 2; dispatch[DEVICE_START + 20].routine = (synthRoutine) doVibra; /* Percussives */ dispatch[OPTS_START + 16].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 16].controller = OPTS_START + 16; dispatch[OPTS_START + 17].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 17].controller = OPTS_START + 17; dispatch[22].routine = (synthRoutine) doPerc; dispatch[23].routine = (synthRoutine) doPerc; dispatch[24].routine = (synthRoutine) doPerc; /* Soft attack - grooming */ dispatch[OPTS_START + 18].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 18].controller = OPTS_START + 18; dispatch[OPTS_START + 19].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 19].controller = OPTS_START + 19; dispatch[DEVICE_START + 25].routine = (synthRoutine) doGrooming; /* Bass Drawbars */ dispatch[26].routine = dispatch[27].routine = (synthRoutine) doPedalSlider; dispatch[26].controller = 0; dispatch[27].controller = 1; /* preacher */ dispatch[OPTS_START + 20].routine = (synthRoutine) doPreacher; dispatch[OPTS_START + 20].controller = OPTS_START + 20; dispatch[OPTS_START + 21].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 21].controller = OPTS_START + 21; dispatch[OPTS_START + 22].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 22].controller = OPTS_START + 22; dispatch[DEVICE_START + 21].routine = (synthRoutine) doBright; dispatch[OPTS_START + 23].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 23].controller = OPTS_START + 23; /* reverb */ dispatch[OPTS_START + 24].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 24].controller = OPTS_START + 24; dispatch[OPTS_START + 25].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 25].controller = OPTS_START + 25; /* dispatch[OPTS_START + 26].routine = (synthRoutine) hammondOption; */ dispatch[OPTS_START + 26].controller = 6; dispatch[OPTS_START + 26].operator = 4; dispatch[OPTS_START + 26].routine = (synthRoutine) doVibra; /* Reverb */ dispatch[OPTS_START + 27].controller = 101; dispatch[OPTS_START + 27].operator = 0; dispatch[OPTS_START + 27].routine = (synthRoutine) doReverbParam; dispatch[OPTS_START + 28].controller = 101; dispatch[OPTS_START + 28].operator = 1; dispatch[OPTS_START + 28].routine = (synthRoutine) doReverbParam; dispatch[OPTS_START + 29].controller = 101; dispatch[OPTS_START + 29].operator = 2; dispatch[OPTS_START + 29].routine = (synthRoutine) doReverbParam; dispatch[OPTS_START + 30].controller = 101; dispatch[OPTS_START + 30].operator = 3; dispatch[OPTS_START + 30].routine = (synthRoutine) doReverbParam; dispatch[OPTS_START + 31].controller = 101; dispatch[OPTS_START + 31].operator = 4; dispatch[OPTS_START + 31].routine = (synthRoutine) doReverbParam; dispatch[DEVICE_START + 19].routine = (synthRoutine) doReverb; dispatch[DEVICE_START + 18].routine = (synthRoutine) doLeslieSpeed; dispatch[LESLIE_START].routine = (synthRoutine) doLeslieSpeed; dispatch[VOL_START].routine = (synthRoutine) doVolume; /* Memory/Midi buttons */ dispatch[MEM_START + 10].controller = 12; dispatch[MEM_START + 10].operator = 0; /* * These are for the memory radio buttons */ dispatch[MEM_START].other1 = 0; dispatch[MEM_START].other2 = 0; dispatch[MEM_START].operator = 0; dispatch[MEM_START + 1].operator = 1; dispatch[MEM_START + 2].operator = 2; dispatch[MEM_START + 3].operator = 3; dispatch[MEM_START + 4].operator = 4; dispatch[MEM_START + 5].operator = 5; dispatch[MEM_START + 6].operator = 6; dispatch[MEM_START + 7].operator = 7; dispatch[MEM_START + 8].operator = 8; dispatch[MEM_START + 9].operator = 9; dispatch[MEM_START].routine = dispatch[MEM_START + 1].routine = dispatch[MEM_START + 2].routine = dispatch[MEM_START + 3].routine = dispatch[MEM_START + 4].routine = dispatch[MEM_START + 5].routine = dispatch[MEM_START + 6].routine = dispatch[MEM_START + 7].routine = dispatch[MEM_START + 8].routine = dispatch[MEM_START + 9].routine = (synthRoutine) hammondB3Memory; /* * Mem load and save */ dispatch[MEM_START + 12].controller = 1; dispatch[MEM_START + 13].controller = 2; dispatch[MEM_START + 14].controller = 3; dispatch[MEM_START + 12].routine = dispatch[MEM_START + 13].routine = dispatch[MEM_START + 14].routine = (synthRoutine) hammondB3Memory; /* * Midi up/down */ dispatch[MEM_START + 10].controller = 2; dispatch[MEM_START + 11].controller = 1; dispatch[MEM_START + 10].routine = dispatch[MEM_START + 11].routine = (synthRoutine) hammondB3Midi; bristolMidiSendMsg(global.controlfd, synth->sid, 1, 0, 0); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 1, 3); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 2, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 3, 400); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 4, 13000); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 5, 0); bristolMidiSendMsg(global.controlfd, synth->sid, 12, 7, 1); bristolMidiSendMsg(global.controlfd, synth->sid, 10, 0, 4); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 0, 0); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 1, 10); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 2, 13000); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 3, 400); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 4, 13000); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 5, 0); bristolMidiSendMsg(global.controlfd, synth->sid, 4, 0, 2); bristolMidiSendMsg(global.controlfd, synth->sid, 4, 1, 1200); bristolMidiSendMsg(global.controlfd, synth->sid, 4, 2, 0); bristolMidiSendMsg(global.controlfd, synth->sid, 4, 3, 20); bristolMidiSendMsg(global.controlfd, synth->sid, 4, 4, 15500); bristolMidiSendMsg(global.controlfd, synth->sid, 4, 5, 0); bristolMidiSendMsg(manual.controlfd, synth->sid2, 1, 0, 2); bristolMidiSendMsg(manual.controlfd, synth->sid2, 1, 1, 3); bristolMidiSendMsg(manual.controlfd, synth->sid2, 1, 2, 16383); bristolMidiSendMsg(manual.controlfd, synth->sid2, 1, 3, 1000); bristolMidiSendMsg(manual.controlfd, synth->sid2, 1, 4, 13000); bristolMidiSendMsg(manual.controlfd, synth->sid2, 1, 5, 0); dispatch[LESLIE_START + 1].routine = (synthRoutine) hammondB3Switch; return(0); } static int hammondB3MidiCallback(brightonWindow *win, int controller, int value, float n) { guiSynth *synth = findSynth(global.synths, win); printf("midi callback: %x, %i\n", controller, value); switch(controller) { case MIDI_PROGRAM: printf("midi program: %x, %i\n", controller, value); synth->location = value; loadMemory(synth, "hammondB3", 0, synth->bank + synth->location, synth->mem.active, FIRST_DEV, 0); break; case MIDI_BANK_SELECT: printf("midi banksel: %x, %i\n", controller, value); synth->bank = value; break; } return(0); } /* * This will be called to make any routine specific parameters available. */ static int hammondB3Configure(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); brightonEvent event; if (synth == 0) { printf("problems going operational\n"); return(-1); } if (synth->flags & OPERATIONAL) return(0); printf("going operational: %p, %p\n", synth, win); synth->flags |= OPERATIONAL; synth->keypanel = 6; synth->keypanel2 = 7; synth->transpose = 24; synth->bank = 0; synth->location = 0; hammondB3Switch(synth, 0, 0, 0, 0, 1); loadMemory(synth, "hammondB3", 0, 0, synth->mem.active, FIRST_DEV, 0); hammondB3Switch(synth, 0, 0, 0, 0, 0); /* * We also want to configure the mod wheel so that it is half way up, this * affects the speed of the leslie. */ if (global.libtest == 0) { bristolMidiControl(global.controlfd, synth->midichannel, 0, 1, C_RANGE_MIN_1 >> 1); bristolMidiControl(global.controlfd, synth->midichannel + 1, 0, 1, C_RANGE_MIN_1 >> 1); /* * And the expression (foot) pedal to full on as it governs the gain */ bristolMidiControl(global.controlfd, synth->midichannel, 0, 4, C_RANGE_MIN_1); bristolMidiControl(global.controlfd, synth->midichannel + 1, 0, 4, C_RANGE_MIN_1); } synth->mem.param[LESLIE_ONOFF] = 1; event.type = BRIGHTON_EXPOSE; event.intvalue = 1; brightonParamChange(synth->win, 8, -1, &event); /* event.value = 1.0; */ /* brightonParamChange(synth->win, 1, 2, &event); */ /* brightonParamChange(synth->win, 1, 0, &event); */ configureGlobals(synth); dc = brightonGetDCTimer(win->dcTimeout); bristolMidiSendMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_KEYON, 0, 10 + synth->transpose); bristolMidiSendMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_KEYOFF, 0, 10 + synth->transpose); return(0); } bristol-0.60.11/brighton/brightonVoxM2.c0000644000175000017500000010573711746476475015010 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include #include "brighton.h" #include "brightonMini.h" #include "brightoninternals.h" static int voxM2Init(); static int voxM2Configure(); static int voxM2Callback(brightonWindow *, int, int, float); static int midiCallback(brightonWindow *, int, int, float); extern guimain global; #include "brightonKeys.h" static guimain manual; static int dc; #define MOD_PANEL 0 #define OPTS_PANEL 1 #define KEY_PANEL 2 #define VARS_PANEL 4 #define KEY_PANEL2 (KEY_PANEL + 1) #define FIRST_DEV 0 #define MOD_COUNT 44 #define DUMMY_OFFSET 26 #define OPTS_COUNT 4 #define VARS_COUNT 11 #define MOD_START 0 #define OPTS_START MOD_COUNT #define MEM_START (MOD_COUNT - 7) #define ACTIVE_DEVS (MOD_COUNT - 7) #define DEVICE_COUNT (MOD_COUNT + OPTS_COUNT) #define DISPLAY_DEV (DEVICE_COUNT - 1) #define MEM_MGT ACTIVE_DEVS #define MIDI_MGT (MEM_MGT + 12) /* * This structure is for device definition. The structure is defined in * include/brighton.h, further definitions in brighton/brightonDevtable.h and * include/brightoninternals.h * * typedef int (*brightonCallback)(int, float); * typedef struct BrightonLocations { * int device; 0=rotary, 1=scale, etc. * float relx, rely; relative position with regards to 1000 by 1000 window * float relw, relh; relative height. * int from, to; * brightonCallback callback; specific to this dev * char *image; bitmap. If zero take a device default. * int flags; * } brightonLocations; * * This example is for a voxM2Bristol type synth interface. */ #define R1 230 #define W1 20 #define L1 850 #define L2 300 #define D1 25 #define D2 20 /* 2 + 4+2 + 5+2 */ #define C1 240 #define C2 (C1 + D1) #define C3 340 #define C4 (C3 + D1) #define C5 (C4 + D1) #define C6 (C5 + D1) #define C7 (C6 + D1 + 20) #define C8 (C7 + D1) #define C9 570 #define C10 (C9 + D1) #define C11 (C10 + D1) #define C12 (C11 + D1) #define C13 (C12 + D1) #define C14 (C13 + D1 + 20) #define C15 (C14 + D1) #define C16 835 #define C17 (C16 + D2) #define C18 (C17 + D2) #define C19 (C18 + D2) #define C20 40 #define C21 (C20 + D2) #define C22 (C21 + D2) #define C23 (C22 + D2) #define C24 (C23 + D2) #define C25 (C24 + D2) #define C26 (C25 + D2) static brightonLocations locations[MOD_COUNT] = { /* 0 - Drawbars, lower, upper then bass */ {"Lower 8'", 1, C3, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondwhite.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, {"Lower 4'", 1, C4, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondwhite.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, {"Lower 2'", 1, C5, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondwhite.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, {"Lower IV'", 1, C6, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondwhite.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, {"Lower Flute", 1, C7, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondbrown.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, {"Lower Reed", 1, C8, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondbrown.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, {"Upper 16'", 1, C9, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondwhite.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, {"Upper 8'", 1, C10, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondwhite.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, {"Upper 4'", 1, C11, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondwhite.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, {"Upper II'", 1, C12, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondwhite.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, {"Upper III'", 1, C13, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondwhite.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, {"Upper Flute", 1, C14, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondbrown.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, {"Upper Reed", 1, C15, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondbrown.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, {"Bass Flute", 1, C1, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondbrown.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, {"Bass Reed", 1, C2, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondbrown.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, /* 15 - Percussive buttons, 4 of them */ {"Perc-I", 2, C16, R1, W1, L2, 0, 1, 0, "bitmaps/buttons/pushout.xpm", "bitmaps/buttons/pushin.xpm", 0}, {"Perc-II", 2, C17, R1, W1, L2, 0, 1, 0, "bitmaps/buttons/pushout.xpm", "bitmaps/buttons/pushin.xpm", 0}, {"Perc-L", 2, C18, R1, W1, L2, 0, 1, 0, "bitmaps/buttons/pushoutw.xpm", "bitmaps/buttons/pushinw.xpm", 0}, {"Perc-S", 2, C19, R1, W1, L2, 0, 1, 0, "bitmaps/buttons/pushoutw.xpm", "bitmaps/buttons/pushinw.xpm", 0}, /* 19 - Dummies, 12 in total for opts and vars */ {"", 2, C16, R1, W1, L2, 0, 1, 0, "bitmaps/buttons/pushout.xpm", "bitmaps/buttons/pushin.xpm", BRIGHTON_WITHDRAWN}, {"", 2, C17, R1, W1, L2, 0, 1, 0, "bitmaps/buttons/pushout.xpm", "bitmaps/buttons/pushin.xpm", BRIGHTON_WITHDRAWN}, {"", 2, C18, R1, W1, L2, 0, 1, 0, "bitmaps/buttons/pushoutw.xpm", "bitmaps/buttons/pushinw.xpm", BRIGHTON_WITHDRAWN}, {"", 2, C19, R1, W1, L2, 0, 1, 0, "bitmaps/buttons/pushoutw.xpm", "bitmaps/buttons/pushinw.xpm", BRIGHTON_WITHDRAWN}, {"", 2, C19, R1, W1, L2, 0, 1, 0, "bitmaps/buttons/pushoutw.xpm", "bitmaps/buttons/pushinw.xpm", BRIGHTON_WITHDRAWN}, {"", 2, C16, R1, W1, L2, 0, 1, 0, "bitmaps/buttons/pushout.xpm", "bitmaps/buttons/pushin.xpm", BRIGHTON_WITHDRAWN}, {"", 2, C17, R1, W1, L2, 0, 1, 0, "bitmaps/buttons/pushout.xpm", "bitmaps/buttons/pushin.xpm", BRIGHTON_WITHDRAWN}, {"", 2, C18, R1, W1, L2, 0, 1, 0, "bitmaps/buttons/pushoutw.xpm", "bitmaps/buttons/pushinw.xpm", BRIGHTON_WITHDRAWN}, {"", 2, C19, R1, W1, L2, 0, 1, 0, "bitmaps/buttons/pushoutw.xpm", "bitmaps/buttons/pushinw.xpm", BRIGHTON_WITHDRAWN}, {"", 2, C19, R1, W1, L2, 0, 1, 0, "bitmaps/buttons/pushoutw.xpm", "bitmaps/buttons/pushinw.xpm", BRIGHTON_WITHDRAWN}, {"", 2, C16, R1, W1, L2, 0, 1, 0, "bitmaps/buttons/pushout.xpm", "bitmaps/buttons/pushin.xpm", BRIGHTON_WITHDRAWN}, {"", 2, C17, R1, W1, L2, 0, 1, 0, "bitmaps/buttons/pushout.xpm", "bitmaps/buttons/pushin.xpm", BRIGHTON_WITHDRAWN}, /* * Dummies, 6. Note that the first set, above, are used to save the Opts * controls for Bass register/sustain and vibrato so to maintain the * memories between releases they should remain reserved, the rest are * used as placeholders for the VARS panel. The following six remain free * however they may become reverb depth and level. * 31 - 36 */ {"", 2, C18, R1, W1, L2, 0, 1, 0, "bitmaps/buttons/pushoutw.xpm", "bitmaps/buttons/pushinw.xpm", BRIGHTON_WITHDRAWN}, {"", 2, C19, R1, W1, L2, 0, 1, 0, "bitmaps/buttons/pushoutw.xpm", "bitmaps/buttons/pushinw.xpm", BRIGHTON_WITHDRAWN}, {"", 2, C18, R1, W1, L2, 0, 1, 0, "bitmaps/buttons/pushoutw.xpm", "bitmaps/buttons/pushinw.xpm", BRIGHTON_WITHDRAWN}, {"", 2, C19, R1, W1, L2, 0, 1, 0, "bitmaps/buttons/pushoutw.xpm", "bitmaps/buttons/pushinw.xpm", BRIGHTON_WITHDRAWN}, {"", 2, C18, R1, W1, L2, 0, 1, 0, "bitmaps/buttons/pushoutw.xpm", "bitmaps/buttons/pushinw.xpm", BRIGHTON_WITHDRAWN}, {"", 2, C19, R1, W1, L2, 0, 1, 0, "bitmaps/buttons/pushoutw.xpm", "bitmaps/buttons/pushinw.xpm", BRIGHTON_WITHDRAWN}, /* Memory buttons, 7 buttons for 6 locations and save */ {"", 2, C20, R1, W1, L2, 0, 1, 0, "bitmaps/buttons/pushoutw.xpm", "bitmaps/buttons/pushinw.xpm", 0}, {"", 2, C21, R1, W1, L2, 0, 1, 0, "bitmaps/buttons/pushoutw.xpm", "bitmaps/buttons/pushinw.xpm", 0}, {"", 2, C22, R1, W1, L2, 0, 1, 0, "bitmaps/buttons/pushoutw.xpm", "bitmaps/buttons/pushinw.xpm", 0}, {"", 2, C23, R1, W1, L2, 0, 1, 0, "bitmaps/buttons/pushoutw.xpm", "bitmaps/buttons/pushinw.xpm", 0}, {"", 2, C24, R1, W1, L2, 0, 1, 0, "bitmaps/buttons/pushoutw.xpm", "bitmaps/buttons/pushinw.xpm", 0}, {"", 2, C25, R1, W1, L2, 0, 1, 0, "bitmaps/buttons/pushoutw.xpm", "bitmaps/buttons/pushinw.xpm", 0}, {"", 2, C26, R1, W1, L2, 0, 1, 0, "bitmaps/buttons/pushout.xpm", "bitmaps/buttons/pushin.xpm", BRIGHTON_CHECKBUTTON}, }; static brightonLocations options[OPTS_COUNT] = { {"", 2, 420, 300, 100, 300, 0, 1, 0, "bitmaps/buttons/rockersmoothBW.xpm", "bitmaps/buttons/rockersmoothBWd.xpm", 0}, {"", 0, 600, 300, 250, 250, 0, 1, 0, 0, 0, 0}, {"", 2, 850, 300, 100, 300, 0, 1, 0, "bitmaps/buttons/rockersmoothBW.xpm", "bitmaps/buttons/rockersmoothBWd.xpm", 0}, {"", 2, 100, 300, 170, 300, 0, 1, 0, "bitmaps/buttons/rockersmoothBWR.xpm", "bitmaps/buttons/rockersmoothBWRd.xpm", 0}, }; static brightonLocations variables[VARS_COUNT] = { {"", 0, 35, 280, 100, 400, 0, 1, 0, 0, 0, BRIGHTON_NOSHADOW}, {"", 0, 110, 280, 100, 400, 0, 1, 0, 0, 0, BRIGHTON_NOSHADOW}, {"", 0, 185, 280, 100, 400, 0, 1, 0, 0, 0, BRIGHTON_NOSHADOW}, {"", 2, 270, 280, 25, 400, 0, 1, 0, "bitmaps/buttons/rockersmoothBW.xpm", "bitmaps/buttons/rockersmoothBWd.xpm", 0}, {"", 0, 335, 280, 100, 400, 0, 1, 0, 0, 0, BRIGHTON_NOSHADOW}, {"", 0, 410, 280, 100, 400, 0, 1, 0, 0, 0, BRIGHTON_NOSHADOW}, {"", 0, 485, 280, 100, 400, 0, 1, 0, 0, 0, BRIGHTON_NOSHADOW}, {"", 0, 560, 280, 100, 400, 0, 1, 0, 0, 0, BRIGHTON_NOSHADOW}, /* Reverb params - 3 */ {"", 0, 635, 280, 100, 400, 0, 1, 0, 0, 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 0, 710, 280, 100, 400, 0, 1, 0, 0, 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 0, 775, 280, 100, 400, 0, 1, 0, 0, 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, }; static void memFix(brightonWindow* win, guiSynth *synth) { brightonEvent event; int i; event.command = BRIGHTON_PARAMCHANGE; event.type = BRIGHTON_FLOAT; for (i = 0; i < 19; i++) { event.value = synth->mem.param[i]; brightonParamChange(synth->win, 0, i, &event); } /* MODS */ event.value = synth->mem.param[19 + 0]; brightonParamChange(synth->win, OPTS_PANEL, 0, &event); event.value = synth->mem.param[19 + 1]; brightonParamChange(synth->win, OPTS_PANEL, 1, &event); event.value = synth->mem.param[19 + 2]; brightonParamChange(synth->win, OPTS_PANEL, 2, &event); /* VARS */ event.value = synth->mem.param[23 + 0]; brightonParamChange(synth->win, VARS_PANEL, 0, &event); event.value = synth->mem.param[23 + 1]; brightonParamChange(synth->win, VARS_PANEL, 1, &event); event.value = synth->mem.param[23 + 2]; brightonParamChange(synth->win, VARS_PANEL, 2, &event); event.value = synth->mem.param[23 + 3]; brightonParamChange(synth->win, VARS_PANEL, 3, &event); event.value = synth->mem.param[23 + 4]; brightonParamChange(synth->win, VARS_PANEL, 4, &event); event.value = synth->mem.param[23 + 5]; brightonParamChange(synth->win, VARS_PANEL, 5, &event); event.value = synth->mem.param[23 + 6]; brightonParamChange(synth->win, VARS_PANEL, 6, &event); event.value = synth->mem.param[23 + 7]; brightonParamChange(synth->win, VARS_PANEL, 7, &event); } static int memCallback(brightonWindow* win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); if (synth->flags & SUPPRESS) return(0); /* * The first ten buttons are exclusive highlighting, we use the first mem * pointer to handle this. */ if (synth->dispatch[MEM_START].other2) { synth->dispatch[MEM_START].other2 = 0; return(0); } /* Is this the save key, double clicked? */ if (index == MOD_COUNT - 1) { if (brightonDoubleClick(dc)) { synth->location = synth->dispatch[MEM_START].other1 - MEM_START; saveMemory(synth, "voxM2", 0, synth->bank + synth->location, 0); } return(0); } /* * Is this one of the presets? * * We should consider making these require a doubleclick also. */ if (index >= MEM_START) { brightonEvent event; event.command = BRIGHTON_PARAMCHANGE; event.type = BRIGHTON_FLOAT; event.value = 0; /* * This is a numeric. We need to force exclusion. */ if (synth->dispatch[MEM_START].other1 != -1) { synth->dispatch[MEM_START].other2 = 1; if (synth->dispatch[MEM_START].other1 != index) event.value = 0; else event.value = 1; brightonParamChange(synth->win, panel, synth->dispatch[MEM_START].other1, &event); } synth->location = index - MEM_START; loadMemory(synth, "voxM2", 0, synth->bank + synth->location, synth->mem.active, 0, BRISTOL_NOCALLS); memFix(win, synth); synth->dispatch[MEM_START].other1 = index; } return(0); } int voxloadMemory(guiSynth *synth, char *algo, char *name, int location, int active, int skip, int flags) { loadMemory(synth, "voxM2", 0, location, synth->mem.active, 0, BRISTOL_NOCALLS); memFix(synth->win, synth); return(0); } int voxPedalCallback(brightonWindow *win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); if ((synth->flags & OPERATIONAL) == 0) return(0); /* * Want to send a note event, on or off, for this index + transpose. */ if (value > 0) bristolMidiSendMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_KEYON, 0, index + 24); else bristolMidiSendMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_KEYOFF, 0, index + 24); return(0); } int voxkeyCallback(brightonWindow *win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); int chan = 0, transp = 0; if (global.libtest) return(0); if (panel == KEY_PANEL2) { transp = 12; chan = 1; } /*printf("keycallback(%x, %i, %i, %f): %i %i\n", synth, panel, index, value, */ /* synth->transpose, global.controlfd); */ /* * Want to send a note event, on or off, for this index + transpose. */ if (value) bristolMidiSendMsg(global.controlfd, synth->midichannel + chan, BRISTOL_EVENT_KEYON, 0, index + synth->transpose + transp); else bristolMidiSendMsg(global.controlfd, synth->midichannel + chan, BRISTOL_EVENT_KEYOFF, 0, index + synth->transpose + transp); return(0); } /* * This is a set of globals for the main window rendering. Again taken from * include/brighton.h */ brightonApp voxM2App = { "voxM2", 0, /* no blueprint on wood background. */ "bitmaps/textures/leather.xpm", 0, voxM2Init, voxM2Configure, /* 3 callbacks */ midiCallback, destroySynth, {-1, 0, 2, 2, 5, 520, 0, 0}, 520, 310, 0, 0, 9, /* panel count */ { { "Drawbars", /* and percussive selections */ "bitmaps/blueprints/voxm2.xpm", 0, BRIGHTON_STRETCH, 0, 0, voxM2Callback, 19, 184, 970, 190, MOD_COUNT, locations }, { "Mods", /* Bass sustain, vibrato on/off */ "bitmaps/blueprints/voxM2.xpm", "bitmaps/textures/leather.xpm", 0, 0, 0, voxM2Callback, 19, 386, 194, 210, OPTS_COUNT, options }, { "Keyboard", 0, "bitmaps/keys/vkbg.xpm", 0x020|BRIGHTON_STRETCH, 0, 0, voxkeyCallback, 55, 612, 710, 210, VKEY_COUNT, vkeys }, { "Keyboard", 0, "bitmaps/keys/vkbg.xpm", 0x020|BRIGHTON_STRETCH, 0, 0, voxkeyCallback, 224, 386, 730, 210, VKEY_COUNT, vkeys }, { "Variables", "bitmaps/blueprints/voxM2vars.xpm", "bitmaps/textures/leather.xpm", 0, /* flags */ 0, 0, voxM2Callback, 16, 24, 970, 160, VARS_COUNT, variables }, { "Top Panel", 0, "bitmaps/textures/orangeleather.xpm", 0, /* flags */ 0, 0, 0, 16, 24, 970, 160, 0, 0 }, { "Pedalboard", 0, "bitmaps/keys/vkbg.xpm", BRIGHTON_STRETCH, /* flags */ 0, 0, voxPedalCallback, 250, 850, 500, 150, 12, /* KEY_COUNT_PEDAL, */ pedalBoard }, { /* Underneath keyboards */ "Bottom Panel", 0, "bitmaps/textures/metal6.xpm", BRIGHTON_STRETCH|BRIGHTON_REVERSE, /* flags */ 0, 0, 0, 16, 386, 966, 440, 0, 0 }, { "Pedalboard", 0, "bitmaps/keys/vkbg.xpm", BRIGHTON_STRETCH, /* flags */ 0, 0, 0, 0, 850, 1000, 150, 0, 0 }, }, }; static int shade_id = 0; static void panelSwitch(guiSynth *id, int fd, int chan, int cont, int op, int value) { brightonEvent event; /* * If the sendvalue is zero, then withdraw the opts window, draw the * slider window, and vice versa. */ if (value == 0) { brightonRemove(id->win, shade_id); event.type = BRIGHTON_EXPOSE; event.intvalue = 0; brightonParamChange(id->win, 5, -1, &event); event.intvalue = 1; brightonParamChange(id->win, 4, -1, &event); shade_id = brightonPut(id->win, "bitmaps/blueprints/voxshade.xpm", 0, 0, id->win->width, id->win->height); } else { brightonRemove(id->win, shade_id); event.type = BRIGHTON_EXPOSE; event.intvalue = 0; brightonParamChange(id->win, 4, -1, &event); event.intvalue = 1; brightonParamChange(id->win, 5, -1, &event); shade_id = brightonPut(id->win, "bitmaps/blueprints/voxshade.xpm", 0, 0, id->win->width, id->win->height); } } static int midiCallback(brightonWindow *win, int controller, int value, float n) { guiSynth *synth = findSynth(global.synths, win); /* printf("midi callback: %x, %i\n", controller, value); */ switch(controller) { case MIDI_PROGRAM: printf("midi program: %x, %i\n", controller, value); synth->location = value; loadMemory(synth, synth->resources->name, 0, synth->bank + synth->location, synth->mem.active, FIRST_DEV, BRISTOL_NOCALLS); memFix(win, synth); break; case MIDI_BANK_SELECT: printf("midi banksel: %x, %i\n", controller, value); synth->bank = value * 10; break; } return(0); } static int voxM2MidiSendMsg(void *synth, int fd, int chan, int c, int o, int v) { /* printf("%i, %i, %i\n", c, o, v); */ bristolMidiSendMsg(fd, chan, c, o, v); return(0); } /* * For the sake of ease of use, links have been placed here to be called * by any of the devices created. They would be better in some other file, * perhaps with this as a dispatch. * * Param refers to the device index in the locations table given below. */ static int voxM2Callback(brightonWindow *win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); int sendvalue; if (synth == 0) return(0); if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0)) return(0); if (voxM2App.resources[panel].devlocn[index].to == 1) sendvalue = value * C_RANGE_MIN_1; else sendvalue = value; if (panel == OPTS_PANEL) index += 19; if (index == 22) { synth->dispatch[index].routine(synth, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); return(0); } if (panel == VARS_PANEL) index += 23; synth->mem.param[index] = value; if (index >= ACTIVE_DEVS) { memCallback(win, panel, index, value); return(0); } if ((!global.libtest) || (index >= ACTIVE_DEVS)) synth->dispatch[index].routine(synth, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #define DEBUG #ifdef DEBUG else printf("dispatch[%p,%i](%i, %i, %i, %i, %i)\n", synth, index, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #endif return(0); } static void voxM2Drawbar(guiSynth *synth, int fd, int chan, int cont, int op, int value) { int sval; /* printf("voxM2Drawbar(%x, %i, %i, %i, %i, %i)\n", synth, fd, chan, cont, op, value); */ /* * We have to take care of dual/triple manual stuff here. Also need to * block the upper manual 4' and II (which we are going to use for perc) * if they are selected on controllers 15 and 16. */ sval = cont * 16 + value; if ((op == 1) && (cont == 2) && (synth->mem.param[15] != 0)) { sval = cont * 16 + 8; bristolMidiSendMsg(global.controlfd, synth->sid2, 0, 0, sval); return; } if ((op == 1) && (cont == 6) && (synth->mem.param[16] != 0)) { sval = cont * 16 + 8; bristolMidiSendMsg(global.controlfd, synth->sid2, 0, 0, sval); return; } switch (op) { case 0: bristolMidiSendMsg(global.controlfd, synth->sid, 0, 0, sval); break; case 1: bristolMidiSendMsg(global.controlfd, synth->sid2, 0, 0, sval); break; } } static void voxM2Vibrato(guiSynth *id, int fd, int chan, int cont, int op, int value) { bristolMidiSendMsg(global.controlfd, chan, cont, op, value); bristolMidiSendMsg(global.controlfd, chan + 1, cont, op, value); } static void voxM2Volume(guiSynth *id, int fd, int chan, int cont, int op, int value) { bristolMidiSendMsg(global.controlfd, chan, 0, 1, value); bristolMidiSendMsg(global.controlfd, chan+1, 0, 1, value); bristolMidiSendMsg(global.controlfd, chan+1, 2, 1, value); } static void voxM2Option(guiSynth *synth, int fd, int chan, int cont, int op, int value) { int actual; /* * We deal with two values representing vibrato speed and depth, then with * percussive decays. */ switch (cont) { case 24: /* Vibra Speed */ bristolMidiSendMsg(global.controlfd, synth->sid, 1, 0, value); bristolMidiSendMsg(global.controlfd, synth->sid2, 1, 0, value); return; case 25: /* Vibra Depth */ bristolMidiSendMsg(global.controlfd, synth->sid, 1, 1, value); bristolMidiSendMsg(global.controlfd, synth->sid2, 1, 1, value); return; case 26: /* Vibra Chorus */ bristolMidiSendMsg(global.controlfd, synth->sid, 1, 2, value); bristolMidiSendMsg(global.controlfd, synth->sid2, 1, 2, value); return; case 27: /* * The next 4 are percusive controls. We have to see if they are * active and get their values before we send the requests. * * We have short/long/soft/loud * * Here - if L is not selected then short - set value. */ actual = synth->mem.param[27] * C_RANGE_MIN_1 / 2; if (synth->mem.param[17] == 0) bristolMidiSendMsg(global.controlfd, synth->sid2, 3, 1, actual); return; case 28: /* * Here - if L is selected then short - set value. */ actual = synth->mem.param[28] * C_RANGE_MIN_1 / 2; if (synth->mem.param[17] != 0) bristolMidiSendMsg(global.controlfd, synth->sid2, 3, 1, actual); return; case 29: /* * Here - if S is selected then soft - set value. */ actual = synth->mem.param[29] * C_RANGE_MIN_1; if (synth->mem.param[18] != 0) bristolMidiSendMsg(global.controlfd, synth->sid2, 3, 4, actual); return; case 30: /* * Here - if S is not selected then loud - set value. */ actual = synth->mem.param[30] * C_RANGE_MIN_1; if (synth->mem.param[18] == 0) bristolMidiSendMsg(global.controlfd, synth->sid2, 3, 4, actual); return; } } /* * Called when a wave selector button */ static void voxM2Waves(guiSynth *synth, int fd, int chan, int cont, int op, int value) { int tval; /* printf("waves %i %i %i\n", cont, op, value); */ if (value != 0) { bristolMidiSendMsg(global.controlfd, synth->sid2, cont, op, value); /* We just set the percussive option, must also send full on drawbar */ if (op == 2) bristolMidiSendMsg(global.controlfd, synth->sid2, 0, 0, 2 * 16 + 8); else bristolMidiSendMsg(global.controlfd, synth->sid2, 0, 0, 6 * 16 + 8); return; } /* * Ok, so we are turning the percussive off, that means we have to change * back to the drawbar current setting and disable percussive. */ bristolMidiSendMsg(global.controlfd, synth->sid2, cont, op, value); if (op == 2) tval = 2 * 16 + synth->mem.param[8]; else tval = 6 * 16 + synth->mem.param[9]; bristolMidiSendMsg(global.controlfd, synth->sid2, 0, 0, tval); } static void voxM2Bass(guiSynth *synth, int fd, int chan, int cont, int op, int value) { switch (op) { case 0: bristolMidiSendMsg(global.controlfd, synth->sid, 2, 0, value == 0? 16:24); break; case 4: case 5: bristolMidiSendMsg(global.controlfd, synth->sid, 2, 0, op * 16 + value); break; } } /* * This is called when the percussive wave selection buttons are pressed. * It needs to set wave gains and request perc options. */ static void voxM2Perc(guiSynth *synth, int fd, int chan, int cont, int op, int value) { int v; /* printf("perc %i %i %i\n", cont, op, value); */ switch (op) { default: if (value == 0) v = synth->mem.param[27] * C_RANGE_MIN_1 / 4; else v = synth->mem.param[28] * C_RANGE_MIN_1 / 4; break; case 4: if (value == 0) v = synth->mem.param[30] * C_RANGE_MIN_1; else v = synth->mem.param[29] * C_RANGE_MIN_1; break; } bristolMidiSendMsg(global.controlfd, synth->sid2, cont, op, v); } static void voxM2Reverb(guiSynth *synth, int fd, int chan, int cont, int op, int value) { bristolMidiSendMsg(global.controlfd, synth->sid2, cont, op, value); } /* * Any location initialisation required to run the callbacks. For bristol, this * will connect to the engine, and give it some base parameters. * May need to generate some application specific menus. * Will also then make specific requests to some of the devices to alter their * rendering. */ static int voxM2Init(brightonWindow* win) { guiSynth *synth = findSynth(global.synths, win); dispatcher *dispatch; int i; if (synth == 0) { synth = findSynth(global.synths, 0); if (synth == 0) { printf("cannot init\n"); return(0); } } synth->win = win; printf("Initialise the voxM2 link to bristol: %p\n", synth->win); synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float)); synth->mem.count = DEVICE_COUNT; synth->mem.active = ACTIVE_DEVS; synth->dispatch = (dispatcher *) brightonmalloc(DEVICE_COUNT * sizeof(dispatcher)); dispatch = synth->dispatch; /* * We really want to have three connection mechanisms. These should be * 1. Unix named sockets. * 2. UDP sockets. * 3. MIDI pipe. */ if (!global.libtest) { if (synth->midichannel > 14) synth->midichannel--; bcopy(&global, &manual, sizeof(guimain)); synth->synthtype = BRISTOL_VOX; if ((synth->sid = initConnection(&global, synth)) < 0) return(-1); /* Crank up another VOX for the upper manual */ manual.flags |= BRISTOL_CONN_FORCE|BRIGHTON_NOENGINE; manual.port = global.port; manual.host = global.host; synth->synthtype = BRISTOL_VOXM2; synth->midichannel++; if ((synth->sid2 = initConnection(&manual, synth)) < 0) return(-1); global.manualfd = manual.controlfd; global.manual = &manual; manual.manual = &global; synth->midichannel--; } for (i = 0; i < DEVICE_COUNT; i++) synth->dispatch[i].routine = voxM2MidiSendMsg; /* Lower manual basic VOX oscillator */ synth->dispatch[MOD_START + 0].operator = 0; synth->dispatch[MOD_START + 0].controller = 0; synth->dispatch[MOD_START + 1].operator = 0; synth->dispatch[MOD_START + 1].controller = 1; synth->dispatch[MOD_START + 2].operator = 0; synth->dispatch[MOD_START + 2].controller = 2; synth->dispatch[MOD_START + 3].operator = 0; synth->dispatch[MOD_START + 3].controller = 3; synth->dispatch[MOD_START + 4].operator = 0; synth->dispatch[MOD_START + 4].controller = 4; synth->dispatch[MOD_START + 5].operator = 0; synth->dispatch[MOD_START + 5].controller = 5; synth->dispatch[MOD_START + 0].routine = synth->dispatch[MOD_START + 1].routine = synth->dispatch[MOD_START + 2].routine = synth->dispatch[MOD_START + 3].routine = synth->dispatch[MOD_START + 4].routine = synth->dispatch[MOD_START + 5].routine = (synthRoutine) voxM2Drawbar; /* Upper manual basic VOX oscillator */ synth->dispatch[MOD_START + 6].operator = 1; synth->dispatch[MOD_START + 6].controller = 0; synth->dispatch[MOD_START + 7].operator = 1; synth->dispatch[MOD_START + 7].controller = 1; synth->dispatch[MOD_START + 8].operator = 1; synth->dispatch[MOD_START + 8].controller = 2; synth->dispatch[MOD_START + 9].operator = 1; synth->dispatch[MOD_START + 9].controller = 6; synth->dispatch[MOD_START + 10].operator = 1; synth->dispatch[MOD_START + 10].controller = 7; synth->dispatch[MOD_START + 11].operator = 1; synth->dispatch[MOD_START + 11].controller = 4; synth->dispatch[MOD_START + 12].operator = 1; synth->dispatch[MOD_START + 12].controller = 5; synth->dispatch[MOD_START + 6].routine = synth->dispatch[MOD_START + 7].routine = synth->dispatch[MOD_START + 8].routine = synth->dispatch[MOD_START + 9].routine = synth->dispatch[MOD_START + 10].routine = synth->dispatch[MOD_START + 11].routine = synth->dispatch[MOD_START + 12].routine = (synthRoutine) voxM2Drawbar; /* * 13 and 14 are the Bass drawbars */ synth->dispatch[MOD_START + 13].controller = 2; synth->dispatch[MOD_START + 13].operator = 4; synth->dispatch[MOD_START + 13].routine = (synthRoutine) voxM2Bass; synth->dispatch[MOD_START + 14].controller = 2; synth->dispatch[MOD_START + 14].operator = 5; synth->dispatch[MOD_START + 14].routine = (synthRoutine) voxM2Bass; /* * 15 and 16 are the percussive selectors that need to be sent to the * modified vox oscillator. We need a shim since they go to the second * manual. */ synth->dispatch[MOD_START + 15].controller = 0; synth->dispatch[MOD_START + 15].operator = 2; synth->dispatch[MOD_START + 16].controller = 0; synth->dispatch[MOD_START + 16].operator = 3; synth->dispatch[MOD_START + 15].routine = synth->dispatch[MOD_START + 16].routine = (synthRoutine) voxM2Waves; /* * Percussive harmonics then envelope */ synth->dispatch[MOD_START + 17].controller = 2; synth->dispatch[MOD_START + 17].operator = 1; synth->dispatch[MOD_START + 18].controller = 2; synth->dispatch[MOD_START + 18].operator = 4; synth->dispatch[MOD_START + 17].routine = synth->dispatch[MOD_START + 18].routine = (synthRoutine) voxM2Perc; /* Bass harmonics */ synth->dispatch[MOD_START + 19].controller = 2; synth->dispatch[MOD_START + 19].operator = 0; synth->dispatch[MOD_START + 19].routine = (synthRoutine) voxM2Bass; /* Bass sustain (actualy env release). */ synth->dispatch[MOD_START + 20].controller = 3; synth->dispatch[MOD_START + 20].operator = 3; /* Vibrato */ synth->dispatch[MOD_START + 21].controller = 126; synth->dispatch[MOD_START + 21].operator = 0; synth->dispatch[MOD_START + 21].routine = (synthRoutine) voxM2Vibrato; /* Panel switch */ synth->dispatch[MOD_START + 22].routine = (synthRoutine) panelSwitch; /* Volume */ synth->dispatch[MOD_START + 23].routine = (synthRoutine) voxM2Volume; /* Options */ synth->dispatch[MOD_START + 24].controller = 24; synth->dispatch[MOD_START + 24].routine = (synthRoutine) voxM2Option; synth->dispatch[MOD_START + 25].controller = 25; synth->dispatch[MOD_START + 25].routine = (synthRoutine) voxM2Option; synth->dispatch[MOD_START + 26].controller = 26; synth->dispatch[MOD_START + 26].routine = (synthRoutine) voxM2Option; synth->dispatch[MOD_START + 27].controller = 27; synth->dispatch[MOD_START + 27].routine = (synthRoutine) voxM2Option; synth->dispatch[MOD_START + 28].controller = 28; synth->dispatch[MOD_START + 28].routine = (synthRoutine) voxM2Option; synth->dispatch[MOD_START + 29].controller = 29; synth->dispatch[MOD_START + 29].routine = (synthRoutine) voxM2Option; synth->dispatch[MOD_START + 30].controller = 30; synth->dispatch[MOD_START + 30].routine = (synthRoutine) voxM2Option; /* Dummies need to be covered */ synth->dispatch[MOD_START + 31].controller = 99; synth->dispatch[MOD_START + 31].operator = 0; synth->dispatch[MOD_START + 32].controller = 99; synth->dispatch[MOD_START + 32].operator = 1; synth->dispatch[MOD_START + 33].controller = 99; synth->dispatch[MOD_START + 33].operator = 2; synth->dispatch[MOD_START + 31].routine = synth->dispatch[MOD_START + 32].routine = synth->dispatch[MOD_START + 33].routine = (synthRoutine) voxM2Reverb; synth->dispatch[MOD_START + 34].operator = 100; synth->dispatch[MOD_START + 34].controller = 100; synth->dispatch[MOD_START + 35].operator = 100; synth->dispatch[MOD_START + 35].controller = 100; synth->dispatch[MOD_START + 36].operator = 100; synth->dispatch[MOD_START + 36].controller = 100; synth->dispatch[MOD_START + 37].operator = 100; synth->dispatch[MOD_START + 37].controller = 100; synth->dispatch[MEM_START + 0].routine = synth->dispatch[MEM_START + 1].routine = synth->dispatch[MEM_START + 2].routine = synth->dispatch[MEM_START + 3].routine = synth->dispatch[MEM_START + 4].routine = synth->dispatch[MEM_START + 5].routine = (synthRoutine) memCallback; /* Vox Mark-II Oscillator */ bristolMidiSendMsg(global.controlfd, synth->sid2, 0, 4, 1); /* Bass Osc 8' (actually remapped to 4') */ bristolMidiSendMsg(global.controlfd, synth->sid, 2, 0, 40); /* * We have to setup the vibra with speed and depth defaults */ bristolMidiSendMsg(global.controlfd, synth->sid, 1, 0, 500); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 1, 2000); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 2, 0); bristolMidiSendMsg(global.controlfd, synth->sid2, 1, 0, 500); bristolMidiSendMsg(global.controlfd, synth->sid2, 1, 1, 2000); bristolMidiSendMsg(global.controlfd, synth->sid2, 1, 2, 0); /* Gain */ bristolMidiSendMsg(global.controlfd, synth->sid, 0, 1, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 2, 1, 16383); /* Perc env parameters */ bristolMidiSendMsg(global.controlfd, synth->sid2, 2, 0, 5); bristolMidiSendMsg(global.controlfd, synth->sid2, 2, 1, 2048); bristolMidiSendMsg(global.controlfd, synth->sid2, 2, 2, 0); bristolMidiSendMsg(global.controlfd, synth->sid2, 2, 3, 0); bristolMidiSendMsg(global.controlfd, synth->sid2, 2, 4, 16383); /* Bass env parameters ADSG, R is in the panel */ bristolMidiSendMsg(global.controlfd, synth->sid, 3, 0, 100); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 1, 100); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 2, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 4, 12000); return(0); } /* * This will be called to make any routine specific parameters available. */ static int voxM2Configure(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); brightonEvent event; if (synth == 0) { printf("problems going operational\n"); return(-1); } if (synth->flags & OPERATIONAL) return(0); printf("going operational\n"); synth->flags |= OPERATIONAL; synth->keypanel = KEY_PANEL; synth->keypanel2 = KEY_PANEL2; synth->transpose = 36; synth->bank = synth->location - (synth->location % 10); synth->location -= synth->bank; loadMemory(synth, "voxM2", 0, synth->bank + synth->location, synth->mem.active, FIRST_DEV, BRISTOL_NOCALLS); memFix(win, synth); /* * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only * occurs on first paint, so we suppress the first paint, and then request * an expose here. */ event.type = BRIGHTON_EXPOSE; event.intvalue = 1; brightonParamChange(synth->win, KEY_PANEL, -1, &event); brightonParamChange(synth->win, KEY_PANEL2, -1, &event); brightonParamChange(synth->win, 6, -1, &event); brightonParamChange(synth->win, 1, -1, &event); event.type = BRIGHTON_FLOAT; event.value = 1; brightonParamChange(synth->win, 1, 3, &event); configureGlobals(synth); synth->dispatch[MEM_START].other1 = MEM_START + synth->location; synth->dispatch[MEM_START].other2 = 1; event.type = BRIGHTON_FLOAT; event.value = 1.0; brightonParamChange(synth->win, 0, synth->location + MEM_START, &event); dc = brightonGetDCTimer(win->dcTimeout); synth->loadMemory = (loadRoutine) voxloadMemory; return(0); } bristol-0.60.11/brighton/brightonHammond.c0000644000175000017500000011050211746476475015402 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include #include "brighton.h" #include "brightonMini.h" #include "brightoninternals.h" static int hammondInit(); static int hammondConfigure(); static int hammondCallback(brightonWindow * , int, int, float); extern guimain global; #define FIRST_DEV 0 #define OPTS_PANEL 0 #define SLIDER_PANEL 1 #define MOD_PANEL 2 #define VOL_PANEL 3 #define MEM_PANEL 4 #define OPTS_COUNT 27 #define SLIDER_COUNT 9 #define MOD_COUNT 14 #define VOL_COUNT 1 #define MEM_COUNT 18 #define OPTS_START FIRST_DEV #define SLIDER_START (OPTS_START + OPTS_COUNT) #define MOD_START (SLIDER_START + SLIDER_COUNT) #define VOL_START (MOD_START + MOD_COUNT) #define MEM_START (VOL_START + VOL_COUNT) #define DEVICE_COUNT (SLIDER_COUNT + MOD_COUNT + MEM_COUNT + VOL_COUNT + OPTS_COUNT + FIRST_DEV) #define ACTIVE_DEVS (SLIDER_COUNT + MOD_COUNT + VOL_COUNT + OPTS_COUNT + FIRST_DEV) #define DISPLAY (MEM_COUNT - 1) #define DISPLAYPANEL 2 #define R1 60 #define D1 100 #define C1 75 #define C2 (C1 + D1) #define C3 (C2 + D1) #define C4 (C3 + D1) #define C5 (C4 + D1) #define C6 (C5 + D1) #define C7 (C6 + D1) #define C8 (C7 + D1) #define C9 (C8 + D1) #define W1 70 #define L1 800 /* * This structure is for device definition. The structure is defined in * include/brighton.h, further definitions in brighton/brightonDevtable.h and * include/brightoninternals.h * * typedef int (*brightonCallback)(int, float); * typedef struct BrightonLocations { * int device; 0=rotary, 1=scale, etc. * float relx, rely; relative position with regards to 1000 by 1000 window * float relw, relh; relative height. * int from, to; * brightonCallback callback; specific to this dev * char *image; bitmap. If zero take a device default. * int flags; * } brightonLocations; * * This example is for a hammondBristol type synth interface. */ static brightonLocations sliders[SLIDER_COUNT] = { {"", 1, C1, R1, W1, L1, 0, 7, 0, "bitmaps/knobs/hammondbrown.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, {"", 1, C2, R1, W1, L1, 0, 7, 0, "bitmaps/knobs/hammondbrown.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, {"", 1, C3, R1, W1, L1, 0, 7, 0, "bitmaps/knobs/hammondwhite.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, {"", 1, C4, R1, W1, L1, 0, 7, 0, "bitmaps/knobs/hammondwhite.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, {"", 1, C5, R1, W1, L1, 0, 7, 0, "bitmaps/knobs/hammondblack.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, {"", 1, C6, R1, W1, L1, 0, 7, 0, "bitmaps/knobs/hammondwhite.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, {"", 1, C7, R1, W1, L1, 0, 7, 0, "bitmaps/knobs/hammondblack.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, {"", 1, C8, R1, W1, L1, 0, 7, 0, "bitmaps/knobs/hammondblack.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, {"", 1, C9, R1, W1, L1, 0, 7, 0, "bitmaps/knobs/hammondwhite.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE} }; #define MR1 150 #define MR2 550 #define MD1 80 #define MC1 100 #define MC2 (MC1 + MD1) #define MC3 (MC2 + MD1) #define MC4 (MC3 + MD1) #define MC5 (MC4 + MD1) #define MC6 (500 + MC1) #define MC7 (500 + MC2) #define MC8 (500 + MC3) #define MC9 (500 + MC4) #define MC10 (500 + MC5) #define S4 35 #define S5 200 static brightonLocations memories[MEM_COUNT] = { /* Memory tablet */ {"", 2, MC10, MR2, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, {"", 2, MC6, MR1, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, {"", 2, MC7, MR1, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, {"", 2, MC8, MR1, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, {"", 2, MC9, MR1, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, {"", 2, MC10, MR1, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, {"", 2, MC6, MR2, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, {"", 2, MC7, MR2, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, {"", 2, MC8, MR2, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, {"", 2, MC9, MR2, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, {"", 2, MC1 - 50, MR2, S4, S5, 0, 1, 0, /* panel switch */ "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, /* midi U, D, Load, Save */ {"", 2, MC2, MR2, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, MC3, MR2, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, MC4, MR2, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, MC5, MR2, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoffo.xpm", "bitmaps/buttons/pressono.xpm", BRIGHTON_CHECKBUTTON}, /* mem up down */ {"", 2, 520, MR1, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 520, MR2, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, /* display */ {"", 3, MC2, MR1, 275, 250, 0, 1, 0, 0, 0, 0} }; #define MODD1 200 #define MODD2 300 #define MODC1 50 #define MODC2 (MODC1 + MODD1) #define MODC3 (MODC2 + MODD1) #define MODC4 (MODC3 + MODD1) #define MODC5 (MODC4 + MODD1) #define MODR1 100 #define MODR2 (MODR1 + MODD2) #define MODR3 (MODR2 + MODD2) #define MW1 80 #define MH1 150 static brightonLocations mods[MOD_COUNT] = { /* Leslie */ {"", 2, MODC1, MODR1, MW1, MH1, 0, 1, 0, "bitmaps/buttons/rockerblue.xpm", 0, 0}, {"", 2, MODC2, MODR1, MW1, MH1, 0, 1, 0, "bitmaps/buttons/rockerblue.xpm", 0, 0}, /* Vibra */ {"", 0, MODC3 - 30, MODR1, MW1 + 150, MH1 + 150, 0, 2, 0, 0, 0, 0}, {"", 2, MODC4, MODR1, MW1, MH1, 0, 1, 0, "bitmaps/buttons/rockerred.xpm", 0, 0}, {"", 2, MODC5, MODR1, MW1, MH1, 0, 1, 0, "bitmaps/buttons/rockerred.xpm", 0, 0}, /* Percussives */ {"", 2, MODC1, MODR3, MW1, MH1, 0, 1, 0, "bitmaps/buttons/rockerwhite.xpm", 0, 0}, {"", 2, MODC2, MODR3, MW1, MH1, 0, 1, 0, "bitmaps/buttons/rockerwhite.xpm", 0, 0}, {"", 2, MODC4, MODR2, MW1, MH1, 0, 1, 0, "bitmaps/buttons/rockerwhite.xpm", 0, 0}, {"", 2, MODC3, MODR3, MW1, MH1, 0, 1, 0, "bitmaps/buttons/rockerwhite.xpm", 0, 0}, /* diverse */ {"", 2, MODC1, MODR2, MW1, MH1, 0, 1, 0, "bitmaps/buttons/rockerblue.xpm", 0, 0}, {"", 2, MODC2, MODR2, MW1, MH1, 0, 1, 0, "bitmaps/buttons/rockerblue.xpm", 0, 0}, {"", 2, MODC5, MODR2, MW1, MH1, 0, 1, 0, "bitmaps/buttons/rockerwhite.xpm", 0, 0}, {"", 2, MODC4, MODR3, MW1, MH1, 0, 1, 0, "bitmaps/buttons/rockerred.xpm", 0, 0}, {"", 2, MODC5, MODR3, MW1, MH1, 0, 1, 0, "bitmaps/buttons/rockerred.xpm", 0, 0} }; static brightonLocations volumes[VOL_COUNT] = { {"", 0, 0, 0, 1000, 800, 0, 1, 0, 0, 0, 0}, }; #define OD1 140 #define OD2 70 #define OD3 70 #define OC1 150 #define OC2 (OC1 + OD1 + 50) #define OC3 (OC2 + OD1) #define OC4 (OC3 + OD1) #define OC5 (OC4 + OD1) #define OC6 (OC5 + OD1) #define OR1 20 #define OR2 (OR1 + OD2) #define OR3 (OR2 + OD2) #define OR4 (OR3 + OD2) #define OR5 (OR4 + 150) #define OR6 (OR5 + 200) #define OR7 (OR6 + 200) #define OS1 25 #define OS2 60 #define OS3 100 static brightonLocations opts[OPTS_COUNT] = { {"", 2, OC1, OR1, OS1, OS2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, OC1, OR2, OS1, OS2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, OC1, OR3, OS1, OS2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, OC1, OR4, OS1, OS2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, {"", 0, OC2, OR1 + 75, OS3, OS3, 0, 1, 0, 0, 0, 0}, {"", 0, OC3, OR1, OS3, OS3, 0, 1, 0, 0, 0, 0}, {"", 0, OC4, OR1, OS3, OS3, 0, 1, 0, 0, 0, 0}, {"", 0, OC5, OR1, OS3, OS3, 0, 1, 0, 0, 0, 0}, {"", 0, OC6, OR1, OS3, OS3, 0, 1, 0, 0, 0, 0}, {"", 0, OC3, OR1 + 150, OS3, OS3, 0, 1, 0, 0, 0, 0}, {"", 0, OC4, OR1 + 150, OS3, OS3, 0, 1, 0, 0, 0, 0}, {"", 0, OC5, OR1 + 150, OS3, OS3, 0, 1, 0, 0, 0, 0}, {"", 0, OC6, OR1 + 150, OS3, OS3, 0, 1, 0, 0, 0, 0}, {"", 0, OC4, OR5, OS3, OS3, 0, 1, 0, 0, 0, 0}, {"", 0, OC5, OR5, OS3, OS3, 0, 1, 0, 0, 0, 0}, {"", 0, OC6, OR5, OS3, OS3, 0, 1, 0, 0, 0, 0}, {"", 0, OC3, OR6, OS3, OS3, 0, 1, 0, 0, 0, 0}, {"", 0, OC4, OR6, OS3, OS3, 0, 1, 0, 0, 0, 0}, {"", 0, OC5, OR6, OS3, OS3, 0, 1, 0, 0, 0, 0}, {"", 0, OC6, OR6, OS3, OS3, 0, 1, 0, 0, 0, 0}, {"", 2, OC1, OR7, OS1, OS2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, OC1, OR7 + OD2, OS1, OS2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, {"", 0, OC2, OR7, OS3, OS3, 0, 7, 0, 0, 0, 0}, {"", 0, OC3, OR7, OS3, OS3, 0, 1, 0, 0, 0, 0}, {"", 0, OC4, OR7, OS3, OS3, 0, 1, 0, 0, 0, 0}, {"", 0, OC5, OR7, OS3, OS3, 0, 1, 0, 0, 0, 0}, {"", 0, OC6, OR7, OS3, OS3, 0, 1, 0, 0, 0, 0}, }; /* * This is a set of globals for the main window rendering. Again taken from * include/brighton.h */ brightonApp hammondApp = { "hammond", 0, /* no blueprint on wood background. */ "bitmaps/textures/wood2.xpm", 0, /* or BRIGHTON_STRETCH, default is tesselate */ hammondInit, hammondConfigure, /* 3 callbacks, unused? */ 0, destroySynth, {32, 0, 2, 2, 5, 520, 0, 0}, 808, 259, 0, 0, 5, /* four panels */ { { "Options", "bitmaps/blueprints/hammondopts.xpm", "bitmaps/textures/metal5.xpm", 0x020, /* flags - 0x020 withdraws */ 0, 0, hammondCallback, /*900, 700, 70, 250, */ 20, 50, 460, 900, OPTS_COUNT, opts }, { "Harmonics", "bitmaps/blueprints/hammond.xpm", "bitmaps/textures/metal6.xpm", BRIGHTON_STRETCH, /* flags */ 0, 0, hammondCallback, 20, 50, 460, 900, SLIDER_COUNT, sliders }, { "Modulations", "bitmaps/blueprints/hammondmods.xpm", "bitmaps/textures/metal6.xpm", BRIGHTON_STRETCH, /* flags */ 0, 0, hammondCallback, 500, 50, 480, 600, MOD_COUNT, mods }, { "Volume", "bitmaps/blueprints/hammondvol.xpm", 0, 0, /* flags */ 0, 0, hammondCallback, 900, 700, 70, 250, VOL_COUNT, volumes }, { "Memories", "bitmaps/blueprints/hammondmem.xpm", "bitmaps/textures/metal6.xpm", BRIGHTON_STRETCH, /* flags */ 0, 0, hammondCallback, 500, 700, 375, 250, MEM_COUNT, memories } } }; static void hammondMemory(guiSynth *synth, int fd, int chan, int c, int o, int v) { /* printf("hammondMemory(%i %i %i %i %i)\n", fd, chan, c, o, v); */ /* * radio button exception */ if (synth->dispatch[MEM_START].other2) { synth->dispatch[MEM_START].other2 = 0; return; } switch (c) { default: case 0: if (synth->dispatch[MEM_START].other2 == 0) { brightonEvent event; if (synth->dispatch[MEM_START].other1 != o) event.value = 0; else event.value = 1; synth->dispatch[MEM_START].other2 = 1; brightonParamChange(synth->win, MEM_PANEL, synth->dispatch[MEM_START].other1, &event); } synth->dispatch[MEM_START].other1 = o; synth->location = synth->location * 10 + o; if (synth->location > 1000) synth->location = o; /*printf("location is now %i\n", synth->location); */ if (loadMemory(synth, "hammond", 0, synth->location, synth->mem.active, FIRST_DEV, BRISTOL_STAT) < 0) displayPanelText(synth, "FRE", synth->location, MEM_PANEL, DISPLAY); else displayPanelText(synth, "PRG", synth->location, MEM_PANEL, DISPLAY); break; case 1: synth->flags |= MEM_LOADING; if (loadMemory(synth, "hammond", 0, synth->location, synth->mem.active, FIRST_DEV, 0) < 0) displayPanelText(synth, "FRE", synth->location, MEM_PANEL, DISPLAY); else displayPanelText(synth, "PRG", synth->location, MEM_PANEL, DISPLAY); synth->flags &= ~MEM_LOADING; /* synth->location = 0; */ break; case 2: saveMemory(synth, "hammond", 0, synth->location, FIRST_DEV); displayPanelText(synth, "PRG", synth->location, MEM_PANEL, DISPLAY); /* synth->location = 0; */ break; case 3: while (loadMemory(synth, "hammond", 0, ++synth->location, synth->mem.active, FIRST_DEV, 0) < 0) { if (synth->location > 999) synth->location = -1; } displayPanelText(synth, "PRG", synth->location, MEM_PANEL, DISPLAY); break; case 4: while (loadMemory(synth, "hammond", 0, --synth->location, synth->mem.active, FIRST_DEV, 0) < 0) { if (synth->location < 0) synth->location = 1000; } displayPanelText(synth, "PRG", synth->location, MEM_PANEL, DISPLAY); break; } } static void hammondMidi(guiSynth *synth, int fd, int chan, int c, int o, int v) { int newchan; if ((synth->flags & OPERATIONAL) == 0) return; if (c == 1) { if ((newchan = synth->midichannel - 1) < 0) { synth->midichannel = 0; return; } } else { if ((newchan = synth->midichannel + 1) >= 16) { synth->midichannel = 15; return; } } if (global.libtest == 0) bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_MIDICHANNEL|newchan); synth->midichannel = newchan; displayPanelText(synth, "MIDI", synth->midichannel + 1, MEM_PANEL, DISPLAY); } /* * For the sake of ease of use, links have been placed here to be called * by any of the devices created. They would be better in some other file, * perhaps with this as a dispatch. * * Param refers to the device index in the locations table given below. */ static int hammondCallback(brightonWindow * win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); int sendvalue; if (synth == 0) return(0); if ((synth->flags & OPERATIONAL) == 0) return(0); switch (panel) { case SLIDER_PANEL: index += SLIDER_START; break; case MOD_PANEL: index += MOD_START; break; case VOL_PANEL: index += VOL_START; break; case OPTS_PANEL: index += OPTS_START; break; case MEM_PANEL: index += MEM_START; break; } /* printf("hammondCallback(%i, %i, %f): %x\n", panel, index, value, synth); */ if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0)) return(0); if (synth->dispatch[index].controller >= DEVICE_COUNT) return(0); if (hammondApp.resources[0].devlocn[index].to == 1.0) sendvalue = value * C_RANGE_MIN_1; else sendvalue = value; synth->mem.param[index] = value; /*printf("index is now %i %i %i\n", index, DEVICE_COUNT, ACTIVE_DEVS); */ /* if ((!global.libtest) || (index >= ACTIVE_DEVS)) */ synth->dispatch[index].routine(synth, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #define DEBUG #ifdef DEBUG printf("dispatch[%p,%i](%i, %i, %i, %i, %i)\n", synth, index, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #endif return(0); } static int hammondNull() { return(0); } static void doSlider(guiSynth *synth, int fd, int chan, int cont, int op, int value) { int slidervalue; /*printf("doSlider(%x, %i, %i, %i, %i, %i)\n", */ /* synth, fd, chan, cont, op, value); */ slidervalue = cont * 8 + value; bristolMidiSendMsg(global.controlfd, synth->sid, 0, 2, slidervalue); } static void doOverdrive(guiSynth *synth) { if (synth->mem.param[MOD_START + MOD_COUNT - 1] == 0) bristolMidiSendMsg(global.controlfd, synth->sid, 100, 5, 0); else bristolMidiSendMsg(global.controlfd, synth->sid, 100, 5, (int) (synth->mem.param[OPTS_START + 9] * C_RANGE_MIN_1)); } static void doReverb(guiSynth *synth) { int revlevel = 0; /*printf("doReverb\n"); */ if (synth->mem.param[MOD_START + 9] != 0) revlevel++; if (synth->mem.param[MOD_START + 10] != 0) revlevel+=2; switch (revlevel) { default: case 0: bristolMidiSendMsg(global.controlfd, synth->sid, 100, 4, 0); break; case 1: bristolMidiSendMsg(global.controlfd, synth->sid, 100, 4, (int) (synth->mem.param[OPTS_START + 24] * C_RANGE_MIN_1)); break; case 2: bristolMidiSendMsg(global.controlfd, synth->sid, 100, 4, (int) (synth->mem.param[OPTS_START + 25] * C_RANGE_MIN_1)); break; case 3: bristolMidiSendMsg(global.controlfd, synth->sid, 100, 4, (int) (synth->mem.param[OPTS_START + 26] * C_RANGE_MIN_1)); break; } } static void doBright(guiSynth *synth) { if (synth->mem.param[MOD_START + 12] == 0) { /* * Once to the hammond manager */ bristolMidiSendMsg(global.controlfd, synth->sid, 126, 1, 0); /* * And to the sine oscillator */ bristolMidiSendMsg(global.controlfd, synth->sid, 0, 0, 0); bristolMidiSendMsg(global.controlfd, synth->sid, 0, 0, 8); bristolMidiSendMsg(global.controlfd, synth->sid, 0, 0, 16); bristolMidiSendMsg(global.controlfd, synth->sid, 0, 0, 24); bristolMidiSendMsg(global.controlfd, synth->sid, 0, 0, 32); bristolMidiSendMsg(global.controlfd, synth->sid, 0, 0, 40); bristolMidiSendMsg(global.controlfd, synth->sid, 0, 0, 48); bristolMidiSendMsg(global.controlfd, synth->sid, 0, 0, 56); bristolMidiSendMsg(global.controlfd, synth->sid, 0, 0, 64); } else { bristolMidiSendMsg(global.controlfd, synth->sid, 126, 1, (int) (synth->mem.param[OPTS_START + 22])); bristolMidiSendMsg(global.controlfd, synth->sid, 0, 0, 0 + (int) (synth->mem.param[OPTS_START + 22])); bristolMidiSendMsg(global.controlfd, synth->sid, 0, 0, 8 + (int) (synth->mem.param[OPTS_START + 22])); bristolMidiSendMsg(global.controlfd, synth->sid, 0, 0, 16 + (int) (synth->mem.param[OPTS_START + 22])); bristolMidiSendMsg(global.controlfd, synth->sid, 0, 0, 24 + (int) (synth->mem.param[OPTS_START + 22])); bristolMidiSendMsg(global.controlfd, synth->sid, 0, 0, 32 + (int) (synth->mem.param[OPTS_START + 22])); bristolMidiSendMsg(global.controlfd, synth->sid, 0, 0, 40 + (int) (synth->mem.param[OPTS_START + 22])); bristolMidiSendMsg(global.controlfd, synth->sid, 0, 0, 48 + (int) (synth->mem.param[OPTS_START + 22])); bristolMidiSendMsg(global.controlfd, synth->sid, 0, 0, 56 + (int) (synth->mem.param[OPTS_START + 22])); bristolMidiSendMsg(global.controlfd, synth->sid, 0, 0, 64 + (int) (synth->mem.param[OPTS_START + 22])); } } static void doClick(guiSynth *synth) { if (synth->mem.param[MOD_START + 11] == 0) bristolMidiSendMsg(global.controlfd, synth->sid, 0, 6, 0); else bristolMidiSendMsg(global.controlfd, synth->sid, 0, 6, (int) (synth->mem.param[OPTS_START + 23] * C_RANGE_MIN_1)); } static void doCompress(guiSynth *synth) { if (synth->mem.param[OPTS_START + 21] == 0) { bristolMidiSendMsg(global.controlfd, synth->sid, 126, 2, 0); } else { bristolMidiSendMsg(global.controlfd, synth->sid, 126, 2, 1); } } static void doPreacher(guiSynth *synth) { if (synth->mem.param[OPTS_START + 20] == 0) { bristolMidiSendMsg(global.controlfd, synth->sid, 126, 3, 0); bristolMidiSendMsg(global.controlfd, synth->sid, 0, 7, 0); } else { bristolMidiSendMsg(global.controlfd, synth->sid, 126, 3, 1); bristolMidiSendMsg(global.controlfd, synth->sid, 0, 7, 1); } } static void doGrooming(guiSynth *synth) { if (synth->mem.param[MOD_START + 7] != 0) bristolMidiSendMsg(global.controlfd, synth->sid, 1, 0, (int) (synth->mem.param[OPTS_START + 18] * C_RANGE_MIN_1)); else bristolMidiSendMsg(global.controlfd, synth->sid, 1, 0, (int) (synth->mem.param[OPTS_START + 19] * C_RANGE_MIN_1)); } static void doPerc(guiSynth *synth) { if (synth->mem.param[MOD_START + 5] == 0) bristolMidiSendMsg(global.controlfd, synth->sid, 0, 3, 24); else bristolMidiSendMsg(global.controlfd, synth->sid, 0, 3, 25); if (synth->mem.param[MOD_START + 6] == 0) bristolMidiSendMsg(global.controlfd, synth->sid, 0, 3, 32); else bristolMidiSendMsg(global.controlfd, synth->sid, 0, 3, 33); if (synth->mem.param[MOD_START + 8] == 0) bristolMidiSendMsg(global.controlfd, synth->sid, 4, 1, (int) (synth->mem.param[OPTS_START + 16] * C_RANGE_MIN_1)); else bristolMidiSendMsg(global.controlfd, synth->sid, 4, 1, (int) (synth->mem.param[OPTS_START + 17] * C_RANGE_MIN_1)); } static void doVibra(guiSynth *synth) { if (synth->mem.param[MOD_START + 3] == 0) { bristolMidiSendMsg(global.controlfd, synth->sid, 126, 0, 0); return; } bristolMidiSendMsg(global.controlfd, synth->sid, 126, 0, 1); if (synth->mem.param[MOD_START + 4] == 0) bristolMidiSendMsg(global.controlfd, synth->sid, 6, 2, 0); else bristolMidiSendMsg(global.controlfd, synth->sid, 6, 2, 1); switch ((int) synth->mem.param[MOD_START + 2]) { case 0: default: bristolMidiSendMsg(global.controlfd, synth->sid, 6, 0, (int) ((1 - synth->mem.param[OPTS_START + 13]) * C_RANGE_MIN_1)); bristolMidiSendMsg(global.controlfd, synth->sid, 6, 1, (int) ((1 - synth->mem.param[OPTS_START + 13]) * C_RANGE_MIN_1)); break; case 1: bristolMidiSendMsg(global.controlfd, synth->sid, 6, 0, (int) ((1 - synth->mem.param[OPTS_START + 14]) * C_RANGE_MIN_1)); bristolMidiSendMsg(global.controlfd, synth->sid, 6, 1, (int) ((1 - synth->mem.param[OPTS_START + 14]) * C_RANGE_MIN_1)); break; case 2: bristolMidiSendMsg(global.controlfd, synth->sid, 6, 0, (int) ((1 - synth->mem.param[OPTS_START + 15]) * C_RANGE_MIN_1)); bristolMidiSendMsg(global.controlfd, synth->sid, 6, 1, (int) ((1 - synth->mem.param[OPTS_START + 14]) * C_RANGE_MIN_1)); break; } } static void doVolume(guiSynth *synth) { bristolMidiSendMsg(global.controlfd, synth->sid, 0, 4, (int) (synth->mem.param[VOL_START] * C_RANGE_MIN_1)); } static void doLeslieSpeed(guiSynth *synth) { int speed, depth, phase; if (synth->mem.param[MOD_START] == 0) { bristolMidiSendMsg(global.controlfd, synth->sid, 100, 7, 0); return; } bristolMidiSendMsg(global.controlfd, synth->sid, 100, 7, (int) (synth->dispatch[OPTS_START + 1].other1)); if (synth->mem.param[MOD_START + 1] != 0) { speed = synth->mem.param[OPTS_START + 6] * C_RANGE_MIN_1; depth = synth->mem.param[OPTS_START + 7] * C_RANGE_MIN_1; phase = synth->mem.param[OPTS_START + 8] * C_RANGE_MIN_1; } else { speed = synth->mem.param[OPTS_START + 10] * C_RANGE_MIN_1; depth = synth->mem.param[OPTS_START + 11] * C_RANGE_MIN_1; phase = synth->mem.param[OPTS_START + 12] * C_RANGE_MIN_1; } bristolMidiSendMsg(global.controlfd, synth->sid, 100, 0, speed); bristolMidiSendMsg(global.controlfd, synth->sid, 100, 3, depth); bristolMidiSendMsg(global.controlfd, synth->sid, 100, 2, phase); bristolMidiSendMsg(global.controlfd, synth->sid, 100, 6, (int) (synth->mem.param[OPTS_START + 4] * C_RANGE_MIN_1)); bristolMidiSendMsg(global.controlfd, synth->sid, 100, 1, (int) (synth->mem.param[OPTS_START + 5] * C_RANGE_MIN_1)); } static void hammondPanelSwitch(guiSynth *id, int fd, int chan, int cont, int op, int value) { brightonEvent event; /* printf("hammondPanelSwitch(%x, %i, %i, %i, %i, %i)\n", */ /* id, fd, chan, cont, op, value); */ /* * If the sendvalue is zero, then withdraw the opts window, draw the * slider window, and vice versa. */ if (value == 0) { event.type = BRIGHTON_EXPOSE; event.intvalue = 0; brightonParamChange(id->win, OPTS_PANEL, -1, &event); event.intvalue = 1; brightonParamChange(id->win, SLIDER_PANEL, -1, &event); } else { event.type = BRIGHTON_EXPOSE; event.intvalue = 0; brightonParamChange(id->win, SLIDER_PANEL, -1, &event); event.intvalue = 1; brightonParamChange(id->win, OPTS_PANEL, -1, &event); } } static void hammondOption(guiSynth *synth, int fd, int chan, int cont, int op, int value) { brightonEvent event; /*printf("hammondOption(%x, %i, %i, %i, %i, %i)\n", */ /* synth, fd, chan, cont, op, value); */ switch (cont) { case OPTS_START: /* * Rotation type. Send 100.7 becomes op; */ if ((synth->flags & MEM_LOADING) == 0) { if (synth->dispatch[OPTS_START].other2) { synth->dispatch[OPTS_START].other2 = 0; return; } synth->dispatch[OPTS_START].other2 = 1; if (synth->dispatch[OPTS_START].other1 >= 0) { event.command = BRIGHTON_PARAMCHANGE; if (synth->dispatch[OPTS_START].other1 != (op - 1)) event.value = 0; else event.value = 1; brightonParamChange(synth->win, OPTS_PANEL, synth->dispatch[OPTS_START].other1, &event); } } if (synth->mem.param[OPTS_START + op - 1] != 0) { synth->dispatch[OPTS_START].other1 = op - 1; synth->dispatch[OPTS_START + 1].other1 = op; if (synth->mem.param[MOD_START] == 0) bristolMidiSendMsg(global.controlfd, chan, 100, 7, 0); else { bristolMidiSendMsg(global.controlfd, chan, 100, 7, op); bristolMidiSendMsg(global.controlfd, chan, 100, 1, (int) (synth->mem.param[OPTS_START + 5] * C_RANGE_MIN_1)); } } break; case OPTS_START + 3: /* * Rotor break. Send 100.7 = 4 off, 100.7 = 5 on. */ if (value == 0) bristolMidiSendMsg(global.controlfd, chan, 100, 7, 4); else bristolMidiSendMsg(global.controlfd, chan, 100, 7, 5); break; case OPTS_START + 4: case OPTS_START + 5: case OPTS_START + 6: case OPTS_START + 7: case OPTS_START + 8: case OPTS_START + 10: case OPTS_START + 11: case OPTS_START + 12: doLeslieSpeed(synth); break; case OPTS_START + 9: /* overdrive */ doOverdrive(synth); break; case OPTS_START + 13: case OPTS_START + 14: case OPTS_START + 15: doVibra(synth); break; case OPTS_START + 16: case OPTS_START + 17: doPerc(synth); break; case OPTS_START + 18: case OPTS_START + 19: doGrooming(synth); break; case OPTS_START + 20: doPreacher(synth); break; case OPTS_START + 21: doCompress(synth); break; case OPTS_START + 22: doBright(synth); break; case OPTS_START + 23: doClick(synth); break; case OPTS_START + 24: case OPTS_START + 25: case OPTS_START + 26: doReverb(synth); break; default: break; } } /* * Any location initialisation required to run the callbacks. For bristol, this * will connect to the engine, and give it some base parameters. * May need to generate some application specific menus. * Will also then make specific requests to some of the devices to alter their * rendering. */ static int hammondInit(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); dispatcher *dispatch; int i; if (synth == 0) { synth = findSynth(global.synths, 0); if (synth == 0) { printf("cannot init\n"); return(0); } } synth->win = win; printf("Initialise the hammond link to bristol: %p\n", synth->win); synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float)); synth->mem.count = DEVICE_COUNT; synth->mem.active = ACTIVE_DEVS; synth->dispatch = (dispatcher *) brightonmalloc(DEVICE_COUNT * sizeof(dispatcher)); dispatch = synth->dispatch; /* * We really want to have three connection mechanisms. These should be * 1. Unix named sockets. * 2. UDP sockets. * 3. MIDI pipe. */ if (!global.libtest) if ((synth->sid = initConnection(&global, synth)) < 0) return(-1); for (i = 0; i < DEVICE_COUNT; i++) synth->dispatch[i].routine = hammondNull; /*hammondMidiSendMsg; */ /* dispatch[FIRST_DEV + 0].controller = 10; dispatch[FIRST_DEV + 0].operator = 0; dispatch[FIRST_DEV + 1].controller = 9; dispatch[FIRST_DEV + 1].operator = 0; dispatch[FIRST_DEV + 2].controller = 11; dispatch[FIRST_DEV + 2].operator = 1; */ dispatch[OPTS_START].routine = (synthRoutine) hammondOption; dispatch[OPTS_START].controller = OPTS_START; dispatch[OPTS_START].operator = 1; dispatch[OPTS_START + 1].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 1].controller = OPTS_START; dispatch[OPTS_START + 1].operator = 2; dispatch[OPTS_START + 2].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 2].controller = OPTS_START; dispatch[OPTS_START + 2].operator = 3; dispatch[OPTS_START].other1 = -1; dispatch[OPTS_START].other2 = 0; dispatch[OPTS_START + 3].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 3].controller = OPTS_START + 3; dispatch[OPTS_START + 4].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 4].controller = OPTS_START + 4; dispatch[OPTS_START + 5].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 5].controller = OPTS_START + 5; dispatch[OPTS_START + 6].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 6].controller = OPTS_START + 6; dispatch[OPTS_START + 7].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 7].controller = OPTS_START + 7; dispatch[OPTS_START + 8].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 8].controller = OPTS_START + 8; dispatch[OPTS_START + 9].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 9].controller = OPTS_START + 9; dispatch[OPTS_START + 10].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 10].controller = OPTS_START + 10; dispatch[OPTS_START + 11].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 11].controller = OPTS_START + 11; dispatch[OPTS_START + 12].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 12].controller = OPTS_START + 12; /* vibra */ dispatch[OPTS_START + 13].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 13].controller = OPTS_START + 13; dispatch[OPTS_START + 14].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 14].controller = OPTS_START + 14; dispatch[OPTS_START + 15].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 15].controller = OPTS_START + 15; dispatch[OPTS_START + 16].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 16].controller = OPTS_START + 16; dispatch[OPTS_START + 17].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 17].controller = OPTS_START + 17; dispatch[OPTS_START + 18].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 18].controller = OPTS_START + 18; dispatch[OPTS_START + 19].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 19].controller = OPTS_START + 19; /* preacher */ dispatch[OPTS_START + 20].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 20].controller = OPTS_START + 20; dispatch[OPTS_START + 21].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 21].controller = OPTS_START + 21; dispatch[OPTS_START + 22].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 22].controller = OPTS_START + 22; dispatch[OPTS_START + 23].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 23].controller = OPTS_START + 23; /* reverb */ dispatch[OPTS_START + 24].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 24].controller = OPTS_START + 24; dispatch[OPTS_START + 25].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 25].controller = OPTS_START + 25; dispatch[OPTS_START + 26].routine = (synthRoutine) hammondOption; dispatch[OPTS_START + 26].controller = OPTS_START + 26; /* Memory/Midi buttons */ dispatch[MEM_START + 10].routine = (synthRoutine) hammondPanelSwitch; dispatch[MEM_START + 10].controller = MEM_COUNT; dispatch[MEM_START + 10].operator = 0; /* * These are for the memory radio buttons */ dispatch[MEM_START].other1 = 0; dispatch[MEM_START].other2 = 0; dispatch[MEM_START].operator = 0; dispatch[MEM_START + 1].operator = 1; dispatch[MEM_START + 2].operator = 2; dispatch[MEM_START + 3].operator = 3; dispatch[MEM_START + 4].operator = 4; dispatch[MEM_START + 5].operator = 5; dispatch[MEM_START + 6].operator = 6; dispatch[MEM_START + 7].operator = 7; dispatch[MEM_START + 8].operator = 8; dispatch[MEM_START + 9].operator = 9; dispatch[MEM_START].routine = dispatch[MEM_START + 1].routine = dispatch[MEM_START + 2].routine = dispatch[MEM_START + 3].routine = dispatch[MEM_START + 4].routine = dispatch[MEM_START + 5].routine = dispatch[MEM_START + 6].routine = dispatch[MEM_START + 7].routine = dispatch[MEM_START + 8].routine = dispatch[MEM_START + 9].routine = (synthRoutine) hammondMemory; /* * Mem load and save */ dispatch[MEM_START + 13].controller = 1; dispatch[MEM_START + 14].controller = 2; dispatch[MEM_START + 15].controller = 3; dispatch[MEM_START + 16].controller = 4; dispatch[MEM_START + 13].routine = dispatch[MEM_START + 14].routine = dispatch[MEM_START + 15].routine = dispatch[MEM_START + 16].routine = (synthRoutine) hammondMemory; /* * Midi up/down */ dispatch[MEM_START + 11].controller = 2; dispatch[MEM_START + 12].controller = 1; dispatch[MEM_START + 11].routine = dispatch[MEM_START + 12].routine = (synthRoutine) hammondMidi; /* * Then we do the mods, starting with leslie */ dispatch[MOD_START].routine = (synthRoutine) doLeslieSpeed; dispatch[MOD_START + 1].routine = (synthRoutine) doLeslieSpeed; dispatch[MOD_START + 2].routine = (synthRoutine) doVibra; dispatch[MOD_START + 3].routine = (synthRoutine) doVibra; dispatch[MOD_START + 4].routine = (synthRoutine) doVibra; /* Perc */ dispatch[MOD_START + 5].routine = (synthRoutine) doPerc; dispatch[MOD_START + 6].routine = (synthRoutine) doPerc; dispatch[MOD_START + 8].routine = (synthRoutine) doPerc; /* grooming */ dispatch[MOD_START + 7].routine = (synthRoutine) doGrooming; /* reverb */ dispatch[MOD_START + 9].routine = (synthRoutine) doReverb; dispatch[MOD_START + 10].routine = (synthRoutine) doReverb; dispatch[MOD_START + 11].routine = (synthRoutine) doClick; dispatch[MOD_START + 12].routine = (synthRoutine) doBright; dispatch[MOD_START + 13].routine = (synthRoutine) doOverdrive; dispatch[VOL_START].routine = (synthRoutine) doVolume; dispatch[SLIDER_START].routine = dispatch[SLIDER_START + 1].routine = dispatch[SLIDER_START + 2].routine = dispatch[SLIDER_START + 3].routine = dispatch[SLIDER_START + 4].routine = dispatch[SLIDER_START + 5].routine = dispatch[SLIDER_START + 6].routine = dispatch[SLIDER_START + 7].routine = dispatch[SLIDER_START + 8].routine = (synthRoutine) doSlider; dispatch[SLIDER_START].controller = 0; dispatch[SLIDER_START + 1].controller = 1; dispatch[SLIDER_START + 2].controller = 2; dispatch[SLIDER_START + 3].controller = 3; dispatch[SLIDER_START + 4].controller = 4; dispatch[SLIDER_START + 5].controller = 5; dispatch[SLIDER_START + 6].controller = 6; dispatch[SLIDER_START + 7].controller = 7; dispatch[SLIDER_START + 8].controller = 8; bristolMidiSendMsg(global.controlfd, synth->sid, 1, 0, 2); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 1, 3); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 2, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 3, 10); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 4, 13000); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 5, 0); bristolMidiSendMsg(global.controlfd, synth->sid, 12, 7, 1); bristolMidiSendMsg(global.controlfd, synth->sid, 10, 0, 4); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 0, 0); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 1, 10); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 2, 13000); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 3, 20); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 4, 13000); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 5, 0); bristolMidiSendMsg(global.controlfd, synth->sid, 4, 0, 2); bristolMidiSendMsg(global.controlfd, synth->sid, 4, 1, 1200); bristolMidiSendMsg(global.controlfd, synth->sid, 4, 2, 0); bristolMidiSendMsg(global.controlfd, synth->sid, 4, 3, 20); bristolMidiSendMsg(global.controlfd, synth->sid, 4, 4, 13000); bristolMidiSendMsg(global.controlfd, synth->sid, 4, 5, 0); return(0); } /* * This will be called to make any routine specific parameters available. */ static int hammondConfigure(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); if (synth == 0) { printf("problems going operational\n"); return(-1); } synth->keypanel = synth->keypanel2 = -1; if (synth->flags & OPERATIONAL) return(0); synth->flags |= OPERATIONAL; loadMemory(synth, "hammond", 0, synth->location, synth->mem.active, FIRST_DEV, 0); configureGlobals(synth); return(0); } bristol-0.60.11/brighton/brightonVox.c0000644000175000017500000004636211746476475014607 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include #include "brighton.h" #include "brightonMini.h" #include "brightoninternals.h" static int voxInit(); static int voxConfigure(); static int voxCallback(brightonWindow *, int, int, float); static int midiCallback(brightonWindow *, int, int, float); extern guimain global; #include "brightonKeys.h" #define OPTS_PANEL 0 #define MOD_PANEL 1 #define MEM_PANEL 2 #define KEY_PANEL 3 #define FIRST_DEV 0 #define MOD_COUNT 8 #define OPTS_COUNT 4 #define MEM_COUNT 17 #define OPTS_START 0 #define MOD_START OPTS_COUNT #define MEM_START (MOD_COUNT + MOD_START) #define ACTIVE_DEVS (OPTS_COUNT + 7 + FIRST_DEV) #define DEVICE_COUNT (MOD_COUNT + OPTS_COUNT + MEM_COUNT) #define DISPLAY_DEV (DEVICE_COUNT - 1) #define MEM_MGT ACTIVE_DEVS #define MIDI_MGT (MEM_MGT + 12) /* * This structure is for device definition. The structure is defined in * include/brighton.h, further definitions in brighton/brightonDevtable.h and * include/brightoninternals.h * * typedef int (*brightonCallback)(int, float); * typedef struct BrightonLocations { * int device; 0=rotary, 1=scale, etc. * float relx, rely; relative position with regards to 1000 by 1000 window * float relw, relh; relative height. * int from, to; * brightonCallback callback; specific to this dev * char *image; bitmap. If zero take a device default. * int flags; * } brightonLocations; * * This example is for a voxBristol type synth interface. */ #define R1 0 #define W1 100 #define L1 600 #define C1 40 #define C2 190 #define C3 340 #define C4 490 #define C5 700 #define C6 850 static brightonLocations locations[DEVICE_COUNT] = { {"Drawbar 16", 1, C1, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondwhite.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, {"Drawbar 8", 1, C2, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondwhite.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, {"Drawbar 4", 1, C3, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondwhite.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, {"Drawbar IV", 1, C4, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondwhite.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, {"Drawbar Sine", 1, C5, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondbrown.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, {"Drawbar Ramp", 1, C6, R1, W1, L1, 0, 8, 0, "bitmaps/knobs/hammondbrown.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE}, {"Opts", 2, 650, 775, 75, 200, 0, 1, 0, "bitmaps/buttons/rockerwhite.xpm", 0, BRIGHTON_VERTICAL}, {"Vibrato", 2, 250, 775, 75, 200, 0, 1, 0, "bitmaps/buttons/rockerwhite.xpm", 0, BRIGHTON_VERTICAL}, }; #define S1 200 static brightonLocations options[OPTS_COUNT] = { {"", 0, 500, 100, S1, S1, 0, 1, 0, 0, 0, 0}, {"", 0, 200, 500, S1, S1, 0, 1, 0, 0, 0, 0}, {"", 0, 500, 500, S1, S1, 0, 1, 0, 0, 0, 0}, {"", 2, 800, 500, 75, 200, 0, 1, 0, "bitmaps/buttons/rockerwhite.xpm", 0, BRIGHTON_VERTICAL}, }; #define mR1 100 #define mR2 300 #define mR3 550 #define mR4 800 #define mC1 100 #define mC2 293 #define mC3 486 #define mC4 679 #define mC5 875 #define mC11 100 #define mC12 255 #define mC13 410 #define mC14 565 #define mC15 720 #define mC16 874 #define S4 80 #define S5 150 brightonLocations mem[MEM_COUNT] = { /* memories */ {"", 2, mC1, mR3, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, mC2, mR3, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, mC3, mR3, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, mC4, mR3, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, mC5, mR3, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, mC1, mR4, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, mC2, mR4, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, mC3, mR4, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, mC4, mR4, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, mC5, mR4, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* mem U/D, midi U/D, Load + Save */ {"", 2, mC11, mR2, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, mC12, mR2, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, mC13, mR2, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoffo.xpm", "bitmaps/buttons/pressono.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, mC14, mR2, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, mC15, mR2, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, mC16, mR2, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, /* display */ {"", 3, mC1, mR1, 875, 125, 0, 1, 0, 0, 0, 0}, }; /* * Should try and make this one as generic as possible, and try to use it as * a general memory routine. has Midi u/d, mem u/d, load/save and a display. */ int memCallback(brightonWindow* win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); int i, memindex = 0; /* printf("memCallback(%i, %i, %f) %i, %s\n", panel, index, value, */ /* synth->mem.active, synth->resources->name); */ if (synth->flags & SUPPRESS) return(0); /* * We need to convert the index into an offset into the mem structure. * To do this we make a simple parse of the panels preceeding this panel. */ for (i = 0; i < panel; i++) memindex += synth->resources->resources[i].ndevices; /* printf("memindex is %i\n", memindex); */ /* * The first ten buttons are exclusive highlighting, we use the first mem * pointer to handle this. */ if (synth->dispatch[memindex].other2) { synth->dispatch[memindex].other2 = 0; return(0); } if (index < 10) { brightonEvent event; /* * This is a numeric. We need to force exclusion. */ if (synth->dispatch[memindex].other1 != -1) { synth->dispatch[memindex].other2 = 1; if (synth->dispatch[memindex].other1 != index) event.value = 0; else event.value = 1; brightonParamChange(synth->win, panel, synth->dispatch[memindex].other1, &event); } synth->dispatch[memindex].other1 = index; if ((synth->location = synth->location * 10 + index) >= 1000) synth->location = index; if (loadMemory(synth, synth->resources->name, 0, synth->location, synth->mem.active, FIRST_DEV, BRISTOL_STAT) < 0) displayPanelText(synth, "FREE", synth->location, panel, MEM_COUNT - 1); else displayPanelText(synth, "PROG", synth->location, panel, MEM_COUNT - 1); } else { int newchan; /* * This is a control button. */ switch(index) { case 10: /* * Midi Down */ if ((newchan = synth->midichannel - 1) < 0) { synth->midichannel = 0; return(0); } bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_MIDICHANNEL|newchan); synth->midichannel = newchan; displayPanelText(synth, "MIDI", synth->midichannel + 1, panel, MEM_COUNT - 1); break; case 11: /* * Midi Up */ if ((newchan = synth->midichannel + 1) > 15) { synth->midichannel = 15; return(0); } bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_MIDICHANNEL|newchan); synth->midichannel = newchan; displayPanelText(synth, "MIDI", synth->midichannel + 1, panel, MEM_COUNT - 1); break; case 12: /* * Save */ saveMemory(synth, synth->resources->name, 0, synth->location, FIRST_DEV); displayPanelText(synth, "PROG", synth->location, panel, MEM_COUNT - 1); break; case 13: default: /* * Load */ synth->flags |= MEM_LOADING; loadMemory(synth, synth->resources->name, 0, synth->location, synth->mem.active, FIRST_DEV, 0); synth->flags &= ~MEM_LOADING; displayPanelText(synth, "PROG", synth->location, panel, MEM_COUNT - 1); break; case 14: /* * Mem Down - these are going to be seek routines - find the * next programmed memory. */ if (--synth->location < 0) synth->location = 999; synth->flags |= MEM_LOADING; while (loadMemory(synth, synth->resources->name, 0, synth->location, synth->mem.active, FIRST_DEV, 0) < 0) { if (--synth->location < 0) synth->location = 999; } synth->flags &= ~MEM_LOADING; displayPanelText(synth, "PROG", synth->location, panel, MEM_COUNT - 1); break; case 15: /* * Mem Up - seek routine, find next programmed memory. */ if (++synth->location >= 1000) synth->location = 0; synth->flags |= MEM_LOADING; while (loadMemory(synth, synth->resources->name, 0, synth->location, synth->mem.active, FIRST_DEV, 0) < 0) { if (++synth->location >= 1000) synth->location = 0; } synth->flags &= ~MEM_LOADING; displayPanelText(synth, "PROG", synth->location, panel, MEM_COUNT - 1); break; } } return(0); } /* * This is a set of globals for the main window rendering. Again taken from * include/brighton.h */ brightonApp voxApp = { "vox", 0, /* no blueprint on wood background. */ "bitmaps/textures/leather.xpm", 0, voxInit, voxConfigure, /* 3 callbacks */ midiCallback, destroySynth, {-1, 0, 2, 2, 5, 520, 0, 1}, 550, 250, 0, 0, 7, /* panel count */ { { "Opts", "bitmaps/blueprints/voxopts.xpm", "bitmaps/textures/metal5.xpm", /* flags */ 0x020, 0, 0, voxCallback, 19, 40, 500, 570, OPTS_COUNT, options }, { "Mods", "bitmaps/blueprints/vox.xpm", "bitmaps/textures/metal6.xpm", /* flags */ BRIGHTON_STRETCH, 0, 0, voxCallback, 15, 662, 150, 310, MOD_COUNT, locations }, { "Mem", "bitmaps/blueprints/genmem.xpm", "bitmaps/textures/metal5.xpm", /* flags */ 0x020, 0, 0, memCallback, 519, 40, 462, 570, MEM_COUNT, mem }, { "Keyboard", 0, "bitmaps/keys/vkbg.xpm", /* flags */ 0x020|BRIGHTON_STRETCH, 0, 0, keyCallback, 200, 662, 780, 305, VKEY_COUNT, vkeys }, { "Vox", 0, "bitmaps/textures/redleather.xpm", 0, /* flags */ 0, 0, 0, /*15, 600, 970, 50, */ 15, 35, 970, 625, 0, 0 }, { "Vox", 0, "bitmaps/textures/orangeleather.xpm", 0, /* flags */ 0, 0, 0, 19, 40, 962, 570, 0, 0 }, { "backing", 0, "bitmaps/textures/metal5.xpm", /* flags */ BRIGHTON_STRETCH, 0, 0, 0, 170, 662, 30, 305, 0, 0 }, } }; /*static dispatcher dispatch[DEVICE_COUNT]; */ static int midiCallback(brightonWindow *win, int controller, int value, float n) { guiSynth *synth = findSynth(global.synths, win); printf("midi callback: %x, %i\n", controller, value); switch(controller) { case MIDI_PROGRAM: printf("midi program: %x, %i\n", controller, value); synth->location = value; loadMemory(synth, synth->resources->name, 0, synth->bank + synth->location, synth->mem.active, FIRST_DEV, 0); break; case MIDI_BANK_SELECT: printf("midi banksel: %x, %i\n", controller, value); synth->bank = value; break; } return(0); } static int voxMidiSendMsg(void *synth, int fd, int chan, int c, int o, int v) { /* printf("%i, %i, %i\n", c, o, v); */ bristolMidiSendMsg(fd, chan, c, o, v); return(0); } /* * For the sake of ease of use, links have been placed here to be called * by any of the devices created. They would be better in some other file, * perhaps with this as a dispatch. * * Param refers to the device index in the locations table given below. */ static int voxCallback(brightonWindow *win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); int sendvalue; /* printf("voxCallback(%i, %i, %f): %x\n", panel, index, value, synth); */ if (synth == 0) return(0); if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0)) return(0); if (voxApp.resources[panel].devlocn[index].to == 1) sendvalue = value * C_RANGE_MIN_1; else sendvalue = value; switch (panel) { case OPTS_PANEL: index += OPTS_START; break; case MOD_PANEL: index += MOD_START; break; case MEM_PANEL: index += MEM_START; break; } /* printf("index is now %i\n", index); */ synth->mem.param[index] = value; if ((!global.libtest) || (index >= ACTIVE_DEVS)) synth->dispatch[index].routine(synth, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #define DEBUG #ifdef DEBUG else printf("dispatch[%p,%i](%i, %i, %i, %i, %i)\n", synth, index, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #endif return(0); } static void voxDrawbar(guiSynth *synth, int fd, int chan, int cont, int op, int value) { int slidervalue; /* printf("voxDrawbar(%x, %i, %i, %i, %i, %i)\n", (size_t) synth, fd, chan, cont, op, value); */ slidervalue = cont * 16 + value; bristolMidiSendMsg(global.controlfd, synth->sid, 0, 0, slidervalue); } static void panelSwitch(guiSynth *id, int fd, int chan, int cont, int op, int value) { brightonEvent event; /* * If the sendvalue is zero, then withdraw the opts window, draw the * slider window, and vice versa. */ if (value == 0) { event.type = BRIGHTON_EXPOSE; event.intvalue = 0; brightonParamChange(id->win, 0, -1, &event); event.intvalue = 0; brightonParamChange(id->win, 2, -1, &event); event.intvalue = 1; brightonParamChange(id->win, 5, -1, &event); } else { event.type = BRIGHTON_EXPOSE; event.intvalue = 0; brightonParamChange(id->win, 5, -1, &event); event.intvalue = 1; brightonParamChange(id->win, 0, -1, &event); event.intvalue = 1; brightonParamChange(id->win, 2, -1, &event); } } static void voxVolume(guiSynth *id, int fd, int chan, int cont, int op, int value) { /* printf("voxVolume\n"); */ bristolMidiSendMsg(global.controlfd, chan, 0, 1, value); } static void voxOption(guiSynth *synth, int fd, int chan, int cont, int op, int value) { /* printf("voxOption(%i, %i, %i)\n", cont, op, value); */ bristolMidiSendMsg(global.controlfd, synth->sid, 1, cont, value); } /* * Any location initialisation required to run the callbacks. For bristol, this * will connect to the engine, and give it some base parameters. * May need to generate some application specific menus. * Will also then make specific requests to some of the devices to alter their * rendering. */ static int voxInit(brightonWindow* win) { guiSynth *synth = findSynth(global.synths, win); dispatcher *dispatch; int i; if (synth == 0) { synth = findSynth(global.synths, 0); if (synth == 0) { printf("cannot init\n"); return(0); } } synth->win = win; printf("Initialise the vox link to bristol: %p\n", synth->win); synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float)); synth->mem.count = DEVICE_COUNT; synth->mem.active = ACTIVE_DEVS; synth->dispatch = (dispatcher *) brightonmalloc(DEVICE_COUNT * sizeof(dispatcher)); dispatch = synth->dispatch; /* * We really want to have three connection mechanisms. These should be * 1. Unix named sockets. * 2. UDP sockets. * 3. MIDI pipe. */ if (!global.libtest) if ((synth->sid = initConnection(&global, synth)) < 0) return(-1); for (i = 0; i < DEVICE_COUNT; i++) synth->dispatch[i].routine = voxMidiSendMsg; /* * First parameter are for the single oscillator. This should pass through * an encaps operator. * * We have 16', 8', 4' pipes, one "IV" composite, flute (sine) and reed * (saw) waves. */ synth->dispatch[OPTS_START + 0].routine = (synthRoutine) voxVolume; synth->dispatch[OPTS_START + 1].routine = synth->dispatch[OPTS_START + 2].routine = (synthRoutine) voxOption; synth->dispatch[OPTS_START + 1].controller = 0; synth->dispatch[OPTS_START + 2].controller = 1; synth->dispatch[OPTS_START + 3].controller = 0; synth->dispatch[OPTS_START + 3].operator = 5; synth->dispatch[MOD_START + 0].routine = synth->dispatch[MOD_START + 1].routine = synth->dispatch[MOD_START + 2].routine = synth->dispatch[MOD_START + 3].routine = synth->dispatch[MOD_START + 4].routine = synth->dispatch[MOD_START + 5].routine = (synthRoutine) voxDrawbar; synth->dispatch[MOD_START + 0].operator = 0; synth->dispatch[MOD_START + 0].controller = 0; synth->dispatch[MOD_START + 1].operator = 0; synth->dispatch[MOD_START + 1].controller = 1; synth->dispatch[MOD_START + 2].operator = 0; synth->dispatch[MOD_START + 2].controller = 2; synth->dispatch[MOD_START + 3].operator = 0; synth->dispatch[MOD_START + 3].controller = 3; synth->dispatch[MOD_START + 4].operator = 0; synth->dispatch[MOD_START + 4].controller = 4; synth->dispatch[MOD_START + 5].operator = 0; synth->dispatch[MOD_START + 5].controller = 5; /* * And one parameter for vibrato. This also needs to be a composite of * a few parameters? Er, no, we just need to initialise the vibra values to * vibra only, and a speed. This is just an on/off switch for the vibra */ synth->dispatch[MOD_START + 6].operator = 0; synth->dispatch[MOD_START + 6].controller = 126; /* * Panel switcher. */ synth->dispatch[MOD_START + 7].routine = (synthRoutine) panelSwitch; /* * These will be replaced by some opts controllers. */ bristolMidiSendMsg(global.controlfd, synth->sid, 1, 0, 550); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 1, 1600); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 2, 0); return(0); } /* * This will be called to make any routine specific parameters available. */ static int voxConfigure(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); brightonEvent event; if (synth == 0) { printf("problems going operational\n"); return(-1); } if (synth->flags & OPERATIONAL) return(0); printf("going operational\n"); synth->flags |= OPERATIONAL; synth->keypanel = 3; synth->keypanel2 = -1; synth->transpose = 36; loadMemory(synth, "vox", 0, synth->location, synth->mem.active, FIRST_DEV, 0); displayPanelText(synth, "PROG", synth->location, MEM_PANEL, MEM_COUNT - 1); /* * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only * occurs on first paint, so we suppress the first paint, and then request * an expose here. */ event.type = BRIGHTON_EXPOSE; event.intvalue = 1; brightonParamChange(synth->win, KEY_PANEL, -1, &event); configureGlobals(synth); return(0); } bristol-0.60.11/brighton/brightonAxxe.c0000644000175000017500000007516111746476475014737 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* ARP Axxe */ #include #include "brighton.h" #include "brightonMini.h" #include "brightoninternals.h" static int initmem; static int axxeInit(); static int axxeConfigure(); static int axxeCallback(brightonWindow *, int, int, float); /*static int keyCallback(void *, int, int, float); */ static int midiCallback(brightonWindow *, int, int, float); extern guimain global; #include "brightonKeys.h" #define DEVICE_COUNT 50 #define ACTIVE_DEVS 30 #define MEM_START (ACTIVE_DEVS) #define MIDI_START (MEM_START + 18) #define RADIOSET_1 MEM_START #define RADIOSET_2 (MEM_START + 1) #define KEY_PANEL 1 #define CDIFF 32 #define CDIFF2 12 #define PC0 118 #define PC1 (PC0 + CDIFF) #define PC2 (PC1 + CDIFF) #define PC3 (PC2 + CDIFF) #define PC4 (PC3 + CDIFF) #define PC5 (PC4 + CDIFF) #define PC6 (PC5 + CDIFF + CDIFF2) #define PC7 (PC6 + CDIFF) #define PC8 (PC7 + CDIFF) #define PC9 (PC8 + CDIFF + CDIFF2) #define PC10 (PC9 + CDIFF + CDIFF2) #define PC11 (PC10 + CDIFF) #define PC12 (PC11 + CDIFF) #define PC13 (PC12 + CDIFF + CDIFF2) #define PC14 (PC13 + CDIFF) #define PC15 (PC14 + CDIFF + CDIFF2) #define PC16 (PC15 + CDIFF) #define PC17 (PC16 + CDIFF) #define PC18 (PC17 + CDIFF + CDIFF2) #define PC19 (PC18 + CDIFF) #define PC20 (PC19 + CDIFF + CDIFF2) #define PC21 (PC20 + CDIFF) #define PC22 (PC21 + CDIFF) #define PC23 (PC22 + CDIFF) #define C0 126 #define C1 (C0 + CDIFF) #define C2 (C1 + CDIFF) #define C3 (C2 + CDIFF) #define C4 (C3 + CDIFF) #define C5 (C4 + CDIFF) #define C6 (C5 + CDIFF + CDIFF2) #define C7 (C6 + CDIFF) #define C8 (C7 + CDIFF) #define C9 (C8 + CDIFF + CDIFF2) #define C10 (C9 + CDIFF + CDIFF2) #define C11 (C10 + CDIFF) #define C12 (C11 + CDIFF) #define C13 (C12 + CDIFF + CDIFF2) #define C14 (C13 + CDIFF) #define C15 (C14 + CDIFF + CDIFF2) #define C16 (C15 + CDIFF) #define C17 (C16 + CDIFF) #define C18 (C17 + CDIFF + CDIFF2) #define C19 (C18 + CDIFF) #define C20 (C19 + CDIFF + CDIFF2) #define C21 (C20 + CDIFF) #define C22 (C21 + CDIFF) #define C23 (C22 + CDIFF) #define RP0 414 #define RP1 (RP0 + 205) #define RP2 (RP0 + 100) #define RP3 880 #define R0 500 #define R1 (R0 + 205) #define R2 (R0 + 75) #define R3 900 #define W1 12 #define PW1 26 #define L1 300 #define LP1 363 #define BDIFF (CDIFF + 2) #define BDIFF2 (CDIFF2 + 2) #define B0 170 #define B1 (B0 + BDIFF + BDIFF2) #define B2 (B1 + BDIFF) #define B3 (B2 + BDIFF) #define B4 (B3 + BDIFF) #define B5 (B4 + BDIFF) #define B6 (B5 + BDIFF) #define B7 (B6 + BDIFF) #define B8 (B7 + BDIFF) #define B9 (B8 + BDIFF + BDIFF2) #define B10 (B9 + BDIFF) #define B11 (B10 + BDIFF) #define B12 (B11 + BDIFF) #define B13 (B12 + BDIFF) #define B14 (B13 + BDIFF) #define B15 (B14 + BDIFF) #define B16 (B15 + BDIFF) #define B17 (B16 + BDIFF + BDIFF2) #define B18 (BDIFF) #define B19 (B18 + BDIFF + BDIFF) /* * This structure is for device definition. The structure is defined in * include/brighton.h, further definitions in brighton/brightonDevtable.h and * include/brightoninternals.h * * typedef int (*brightonCallback)(int, float); * typedef struct BrightonLocations { * int device; 0=rotary, 1=scale, etc. * float relx, rely; relative position with regards to 1000 by 1000 window * float relw, relh; relative height. * int from, to; * brightonCallback callback; specific to this dev * char *image; bitmap. If zero take a device default. * int flags; * } brightonLocations; * * This example is for a axxeBristol type synth interface. */ static brightonLocations phatlocations[DEVICE_COUNT] = { /* Glide/Tranpose - 0 */ {"Glide", 1, PC0, RP0, PW1, LP1, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, {"Transpose", 2, C1, R2 - 30, 15, LP1/2 - 60, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW}, /* VCO - 2 */ {"VCO LFO Sine Mod", 1, PC2, RP0, PW1, LP1, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, {"VCO LFO Square Mod", 1, PC3, RP0, PW1, LP1, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, {"VCO S/H Mod", 1, PC4, RP0, PW1, LP1, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, {"VCO ADSR Mod", 1, PC5, RP0, PW1, LP1, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, {"VCO PW", 1, PC6, RP0, PW1, LP1, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, {"VCO PWM LFO", 1, PC7, RP0, PW1, LP1, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, {"VCO PWM ADSR", 1, PC8, RP0, PW1, LP1, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, /* LFO - 9 */ {"LFO Freq", 1, PC9, RP0, PW1, LP1, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, /* Mixer - 10 */ {"Mix Noise", 1, PC10, RP0, PW1, LP1, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, {"Mix VCO Ramp", 1, PC11, RP0, PW1, LP1, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, {"Mix VCO Pulse", 1, PC12, RP0, PW1, LP1, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, /* VCF - 13 */ {"VCF Cutoff", 1, PC13, RP0, PW1, LP1, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, {"VCO Resonance", 1, PC14, RP0, PW1, LP1, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, {"VCO KBD", 1, PC15, RP0, PW1, LP1, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, {"VCF LFO Sine", 1, PC16, RP0, PW1, LP1, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, {"VCF ADSR", 1, PC17, RP0, PW1, LP1, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, /* VCA - 18 */ {"VCA Gain", 1, PC18, RP0, PW1, LP1, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, {"VCA ADSR", 1, PC19, RP0, PW1, LP1, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, /* ADSR - 20 */ {"Attack", 1, PC20, RP0, PW1, LP1, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, {"Decay", 1, PC21, RP0, PW1, LP1, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, {"Sustain", 1, PC22, RP0, PW1, LP1, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, {"Release", 1, PC23, RP0, PW1, LP1, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, /* Pink/White noise - 24 */ {"Pink/White", 2, C1, 110, 14, 100, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, /* LFO mode - 25 */ {"LFO S/M", 2, C22, 110, 14, 100, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, /* LFO trigger - gate/auto - 26 */ {"LFO Trig", 2, C20, 110, 14, 100, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, /* Pitch Control - 27 */ {"Pitch Flat", 2, 25, RP2, 30, 80, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlw.xpm", 0}, {"Pitch Trill", 2, 53, RP2, 30, 80, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlw.xpm", 0}, {"Pitch Sharp", 2, 80, RP2, 30, 80, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlw.xpm", 0}, /* Memory Load, mem, Save - 30 */ {"", 2, B0, RP3, 20, 60, 0, 1, 0, "bitmaps/buttons/pressoffw.xpm", "bitmaps/buttons/pressonw.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, B1, RP3, 20, 60, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B2, RP3, 20, 60, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B3, RP3, 20, 60, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B4, RP3, 20, 60, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B5, RP3, 20, 60, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B6, RP3, 20, 60, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B7, RP3, 20, 60, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B8, RP3, 20, 60, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B9, RP3, 20, 60, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B10, RP3, 20, 60, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B11, RP3, 20, 60, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B12, RP3, 20, 60, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B13, RP3, 20, 60, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B14, RP3, 20, 60, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B15, RP3, 20, 60, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B16, RP3, 20, 60, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B17, RP3, 20, 60, 0, 1, 0, "bitmaps/buttons/pressoffo.xpm", "bitmaps/buttons/pressono.xpm", BRIGHTON_CHECKBUTTON}, /* MIDI - or android up/down memories */ {"", 2, B18, RP3, 20, 60, 0, 1, 0, "bitmaps/buttons/pressoffw.xpm", "bitmaps/buttons/pressonw.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, B19, RP3, 20, 60, 0, 1, 0, "bitmaps/buttons/pressoffw.xpm", "bitmaps/buttons/pressonw.xpm", BRIGHTON_CHECKBUTTON}, }; static brightonLocations locations[DEVICE_COUNT] = { /* Glide/Tranpose - 0 */ {"Glide", 1, C0, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, {"Transpose", 2, C1, R2 + 30, 15, L1/2 - 60, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW}, /* VCO - 2 */ {"VCO LFO Sine Mod", 1, C2, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, {"VCO LFO Square Mod", 1, C3, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, {"VCO S/H Mod", 1, C4, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, {"VCO ADSR Mod", 1, C5, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, {"VCO PW", 1, C6, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, {"VCO PWM LFO", 1, C7, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, {"VCO PWM ADSR", 1, C8, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, /* LFO - 9 */ {"LFO Freq", 1, C9, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, /* Mixer - 10 */ {"Mix Noise", 1, C10, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, {"Mix VCO Ramp", 1, C11, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, {"Mix VCO Pulse", 1, C12, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, /* VCF - 13 */ {"VCF Cutoff", 1, C13, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, {"VCO Resonance", 1, C14, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, {"VCO KBD", 1, C15, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, {"VCF LFO Sine", 1, C16, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, {"VCF ADSR", 1, C17, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, /* VCA - 18 */ {"VCA Gain", 1, C18, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, {"VCA ADSR", 1, C19, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, /* ADSR - 20 */ {"Attack", 1, C20, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, {"Decay", 1, C21, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, {"Sustain", 1, C22, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, {"Release", 1, C23, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, /* Pink/White noise - 24 */ {"Pink/White", 2, C1, 220, 14, 100, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, /* LFO mode - 25 */ {"LFO S/M", 2, C22, 220, 14, 100, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, /* LFO trigger - gate/auto - 26 */ {"LFO Trig", 2, C20, 220, 14, 100, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, /* Pitch Control - 27 */ {"Pitch Flat", 2, 25, R2, 30, 80, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlw.xpm", 0}, {"Pitch Trill", 2, 53, R2, 30, 80, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlw.xpm", 0}, {"Pitch Sharp", 2, 80, R2, 30, 80, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlw.xpm", 0}, /* Memory Load, mem, Save - 30 */ {"", 2, B0, R3, 20, 60, 0, 1, 0, "bitmaps/buttons/pressoffw.xpm", "bitmaps/buttons/pressonw.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, B1, R3, 20, 60, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B2, R3, 20, 60, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B3, R3, 20, 60, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B4, R3, 20, 60, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B5, R3, 20, 60, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B6, R3, 20, 60, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B7, R3, 20, 60, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B8, R3, 20, 60, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B9, R3, 20, 60, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B10, R3, 20, 60, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B11, R3, 20, 60, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B12, R3, 20, 60, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B13, R3, 20, 60, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B14, R3, 20, 60, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B15, R3, 20, 60, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B16, R3, 20, 60, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B17, R3, 20, 60, 0, 1, 0, "bitmaps/buttons/pressoffo.xpm", "bitmaps/buttons/pressono.xpm", BRIGHTON_CHECKBUTTON}, /* MIDI */ {"", 2, B18, R3, 20, 60, 0, 1, 0, "bitmaps/buttons/pressoffw.xpm", "bitmaps/buttons/pressonw.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, B19, R3, 20, 60, 0, 1, 0, "bitmaps/buttons/pressoffw.xpm", "bitmaps/buttons/pressonw.xpm", BRIGHTON_CHECKBUTTON}, }; /* */ /* * This is a set of globals for the main window rendering. Again taken from * include/brighton.h */ brightonApp axxePhatApp = { "axxe", 0, /* no blueprint on wood background. */ "bitmaps/textures/metal4.xpm", 0, /* BRIGHTON_STRETCH, //flags */ axxeInit, axxeConfigure, /* 3 callbacks, unused? */ midiCallback, destroySynth, {1, 100, 2, 2, 5, 520, 0, 0}, 600, 350, 0, 0, 4, /* Panels */ { { "Axxe", "bitmaps/blueprints/axxephat.xpm", "bitmaps/textures/metal6.xpm", BRIGHTON_STRETCH, /* flags */ 0, 0, axxeCallback, 15, 0, 970, 620, DEVICE_COUNT, phatlocations }, #ifdef RIBBON_KEYBOARD { "RibbonKeyboard", 0, "bitmaps/newkeys/ribbonKeys.xpm", BRIGHTON_STRETCH, 0, ribbonCallBack, ribbonCallBack, 80, 625, 840, 360, 1, ribbonkeyboard, }, #else { "Keyboard", 0, "bitmaps/newkeys/fkbg.xpm", /* flags */ BRIGHTON_STRETCH|BRIGHTON_KEY_PANEL, 0, 0, keyCallback, 80, 625, 840, 360, KEY_COUNT_2OCTAVE2, keys2octave2 }, #endif { "Axxe", 0, "bitmaps/textures/metal4.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 0, 0, 15, 1000, 0, 0 }, { "Axxe", 0, "bitmaps/textures/metal4.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 985, 0, 15, 1000, 0, 0 } } }; /* * This is a set of globals for the main window rendering. Again taken from * include/brighton.h */ brightonApp axxeApp = { "axxe", 0, /* no blueprint on wood background. */ "bitmaps/textures/metal4.xpm", 0, /* BRIGHTON_STRETCH, //flags */ axxeInit, axxeConfigure, /* 3 callbacks, unused? */ midiCallback, destroySynth, {1, 100, 2, 2, 5, 520, 0, 0}, 600, 350, 0, 0, 4, /* Panels */ { { "Axxe", "bitmaps/blueprints/axxe.xpm", "bitmaps/textures/metal6.xpm", BRIGHTON_STRETCH, /* flags */ 0, 0, axxeCallback, 15, 0, 970, 700, DEVICE_COUNT, locations }, { "Keyboard", 0, "bitmaps/newkeys/ekbg.xpm", /* flags */ 0x020|BRIGHTON_STRETCH, 0, 0, keyCallback, 120, 700, 800, 300, KEY_COUNT_3OCTAVE, keys3octave }, { "Axxe", 0, "bitmaps/textures/metal4.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 0, 0, 15, 1000, 0, 0 }, { "Axxe", 0, "bitmaps/textures/metal4.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 985, 0, 15, 1000, 0, 0 } } }; static int midiCallback(brightonWindow *win, int controller, int value, float n) { guiSynth *synth = findSynth(global.synths, win); printf("midi callback: %x, %i\n", controller, value); switch(controller) { case MIDI_PROGRAM: printf("midi program: %x, %i\n", controller, value); synth->location = value; loadMemory(synth, synth->resources->name, 0, synth->location, synth->mem.active, 0, 0); break; case MIDI_BANK_SELECT: printf("midi banksel: %x, %i\n", controller, value); synth->bank = value * 10; synth->location = (synth->location % 10) + value * 10; loadMemory(synth, synth->resources->name, 0, synth->location, synth->mem.active, 0, 0); break; } return(0); } static int axxeMidiSendMsg(void *synth, int fd, int chan, int c, int o, int v) { bristolMidiSendMsg(fd, chan, c, o, v); return(0); } static int axxeMemory(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; if ((synth->flags | OPERATIONAL) == 0) return(0); /* printf(" axxeMemory(B: %i L %i: %i, %i)\n", */ /* synth->bank, synth->location, c, o); */ switch(c) { case 0: saveMemory(synth, "axxe", 0, synth->bank + synth->location, 0); return(0); break; case 17: loadMemory(synth, "axxe", 0, synth->bank + synth->location, synth->mem.active, 0, 0); return(0); break; case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: if (synth->dispatch[RADIOSET_1].other2) { synth->dispatch[RADIOSET_1].other2 = 0; return(0); } if (synth->dispatch[RADIOSET_1].other1 != -1) { synth->dispatch[RADIOSET_1].other2 = 1; if (synth->dispatch[RADIOSET_1].other1 != c) event.value = 0; else event.value = 1; brightonParamChange(synth->win, synth->panel, synth->dispatch[RADIOSET_1].other1 + MEM_START, &event); } synth->dispatch[RADIOSET_1].other1 = c; synth->bank = c * 10; break; case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: if (synth->dispatch[RADIOSET_2].other2) { synth->dispatch[RADIOSET_2].other2 = 0; return(0); } if (synth->dispatch[RADIOSET_2].other1 != -1) { synth->dispatch[RADIOSET_2].other2 = 1; if (synth->dispatch[RADIOSET_2].other1 != c) event.value = 0; else event.value = 1; brightonParamChange(synth->win, synth->panel, synth->dispatch[RADIOSET_2].other1 + MEM_START, &event); } synth->dispatch[RADIOSET_2].other1 = c; /* Do radio buttons */ synth->location = c - 8; break; } return(0); } static int axxeMidi(guiSynth *synth, int fd, int chan, int c, int o, int v) { int newchan; if ((synth->flags & OPERATIONAL) == 0) return(0); if (c == 1) { if ((newchan = synth->midichannel - 1) < 0) { synth->midichannel = 0; return(0); } } else { if ((newchan = synth->midichannel + 1) >= 16) { synth->midichannel = 15; return(0); } } if (global.libtest == 0) { /* #warning if we do not check for ack then socket might hang on exit * To overcome that we should consider checking a sequence number in * the message library? That is non trivial since it requires that * our midi messges have a 'ack' flag included - we cannot check for * ack here (actually, we could, and in the app is probably the right * place to do it rather than the lib however both would have to be * changed to suppor this - nc). */ bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_MIDICHANNEL|newchan); } synth->midichannel = newchan; return(0); } /* * For the sake of ease of use, links have been placed here to be called * by any of the devices created. They would be better in some other file, * perhaps with this as a dispatch. * * Param refers to the device index in the locations table given below. */ static int axxeCallback(brightonWindow * win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); int sendvalue; /*printf("axxeCallback(%i, %f): %x\n", index, value, synth); */ if (synth == 0) return(0); if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0)) return(0); if (axxeApp.resources[0].devlocn[index].to == 1.0) sendvalue = value * (CONTROLLER_RANGE - 1); else sendvalue = value; synth->mem.param[index] = value; if ((!global.libtest) || (index >= ACTIVE_DEVS)) synth->dispatch[index].routine(synth, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #ifdef DEBUG else printf("dispatch[%x,%i](%i, %i, %i, %i, %i)\n", synth, index, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #endif return(0); } static int axxeAutoTrig(guiSynth *synth, int fd, int chan, int c, int o, int v) { /* * This takes the LFO value and sends it to the LFO, and if we have auto * trig configured will also send a value to 126/19 for trigger repeat rate. */ if (synth->mem.param[26] == 0) { /* * This is measured in buffer sizes, so it not exactly accurate. * * Fastest rate is going to be 10Hz (1.0), slowest rate 0.1Hz (0.0). */ bristolMidiSendMsg(fd, chan, 126, 19, (int) (synth->mem.param[9] * C_RANGE_MIN_1)); } else { bristolMidiSendMsg(fd, chan, 126, 19, 0); } bristolMidiSendMsg(fd, chan, 2, 0, (int) (synth->mem.param[9] * C_RANGE_MIN_1)); return(0); } static int axxeTranspose(guiSynth *synth, int fd, int chan, int c, int o, int v) { switch (v) { case 0: synth->transpose = 36; break; case 1: synth->transpose = 48; break; case 2: synth->transpose = 60; break; } return(0); } /* * Any location initialisation required to run the callbacks. For bristol, this * will connect to the engine, and give it some base parameters. * May need to generate some application specific menus. * Will also then make specific requests to some of the devices to alter their * rendering. */ static int axxeInit(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); dispatcher *dispatch; int i; if (synth == 0) { synth = findSynth(global.synths, (int) 0); if (synth == 0) { printf("cannot init\n"); return(0); } } /* * We need to take a copy here since the value may change as the synth * is drawn */ if ((initmem = synth->location) == 0) initmem = 11; synth->win = win; printf("Initialise the axxe link to bristol: %p\n", synth->win); synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float)); synth->mem.count = DEVICE_COUNT; synth->mem.active = ACTIVE_DEVS; synth->dispatch = (dispatcher *) brightonmalloc(DEVICE_COUNT * sizeof(dispatcher)); dispatch = synth->dispatch; /* * We really want to have three connection mechanisms. These should be * 1. Unix named sockets. * 2. UDP sockets. * 3. MIDI pipe. */ if (!global.libtest) { if ((synth->sid = initConnection(&global, synth)) < 0) return(-1); } for (i = 0; i < DEVICE_COUNT; i++) { synth->dispatch[i].routine = axxeMidiSendMsg; } dispatch[0].controller = 126; dispatch[0].operator = 0; dispatch[1].controller = 126; dispatch[1].operator = 0; dispatch[1].routine = (synthRoutine) axxeTranspose; dispatch[2].controller = 126; dispatch[2].operator = 2; dispatch[3].controller = 126; dispatch[3].operator = 3; dispatch[4].controller = 126; dispatch[4].operator = 4; dispatch[5].controller = 126; dispatch[5].operator = 5; dispatch[6].controller = 1; dispatch[6].operator = 0; dispatch[7].controller = 126; dispatch[7].operator = 6; dispatch[8].controller = 126; dispatch[8].operator = 7; dispatch[9].controller = 2; dispatch[9].operator = 0; dispatch[9].routine = (synthRoutine) axxeAutoTrig; dispatch[10].controller = 126; dispatch[10].operator = 8; dispatch[11].controller = 126; dispatch[11].operator = 9; dispatch[12].controller = 126; dispatch[12].operator = 10; dispatch[13].controller = 3; dispatch[13].operator = 0; dispatch[14].controller = 3; dispatch[14].operator = 1; dispatch[15].controller = 3; dispatch[15].operator = 3; dispatch[16].controller = 126; dispatch[16].operator = 11; dispatch[17].controller = 126; dispatch[17].operator = 12; dispatch[18].controller = 126; dispatch[18].operator = 13; dispatch[19].controller = 126; dispatch[19].operator = 14; dispatch[20].controller = 4; dispatch[20].operator = 0; dispatch[21].controller = 4; dispatch[21].operator = 1; dispatch[22].controller = 4; dispatch[22].operator = 2; dispatch[23].controller = 4; dispatch[23].operator = 3; dispatch[24].controller = 6; dispatch[24].operator = 1; dispatch[25].controller = 126; dispatch[25].operator = 15; dispatch[26].controller = 126; dispatch[26].operator = 19; dispatch[26].routine = (synthRoutine) axxeAutoTrig; dispatch[27].controller = 126; dispatch[27].operator = 16; dispatch[28].controller = 126; dispatch[28].operator = 17; dispatch[29].controller = 126; dispatch[29].operator = 18; dispatch[MEM_START + 0].controller = 17; dispatch[MEM_START + 1].controller = 1; dispatch[MEM_START + 2].controller = 2; dispatch[MEM_START + 3].controller = 3; dispatch[MEM_START + 4].controller = 4; dispatch[MEM_START + 5].controller = 5; dispatch[MEM_START + 6].controller = 6; dispatch[MEM_START + 7].controller = 7; dispatch[MEM_START + 8].controller = 8; dispatch[MEM_START + 9].controller = 9; dispatch[MEM_START + 10].controller = 10; dispatch[MEM_START + 11].controller = 11; dispatch[MEM_START + 12].controller = 12; dispatch[MEM_START + 13].controller = 13; dispatch[MEM_START + 14].controller = 14; dispatch[MEM_START + 15].controller = 15; dispatch[MEM_START + 16].controller = 16; dispatch[MEM_START + 17].controller = 0; dispatch[MEM_START + 0].routine = dispatch[MEM_START + 1].routine = dispatch[MEM_START + 2].routine = dispatch[MEM_START + 3].routine = dispatch[MEM_START + 4].routine = dispatch[MEM_START + 5].routine = dispatch[MEM_START + 6].routine = dispatch[MEM_START + 7].routine = dispatch[MEM_START + 8].routine = dispatch[MEM_START + 9].routine = dispatch[MEM_START + 10].routine = dispatch[MEM_START + 11].routine = dispatch[MEM_START + 12].routine = dispatch[MEM_START + 13].routine = dispatch[MEM_START + 14].routine = dispatch[MEM_START + 15].routine = dispatch[MEM_START + 16].routine = dispatch[MEM_START + 17].routine = (synthRoutine) axxeMemory; dispatch[MIDI_START].controller = 1; dispatch[MIDI_START + 1].controller = 2; dispatch[MIDI_START].routine = dispatch[MIDI_START + 1].routine = (synthRoutine) axxeMidi; dispatch[RADIOSET_1].other1 = -1; dispatch[RADIOSET_2].other1 = -1; /* * Grooming env for 'gain' to amp. Short but not choppy attack, slightly * larger decay since the main env can shorten that if really desired. */ bristolMidiSendMsg(global.controlfd, synth->sid, 7, 0, 20); bristolMidiSendMsg(global.controlfd, synth->sid, 7, 1, 1000); bristolMidiSendMsg(global.controlfd, synth->sid, 7, 2, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 7, 3, 50); bristolMidiSendMsg(global.controlfd, synth->sid, 7, 4, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 7, 5, 0); /* no velocity */ bristolMidiSendMsg(global.controlfd, synth->sid, 7, 6, 0); /* no rezero */ /* * Need to specify env gain fixed, filter mod on, osc waveform. */ bristolMidiSendMsg(global.controlfd, synth->sid, 4, 4, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 2, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 4, 4); bristolMidiSendMsg(global.controlfd, synth->sid, 0, 4, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 6, 16383); /* sync LFO to keyon */ bristolMidiSendMsg(global.controlfd, synth->sid, 2, 1, 16383); return(0); } /* * This will be called to make any routine specific parameters available. */ static int axxeConfigure(brightonWindow* win) { guiSynth *synth = findSynth(global.synths, win); brightonEvent event; if (synth == 0) { printf("problems going operational\n"); return(-1); } if (synth->flags & OPERATIONAL) return(0); printf("going operational\n"); synth->bank = 10; if (synth->location == 0) synth->location = 11; synth->flags |= OPERATIONAL; synth->keypanel = 1; synth->keypanel2 = -1; synth->transpose = 36; loadMemory(synth, "axxe", 0, initmem, synth->mem.active, 0, 0); brightonPut(win, "bitmaps/blueprints/axxeshade.xpm", 0, 0, win->width, win->height); event.value = 1; brightonParamChange(synth->win, synth->panel, MEM_START + 1, &event); brightonParamChange(synth->win, synth->panel, MEM_START + 9, &event); /* * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only * occurs on first paint, so we suppress the first paint, and then request * an expose here. */ event.type = BRIGHTON_EXPOSE; event.intvalue = 1; brightonParamChange(synth->win, KEY_PANEL, -1, &event); /* * Touch a key on/off */ /* bristolMidiSendMsg(global.controlfd, synth->midichannel, */ /* BRISTOL_EVENT_KEYON, 0, 10 + synth->transpose); */ /* bristolMidiSendMsg(global.controlfd, synth->midichannel, */ /* BRISTOL_EVENT_KEYOFF, 0, 10 + synth->transpose); */ configureGlobals(synth); return(0); } bristol-0.60.11/brighton/brightonProphet.c0000644000175000017500000006372711746476475015460 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include #include "brighton.h" #include "brightonMini.h" #include "brightoninternals.h" static int initmem; static int prophetInit(); static int prophetConfigure(); static int prophetCallback(brightonWindow *, int, int, float); /*static int keyCallback(void *, int, int, float); */ /*static int modCallback(void *, int, int, float); */ static int midiCallback(brightonWindow *, int, int, float); extern guimain global; #include "brightonKeys.h" #define FIRST_DEV 0 #define DEVICE_COUNT (65 + FIRST_DEV) #define ACTIVE_DEVS (47 + FIRST_DEV) #define DISPLAY_DEV (64 + FIRST_DEV) #define RADIOSET_1 50 #define KEY_PANEL 1 #define R1 140 #define RB1 160 #define R2 425 #define RB2 445 #define R3 710 #define RB3 730 #define C1 20 #define C2 70 #define CB1 60 #define CB2 90 #define C3 120 #define C4 150 #define C5 180 #define C6 235 #define CB6 275 #define CB7 305 #define C7 340 #define CB8 390 #define C9 280 #define CB9 330 #define CB10 360 #define CB11 390 #define C10 430 #define CB12 480 #define CB13 510 #define C11 442 #define C12 490 #define C13 538 #define C14 595 #define C15 642 #define C16 688 #define C17 735 #define C18 800 #define C19 850 #define C20 900 #define C21 950 #define C22 877 #define S1 120 #define B1 14 #define B2 80 /* * This structure is for device definition. The structure is defined in * include/brighton.h, further definitions in brighton/brightonDevtable.h and * include/brightoninternals.h * * typedef int (*brightonCallback)(int, float); * typedef struct BrightonLocations { * int device; 0=rotary, 1=scale, etc. * float relx, rely; relative position with regards to 1000 by 1000 window * float relw, relh; relative height. * int from, to; * brightonCallback callback; specific to this dev * char *image; bitmap. If zero take a device default. * int flags; * } brightonLocations; * * This example is for a prophetBristol type synth interface. */ static brightonLocations locations[DEVICE_COUNT] = { /* poly mod */ {"PolyMod-Filt", 0, C1, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0|BRIGHTON_HALFSHADOW}, {"PolyMod-OscB", 0, C2, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0|BRIGHTON_HALFSHADOW}, {"PolyMod2Freq-A", 2, C3, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"PolyMod2PW-A", 2, C4, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"PolyMod2Filt", 2, C5, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* lfo */ {"LFO-Freq", 0, C2, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"LFO-Ramp", 2, C3, RB2, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"LFO-Tri", 2, C4, RB2, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"LFO-Square", 2, C5, RB2, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* wheel mod */ {"Wheel-Mix", 0, C1, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"Wheel-FreqA", 2, CB1, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"Wheel-FreqB", 2, CB2, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"Wheel-PW-A", 2, C3, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"Wheel-PW-B", 2, C4, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"Wheel-Filt", 2, C5, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* osc a */ {"OscA-Transpose", 0, C6, R1, S1, S1, 0, 5, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"OscA-Ramp", 2, CB6, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"OscA-Pulse", 2, CB7, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"OscA-PW", 0, C7, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"OscA-Sync", 2, CB8, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* osc b */ {"OscB-Transpose", 0, C6, R2, S1, S1, 0, 5, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"OscB-Tuning", 0, C9, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, BRIGHTON_NOTCH}, {"OscB-Ramp", 2, CB9, RB2, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"OscB-Tri", 2, CB10, RB2, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"OscB-Pulse", 2, CB11, RB2, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"OscB-PW", 0, C10, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"OscB-LFO", 2, CB12, RB2, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"OscB-KBD", 2, CB13, RB2, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* glide, etc */ {"Glide", 0, C6, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"Unison", 2, CB7, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* mixer */ {"Mix-OscA", 0, C11, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"Mix-OscB", 0, C12, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"Mix-Noise", 0, C13, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, /* filter + env */ {"VCF-Cutoff", 0, C14, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"VCF-Resonance", 0, C15, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"VCF-Env", 0, C16, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"VCF-KBD", 2, C17 + 6, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"VCF-Attack", 0, C14, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"VCF-Decay", 0, C15, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"VCF-Sustain", 0, C16, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"VCF-Release", 0, C17, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, /* main env */ {"VCA-Attack", 0, C18, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"VCA-Decay", 0, C19, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"VCA-Sustain", 0, C20, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"VCA-Release", 0, C21, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, /* tune + vol */ {"MasterTuning", 0, C18, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob3.xpm", 0, BRIGHTON_NOTCH}, {"MasterVolume", 0, C22, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob3.xpm", 0, 0}, {"Release", 2, C18 + 7, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, {"A-440", 2, C19 + 7, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, {"Tune", 2, C21 + 10, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, /* memories */ {"", 2, C14 + 10, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C14 + 30, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C14 + 50, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C14 + 70, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C14 + 90, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C14 + 110, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C14 + 130, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C14 + 150, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, CB8, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, CB8 + 30, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffo.xpm", "bitmaps/buttons/pressono.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, CB8 + 60, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, /* Midi, perhaps eventually file import/export buttons */ {"", 2, C20 + 10, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, C21 + 10, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, /* */ {"", 4, 850, 1025, 130, 130, 0, 1, 0, "bitmaps/images/prophet.xpm", 0, 0}, /* Display */ {"", 3, CB8 + 85, RB3, 120, B2, 0, 1, 0, 0, "bitmaps/images/alphadisplay3.xpm", 0} }; /* */ /* * This is a set of globals for the main window rendering. Again taken from * include/brighton.h */ brightonApp prophetApp = { "prophet", 0, /* no blueprint on wood background. */ "bitmaps/textures/wood3.xpm", 0, /* BRIGHTON_STRETCH, //flags */ prophetInit, prophetConfigure, /* 3 callbacks, unused? */ midiCallback, destroySynth, {5, 100, 2, 2, 5, 520, 0, 0}, 745, 310, 0, 0, 7, { { "Prophet", "bitmaps/blueprints/prophet.xpm", "bitmaps/textures/metal5.xpm", 0, /*BRIGHTON_STRETCH, // flags */ 0, 0, prophetCallback, 15, 25, 970, 540, DEVICE_COUNT, locations }, { "Keyboard", 0, "bitmaps/newkeys/kbg.xpm", /* flags */ 0x020|BRIGHTON_STRETCH, 0, 0, keyCallback, 110, 660, 899, 320, KEY_COUNT, keysprofile }, { "Mods", "bitmaps/blueprints/prophetmod.xpm", "bitmaps/textures/metal5.xpm", /* flags */ 0, 0, 0, modCallback, 15, 660, 95, 320, 2, mods }, { "Wood side", 0, "bitmaps/textures/wood4.xpm", BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 0, 0, 15, 1000, 0, 0 }, { "Wood side", 0, "bitmaps/textures/wood3.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 2, 4, 13, 992, 0, 0 }, { "Wood side", 0, "bitmaps/textures/wood4.xpm", BRIGHTON_VERTICAL, /*flags */ 0, 0, 0, 985, 0, 15, 1000, 0, 0 }, { "Wood side", 0, "bitmaps/textures/wood3.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /*flags */ 0, 0, 0, 986, 4, 13, 992, 0, 0 } } }; static int midiCallback(brightonWindow *win, int controller, int value, float n) { guiSynth *synth = findSynth(global.synths, win); printf("midi callback: %x, %i\n", controller, value); switch(controller) { case MIDI_PROGRAM: printf("midi program: %x, %i\n", controller, value); synth->location = value; loadMemory(synth, "prophet", 0, synth->bank + synth->location, synth->mem.active, FIRST_DEV, 0); break; case MIDI_BANK_SELECT: printf("midi banksel: %x, %i\n", controller, value); synth->bank = value; break; } return(0); } /*static dispatcher dispatch[DEVICE_COUNT]; */ static int prophetMidiSendMsg(void *synth, int fd, int chan, int c, int o, int v) { bristolMidiSendMsg(fd, chan, c, o, v); return(0); } static void multiTune(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; /* * Configures all the tune settings to zero (ie, 0.5). Do the Osc-A first, * since it is not visible, and then request the GUI to configure Osc-B. */ bristolMidiSendMsg(fd, synth->sid, 0, 2, 8191); event.type = BRIGHTON_FLOAT; event.value = 0.5; brightonParamChange(synth->win, synth->panel, FIRST_DEV + 45, &event); brightonParamChange(synth->win, synth->panel, FIRST_DEV + 21, &event); } static void keyTracking(guiSynth *synth, int fd, int chan, int c, int o, int v) { bristolMidiSendMsg(fd, synth->sid, 4, 3, v / 2); } static void midiRelease(guiSynth *synth, int fd, int chan, int c, int o, int v) { if (!global.libtest) { bristolMidiSendMsg(fd, synth->sid, 127, 0, BRISTOL_ALL_NOTES_OFF); } } static void prophetMemory(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; if (synth->flags & MEM_LOADING) return; if ((synth->flags & OPERATIONAL) == 0) return; if (synth->dispatch[RADIOSET_1].other2) { synth->dispatch[RADIOSET_1].other2 = 0; return; } switch (c) { default: case 0: /* * We want to make these into memory buttons. To do so we need to * know what the last active button was, and deactivate its * display, then send any message which represents the most * recently configured value. Since this is a memory button we do * not have much issue with the message, but we are concerned with * the display. */ if (synth->dispatch[RADIOSET_1].other1 != -1) { synth->dispatch[RADIOSET_1].other2 = 1; if (synth->dispatch[RADIOSET_1].other1 != o) event.value = 0; else event.value = 1; brightonParamChange(synth->win, synth->panel, synth->dispatch[RADIOSET_1].other1 + 49, &event); } synth->dispatch[RADIOSET_1].other1 = o; if (synth->flags & BANK_SELECT) { if ((synth->bank * 10 + o * 10) >= 1000) { synth->location = o; synth->flags &= ~BANK_SELECT; if (loadMemory(synth, "prophet", 0, synth->bank + synth->location, synth->mem.active, FIRST_DEV, BRISTOL_STAT) < 0) displayText(synth, "FRE", synth->bank + synth->location, DISPLAY_DEV); else displayText(synth, "PRG", synth->bank + synth->location, DISPLAY_DEV); } else { synth->bank = synth->bank * 10 + o * 10; displayText(synth, "BANK", synth->bank + synth->location, DISPLAY_DEV); } } else { if (synth->bank < 10) synth->bank = 10; synth->location = o; if (loadMemory(synth, "prophet", 0, synth->bank + synth->location, synth->mem.active, FIRST_DEV, BRISTOL_STAT) < 0) displayText(synth, "FRE", synth->bank + synth->location, DISPLAY_DEV); else displayText(synth, "PRG", synth->bank + synth->location, DISPLAY_DEV); } break; case 1: if (synth->bank < 10) synth->bank = 10; if (synth->location == 0) synth->location = 1; if (loadMemory(synth, "prophet", 0, synth->bank + synth->location, synth->mem.active, FIRST_DEV, 0) < 0) displayText(synth, "FRE", synth->bank + synth->location, DISPLAY_DEV); else displayText(synth, "PRG", synth->bank + synth->location, DISPLAY_DEV); synth->flags &= ~BANK_SELECT; break; case 2: if (synth->bank < 10) synth->bank = 10; if (synth->location == 0) synth->location = 1; saveMemory(synth, "prophet", 0, synth->bank + synth->location, FIRST_DEV); displayText(synth, "PRG", synth->bank + synth->location, DISPLAY_DEV); synth->flags &= ~BANK_SELECT; break; case 3: if (synth->flags & BANK_SELECT) { synth->flags &= ~BANK_SELECT; if (loadMemory(synth, "prophet", 0, synth->bank + synth->location, synth->mem.active, FIRST_DEV, BRISTOL_STAT) < 0) displayText(synth, "FRE", synth->bank + synth->location, DISPLAY_DEV); else displayText(synth, "PRG", synth->bank + synth->location, DISPLAY_DEV); } else { synth->bank = 0; displayText(synth, "BANK", synth->bank, DISPLAY_DEV); synth->flags |= BANK_SELECT; } break; } /* printf(" prophetMemory(B: %i L %i: %i)\n", */ /* synth->bank, synth->location, o); */ } static int prophetMidi(guiSynth *synth, int fd, int chan, int c, int o, int v) { int newchan; if ((synth->flags & OPERATIONAL) == 0) return(0); if (c == 1) { if ((newchan = synth->midichannel - 1) < 0) { synth->midichannel = 0; return(0); } } else { if ((newchan = synth->midichannel + 1) >= 16) { synth->midichannel = 15; return(0); } } if (global.libtest == 0) { bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_MIDICHANNEL|newchan); } synth->midichannel = newchan; /* printf("P: going to display: %x, %x\n", synth, synth->win); */ /* displayText(synth, "MIDI", synth->midichannel + 1, DISPLAY_DEV); */ return(0); } /* * For the sake of ease of use, links have been placed here to be called * by any of the devices created. They would be better in some other file, * perhaps with this as a dispatch. * * Param refers to the device index in the locations table given below. */ static int prophetCallback(brightonWindow * win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); int sendvalue; /*printf("prophetCallback(%i, %f): %x\n", index, value, synth); */ if (synth == 0) return(0); if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0)) return(0); if (prophetApp.resources[0].devlocn[index].to == 1.0) sendvalue = value * (CONTROLLER_RANGE - 1); else sendvalue = value; synth->mem.param[index] = value; if ((!global.libtest) || (index >= ACTIVE_DEVS)) synth->dispatch[index].routine(synth, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #ifdef DEBUG else printf("dispatch[%p,%i](%i, %i, %i, %i, %i)\n", synth, index, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #endif return(0); } /* * Any location initialisation required to run the callbacks. For bristol, this * will connect to the engine, and give it some base parameters. * May need to generate some application specific menus. * Will also then make specific requests to some of the devices to alter their * rendering. */ static int prophetInit(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); dispatcher *dispatch; int i; if (synth == 0) { synth = findSynth(global.synths, (int) 0); if (synth == 0) { printf("cannot init\n"); return(0); } } if ((initmem = synth->location) == 0) initmem = 11; synth->win = win; printf("Initialise the prophet link to bristol: %p\n", synth->win); synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float)); synth->mem.count = DEVICE_COUNT; synth->mem.active = ACTIVE_DEVS; synth->dispatch = (dispatcher *) brightonmalloc(DEVICE_COUNT * sizeof(dispatcher)); dispatch = synth->dispatch; /* * We really want to have three connection mechanisms. These should be * 1. Unix named sockets. * 2. UDP sockets. * 3. MIDI pipe. */ if (!global.libtest) { if ((synth->sid = initConnection(&global, synth)) < 0) return(-1); } for (i = 0; i < DEVICE_COUNT; i++) { synth->dispatch[i].routine = prophetMidiSendMsg; } dispatch[FIRST_DEV].controller = 126; dispatch[FIRST_DEV].operator = 6; dispatch[FIRST_DEV + 1].controller = 126; dispatch[FIRST_DEV + 1].operator = 7; dispatch[FIRST_DEV + 2].controller = 126; dispatch[FIRST_DEV + 2].operator = 8; dispatch[FIRST_DEV + 3].controller = 126; dispatch[FIRST_DEV + 3].operator = 9; dispatch[FIRST_DEV + 4].controller = 126; dispatch[FIRST_DEV + 4].operator = 10; /* * This is for prophetDCO as LFO. Should change to true LFO. One parameter * for freq (0) and the rest are then mix parameters. */ dispatch[FIRST_DEV + 5].controller = 2; dispatch[FIRST_DEV + 5].operator = 0; dispatch[FIRST_DEV + 6].controller = 126; dispatch[FIRST_DEV + 6].operator = 24; dispatch[FIRST_DEV + 7].controller = 126; dispatch[FIRST_DEV + 7].operator = 25; dispatch[FIRST_DEV + 8].controller = 126; dispatch[FIRST_DEV + 8].operator = 26; dispatch[FIRST_DEV + 9].controller = 126; dispatch[FIRST_DEV + 9].operator = 11; dispatch[FIRST_DEV + 10].controller = 126; dispatch[FIRST_DEV + 10].operator = 12; dispatch[FIRST_DEV + 11].controller = 126; dispatch[FIRST_DEV + 11].operator = 13; dispatch[FIRST_DEV + 12].controller = 126; dispatch[FIRST_DEV + 12].operator = 14; dispatch[FIRST_DEV + 13].controller = 126; dispatch[FIRST_DEV + 13].operator = 15; dispatch[FIRST_DEV + 14].controller = 126; dispatch[FIRST_DEV + 14].operator = 16; dispatch[FIRST_DEV + 15].controller = 0; dispatch[FIRST_DEV + 15].operator = 1; dispatch[FIRST_DEV + 16].controller = 0; dispatch[FIRST_DEV + 16].operator = 4; dispatch[FIRST_DEV + 17].controller = 0; dispatch[FIRST_DEV + 17].operator = 6; dispatch[FIRST_DEV + 18].controller = 0; dispatch[FIRST_DEV + 18].operator = 0; dispatch[FIRST_DEV + 19].controller = 0; dispatch[FIRST_DEV + 19].operator = 7; dispatch[FIRST_DEV + 20].controller = 1; dispatch[FIRST_DEV + 20].operator = 1; dispatch[FIRST_DEV + 21].controller = 1; dispatch[FIRST_DEV + 21].operator = 2; dispatch[FIRST_DEV + 22].controller = 1; dispatch[FIRST_DEV + 22].operator = 4; dispatch[FIRST_DEV + 23].controller = 1; dispatch[FIRST_DEV + 23].operator = 5; dispatch[FIRST_DEV + 24].controller = 1; dispatch[FIRST_DEV + 24].operator = 6; dispatch[FIRST_DEV + 25].controller = 1; dispatch[FIRST_DEV + 25].operator = 0; dispatch[FIRST_DEV + 26].controller = 126; dispatch[FIRST_DEV + 26].operator = 18; dispatch[FIRST_DEV + 27].controller = 126; dispatch[FIRST_DEV + 27].operator = 19; dispatch[FIRST_DEV + 28].controller = 126; dispatch[FIRST_DEV + 28].operator = 0; dispatch[FIRST_DEV + 29].controller = 126; dispatch[FIRST_DEV + 29].operator = 1; dispatch[FIRST_DEV + 30].controller = 126; dispatch[FIRST_DEV + 30].operator = 20; dispatch[FIRST_DEV + 31].controller = 126; dispatch[FIRST_DEV + 31].operator = 21; dispatch[FIRST_DEV + 32].controller = 126; dispatch[FIRST_DEV + 32].operator = 22; dispatch[FIRST_DEV + 33].controller = 4; dispatch[FIRST_DEV + 33].operator = 0; dispatch[FIRST_DEV + 34].controller = 4; dispatch[FIRST_DEV + 34].operator = 1; dispatch[FIRST_DEV + 35].controller = 126; dispatch[FIRST_DEV + 35].operator = 23; dispatch[FIRST_DEV + 36].controller = 4; dispatch[FIRST_DEV + 36].operator = 3; dispatch[FIRST_DEV + 36].routine = (synthRoutine) keyTracking; dispatch[FIRST_DEV + 37].controller = 3; dispatch[FIRST_DEV + 37].operator = 0; dispatch[FIRST_DEV + 38].controller = 3; dispatch[FIRST_DEV + 38].operator = 1; dispatch[FIRST_DEV + 39].controller = 3; dispatch[FIRST_DEV + 39].operator = 2; dispatch[FIRST_DEV + 40].controller = 3; dispatch[FIRST_DEV + 40].operator = 3; dispatch[FIRST_DEV + 41].controller = 5; dispatch[FIRST_DEV + 41].operator = 0; dispatch[FIRST_DEV + 42].controller = 5; dispatch[FIRST_DEV + 42].operator = 1; dispatch[FIRST_DEV + 43].controller = 5; dispatch[FIRST_DEV + 43].operator = 2; dispatch[FIRST_DEV + 44].controller = 5; dispatch[FIRST_DEV + 44].operator = 3; dispatch[FIRST_DEV + 45].controller = 126; dispatch[FIRST_DEV + 45].operator = 2; dispatch[FIRST_DEV + 46].controller = 5; dispatch[FIRST_DEV + 46].operator = 4; dispatch[FIRST_DEV + 47].controller = 1; dispatch[FIRST_DEV + 47].operator = 1; dispatch[FIRST_DEV + 47].routine = (synthRoutine) midiRelease; dispatch[FIRST_DEV + 48].controller = 126; dispatch[FIRST_DEV + 48].operator = 3; dispatch[FIRST_DEV + 49].controller = 1; dispatch[FIRST_DEV + 49].operator = 1; dispatch[FIRST_DEV + 49].routine = (synthRoutine) multiTune; dispatch[FIRST_DEV + 50].operator = 1; dispatch[FIRST_DEV + 51].operator = 2; dispatch[FIRST_DEV + 52].operator = 3; dispatch[FIRST_DEV + 53].operator = 4; dispatch[FIRST_DEV + 54].operator = 5; dispatch[FIRST_DEV + 55].operator = 6; dispatch[FIRST_DEV + 56].operator = 7; dispatch[FIRST_DEV + 57].operator = 8; dispatch[FIRST_DEV + 58].controller = 1; dispatch[FIRST_DEV + 59].controller = 2; dispatch[FIRST_DEV + 60].controller = 3; dispatch[FIRST_DEV + 50].routine = dispatch[FIRST_DEV + 51].routine = dispatch[FIRST_DEV + 52].routine = dispatch[FIRST_DEV + 53].routine = dispatch[FIRST_DEV + 54].routine = dispatch[FIRST_DEV + 55].routine = dispatch[FIRST_DEV + 56].routine = dispatch[FIRST_DEV + 57].routine = dispatch[FIRST_DEV + 58].routine = dispatch[FIRST_DEV + 59].routine = dispatch[FIRST_DEV + 60].routine = (synthRoutine) prophetMemory; dispatch[FIRST_DEV + 61].routine = dispatch[FIRST_DEV + 62].routine = (synthRoutine) prophetMidi; dispatch[FIRST_DEV + 61].controller = 1; dispatch[FIRST_DEV + 62].controller = 2; dispatch[RADIOSET_1].other1 = -1; /* Tune osc-1 */ bristolMidiSendMsg(global.controlfd, synth->sid, 0, 2, 8192); /* Gain on filter contour */ bristolMidiSendMsg(global.controlfd, synth->sid, 3, 4, CONTROLLER_RANGE - 1); bristolMidiSendMsg(global.controlfd, synth->sid, 4, 4, 4); bristolMidiSendMsg(global.controlfd, synth->sid, 126, 36, C_RANGE_MIN_1); return(0); } /* * This will be called to make any routine specific parameters available. */ static int prophetConfigure(brightonWindow* win) { guiSynth *synth = findSynth(global.synths, win); brightonEvent event; if (synth == 0) { printf("problems going operational\n"); return(-1); } if (synth->flags & OPERATIONAL) return(0); printf("going operational\n"); synth->flags |= OPERATIONAL; synth->keypanel = 1; synth->keypanel2 = -1; synth->transpose = 36; if (synth->location == 0) { synth->bank = 10; synth->location = 1; } loadMemory(synth, "prophet", 0, initmem, synth->mem.active, FIRST_DEV, 0); brightonPut(win, "bitmaps/blueprints/prophetshade.xpm", 0, 0, win->width, win->height); /* * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only * occurs on first paint, so we suppress the first paint, and then request * an expose here. */ event.type = BRIGHTON_EXPOSE; event.intvalue = 1; brightonParamChange(synth->win, KEY_PANEL, -1, &event); configureGlobals(synth); return(0); } bristol-0.60.11/brighton/brightonMemoryMoog.c0000644000175000017500000012545211746476475016123 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* Korg MemoryMoog UI */ #include #include "brighton.h" #include "brightonMini.h" #include "brightoninternals.h" static int memMoogInit(); static int memMoogConfigure(); static int memMoogCallback(brightonWindow *, int, int, float); static int memMoogModCallback(brightonWindow *, int, int, float); static int MMmidiCallback(brightonWindow *, int, int, float); extern guimain global; #include "brightonKeys.h" #define DEVICE_COUNT 113 #define ACTIVE_DEVS 91 #define DISPLAY (DEVICE_COUNT - 1) #define MEM_START (ACTIVE_DEVS + 4) #define MIDI_START (MEM_START + 14) #define KEY_PANEL 1 #define OSC_1_RADIO 0 #define OSC_2_RADIO 1 #define OSC_3_RADIO 2 /* * This structure is for device definition. The structure is defined in * include/brighton.h, further definitions in brighton/brightonDevtable.h and * include/brightoninternals.h * * typedef int (*brightonCallback)(int, float); * typedef struct BrightonLocations { * int device; 0=rotary, 1=scale, etc. * float relx, rely; relative position with regards to 1000 by 1000 window * float relw, relh; relative height. * int from, to; * brightonCallback callback; specific to this dev * char *image; bitmap. If zero take a device default. * int flags; * } brightonLocations; * * This example is for a memMoogBristol type synth interface. */ #define RD1 210 #define C4D0 30 #define C4D1 27 #define C4D2 44 #define C4D3 25 #define R0 140 #define R1 (R0 + RD1) #define R2 (R1 + RD1) #define R3 (R2 + RD1) #define R1_1 (R0 + (R3 - R0) / 2) #define R1_0 (R0 + (R1_1 - R0) / 2) #define R1_2 (R3 - (R1_1 - R0) / 2) #define C10 35 #define C11 (C10 + C4D0) #define C20 (C11 + C4D1 + 10) #define C21 (C20 + C4D1) #define C22 (C21 + C4D1) #define C23 (C22 + C4D1) #define R21_0 (R1_1 + (R3 - R1_1) / 3) #define R21_1 (R1_1 + (R3 - R1_1) * 2 / 3) #define C30 (C23 + C4D1 + 10) #define C40 (C30 + C4D1 + 30) #define C41 (C40 + C4D3) #define C42 (C41 + C4D3) #define C43 (C42 + C4D3) #define C44 (C43 + C4D3) #define C45 (C44 + C4D3) #define C46 (C45 + C4D3) #define C50 (C46 + C4D3 + 10) #define C51 (C50 + C4D3) #define C52 (C51 + C4D3) #define C53 (C52 + C4D3) #define C54 (C53 + C4D3 + 10) #define C55 (C54 + C4D3 - 10) #define C56 (C55 + C4D3 - 10) #define C57 (C56 + C4D3 + 15) #define C58 (C57 + C4D3) #define C59 (C58 + C4D3) #define C60 (C59 + C4D1 + 5) #define C70 (C60 + C4D2 + 15) #define C71 (C70 + C4D2) #define C72 (C71 + C4D2) #define C73 (C72 + C4D2) #define C80 (C73 + C4D2) #define S1 90 #define S2 14 #define S3 40 #define S4 100 static brightonLocations locations[DEVICE_COUNT] = { /* Oscillators - 0 */ {"Osc1-16", 2, C50, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"Osc1-8", 2, C51, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"Osc1-4", 2, C52, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"Osc1-2", 2, C53, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"Osc1-Sync", 2, C54, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"Osc1-PW", 0, C56, R0, S3, S4, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"Osc1-Square", 2, C57, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"Osc1-Ramp", 2, C58, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"Osc1-Tri", 2, C59, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, /* Osc-2 9 */ {"Osc2-16", 2, C50, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"Osc2-8", 2, C51, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"Osc2-4", 2, C52, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"Osc2-2", 2, C53, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"Osc2-Tuning", 0, C54 - 5, R1, S3, S4, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, BRIGHTON_NOTCH}, {"Osc2-PW", 0, C56, R1, S3, S4, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"Osc2-Square", 2, C57, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"Osc2-Ramp", 2, C58, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"Osc2-Tri", 2, C59, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, /* Osc-3 - 18 */ {"Osc3-16", 2, C50, R2, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"Osc3-8", 2, C51, R2, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"Osc3-4", 2, C52, R2, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"Osc3-2", 2, C53, R2, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"Osc3-Tuning", 0, C54 - 5, R2, S3, S4, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, BRIGHTON_NOTCH}, {"Osc3-PW", 0, C56, R2, S3, S4, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"Osc3-Square", 2, C57, R2, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"Osc3-Ramp", 2, C58, R2, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"Osc3-Tri", 2, C59, R2, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, /* Osc-3 options - 27 */ {"Osc3-LFO", 2, C51, R3, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"Osc3-KBD", 2, C53, R3, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, /* Mixer - 29 */ {"Mix-Osc1", 0, C60, R0, S3, S4, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"Mix-Osc2", 0, C60, R1, S3, S4, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"Mix-Osc3", 0, C60, R2, S3, S4, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"Mix-Noise", 0, C60, R3, S3, S4, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, /* Filter/Env - 33 */ {"VCF-Cutoff", 0, C71, R0, S3, S4, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"VCF-Resonance", 0, C72, R0, S3, S4, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"VCF-Env", 0, C73, R0, S3, S4, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"VCF-Attack", 0, C70, R1, S3, S4, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"VCF-Decay", 0, C71, R1, S3, S4, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"VCF-Sustain", 0, C72, R1, S3, S4, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"VCF-Release", 0, C73, R1, S3, S4, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"VCF-KBD-1/3", 2, C70 - 5, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"VCF-KBD-2/3", 2, C70 + 15, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, /* Env - 42 */ {"VCA-Attack", 0, C70, R3, S3, S4, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"VCA-Decay", 0, C71, R3, S3, S4, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"VCA-Sustain", 0, C72, R3, S3, S4, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"VCA-Release", 0, C73, R3, S3, S4, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"Env-ReZero", 2, C70, R2, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"Env-Conditional", 2, C71, R2, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"Env-KBD", 2, C72, R2, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"Env-Release", 2, C73, R2, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, /* Outputs - 50 */ {"ProgVolume", 0, C80, R1, S3, S4, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"Chorus-Depth", 0, C80, R3, S3, S4, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, /* Mods - 52 */ {"LFO-Freq", 0, C40 + 10, R0, S3, S4, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"LFO-Tri", 2, C42, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/touchog.xpm", "bitmaps/buttons/touchg.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"LFO-Saw", 2, C43, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/touchog.xpm", "bitmaps/buttons/touchg.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"LFO-Ramp", 2, C44, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/touchog.xpm", "bitmaps/buttons/touchg.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"LFO-Square", 2, C45, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/touchog.xpm", "bitmaps/buttons/touchg.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"LFO-S/H", 2, C46, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/touchog.xpm", "bitmaps/buttons/touchg.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"Mod-FM1", 2, C40, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/touchog.xpm", "bitmaps/buttons/touchg.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"Mod-FM2", 2, C41, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/touchog.xpm", "bitmaps/buttons/touchg.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"Mod-FM3", 2, C42, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/touchog.xpm", "bitmaps/buttons/touchg.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"Mod-PW1", 2, C43, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/touchog.xpm", "bitmaps/buttons/touchg.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"Mod-PW2", 2, C44, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/touchog.xpm", "bitmaps/buttons/touchg.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"Mod-PW3", 2, C45, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/touchog.xpm", "bitmaps/buttons/touchg.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"Mod-Filter", 2, C46, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/touchog.xpm", "bitmaps/buttons/touchg.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"PolyMod-Osc3", 0, C40 + 10, R2, S3, S4, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"PolyMod-Env", 0, C41 + 30, R2, S3, S4, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"PolyMod-Cont", 2, C44, R2, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"PolyMod-Inv", 2, C46, R2, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"PolyMod-FM1", 2, C41, R3, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"PolyMod-FM2", 2, C42, R3, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"PolyMod-PM1", 2, C43, R3, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"PolyMod-PM2", 2, C44, R3, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"PolyMod-Filt", 2, C45, R3, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, /* Pedals - 74 */ {"Pedal1-AMT", 0, C30, R0 + 45, S3, S4, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"Pedal1-Pitch", 2, C30 - 7, R1_0 - 20, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"Pedal1-Filt", 2, C30 + 13, R1_0 - 20, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"Pedal1-Vol", 2, C30 + 3, R1_1 - 30, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"Pedal2-AMT", 0, C30, R1_2 + 60, S3, S4, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"Pedal2-Mod", 2, C30 - 7, R3, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"Pedal2-Osc2", 2, C30 + 13, R3, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, /* Main - 81 */ {"G-Mono", 2, C10 - 10, R1_0, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"G-Hold", 2, C10 + 10, R1_0, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"G-Multi", 2, C11, R1_0, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"Glide", 0, C10 - 10, R1_1, S3, S4, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"Glide-On", 2, C11, R1_1, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"Transpose1", 2, C10 - 10, R1_2, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"Transpose2", 2, C10 + 10, R1_2, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"Transpose3", 2, C11, R1_2, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_RADIOBUTTON|BRIGHTON_NOSHADOW}, {"Tuning", 0, C10 - 10, R3, S3, S4, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"ModDepth", 0, C11 - 5, R3, S3, S4, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, /* Effect option */ {"", 0, C80, R2, S3, S4, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, /* Master vol - 92 */ {"", 0, C80, R0, S3, S4, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, /* Tuning */ {"", 2, C10 - 10, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, {"", 0, C11 - 5, R0, S3, S4, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, BRIGHTON_NOTCH}, /* Memory/Midi - 94 */ /* Load/Save */ {"", 2, C20 - 4, R3, S2, S1, 0, 1, 0, "bitmaps/buttons/touchogb.xpm", "bitmaps/buttons/touchgb.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, {"", 2, C23 + 3, R3, S2, S1, 0, 1, 0, "bitmaps/buttons/touchogb.xpm", "bitmaps/buttons/touchgb.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, /* 1 - 3 */ {"", 2, C20 - 4, R1_1 - 70, S2, S1, 0, 1, 0, "bitmaps/buttons/touchogb.xpm", "bitmaps/buttons/touchgb.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, {"", 2, C21 + S2, R1_1 - 70, S2, S1, 0, 1, 0, "bitmaps/buttons/touchogb.xpm", "bitmaps/buttons/touchgb.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, {"", 2, C23 + 3, R1_1 - 70, S2, S1, 0, 1, 0, "bitmaps/buttons/touchogb.xpm", "bitmaps/buttons/touchgb.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, /* 4 - 6 */ {"", 2, C20 - 4, R21_0 - 46, S2, S1, 0, 1, 0, "bitmaps/buttons/touchogb.xpm", "bitmaps/buttons/touchgb.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, {"", 2, C21 + S2, R21_0 - 46, S2, S1, 0, 1, 0, "bitmaps/buttons/touchogb.xpm", "bitmaps/buttons/touchgb.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, {"", 2, C23 + 3, R21_0 - 46, S2, S1, 0, 1, 0, "bitmaps/buttons/touchogb.xpm", "bitmaps/buttons/touchgb.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, /* 7 - 9 */ {"", 2, C20 - 4, R21_1 - 23, S2, S1, 0, 1, 0, "bitmaps/buttons/touchogb.xpm", "bitmaps/buttons/touchgb.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, {"", 2, C21 + S2, R21_1 - 23, S2, S1, 0, 1, 0, "bitmaps/buttons/touchogb.xpm", "bitmaps/buttons/touchgb.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, {"", 2, C23 + 3, R21_1 - 23, S2, S1, 0, 1, 0, "bitmaps/buttons/touchogb.xpm", "bitmaps/buttons/touchgb.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, /* 0 */ {"", 2, C21 + S2, R3, S2, S1, 0, 1, 0, "bitmaps/buttons/touchogb.xpm", "bitmaps/buttons/touchgb.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, /* {"", 2, C23, R1_1, S2, S1, 0, 1, 0, "bitmaps/buttons/touchogb.xpm", */ /* "bitmaps/buttons/touchgb.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, */ /* {"", 2, C23, R21_0, S2, S1, 0, 1, 0, "bitmaps/buttons/touchogb.xpm", */ /* "bitmaps/buttons/touchgb.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, */ {"", 2, C23 + 3, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/touchogb.xpm", "bitmaps/buttons/touchgb.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, {"", 2, C20 - 4, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/touchogb.xpm", "bitmaps/buttons/touchgb.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, {"", 2, 0, 0, S2, S1, 0, 1, 0, "bitmaps/buttons/touchogb.xpm", "bitmaps/buttons/touchgb.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, S2, S1, 0, 1, 0, "bitmaps/buttons/touchogb.xpm", "bitmaps/buttons/touchgb.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_WITHDRAWN}, {"", 4, 790, 1020, 180, 140, 0, 1, 0, "bitmaps/images/memorymoog.xpm",0, 0}, {"", 3, C20 - 6, R1_0, 106, S1 - 10, 0, 1, 0, 0, "bitmaps/images/alphadisplay3.xpm", 0}, }; /* */ /* * This is a set of globals for the main window rendering. Again taken from * include/brighton.h */ brightonApp memMoogApp = { "memoryMoog", 0, /* no blueprint on wood background. */ "bitmaps/textures/metal6.xpm", 0, memMoogInit, memMoogConfigure, /* 3 callbacks, unused? */ MMmidiCallback, destroySynth, {6, 100, 4, 2, 5, 520, 0, 0}, 817, 310, 0, 0, 8, /* Panels */ { { "MemoryMoog", "bitmaps/blueprints/memMoog.xpm", "bitmaps/textures/metal4.xpm", BRIGHTON_STRETCH, /* flags */ 0, 0, memMoogCallback, 12, 0, 980, 550, DEVICE_COUNT, locations }, { "Keyboard", 0, "bitmaps/newkeys/nkbg.xpm", /* flags */ 0x020|BRIGHTON_STRETCH, 0, 0, keyCallback, 100, 650, 913, 340, KEY_COUNT_5OCTAVE, keysprofile2 }, { "Mods", "bitmaps/blueprints/mmmods.xpm", "bitmaps/textures/metal6.xpm", /* flags */ BRIGHTON_STRETCH, 0, 0, memMoogModCallback, 14, 656, 86, 334, 2, mods }, { "Edge", 0, "bitmaps/textures/wood4.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 988, 0, 13, 1000, 0, 0 }, { "Bar", 0, "bitmaps/textures/wood6.xpm", BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 13, 550, 975, 100, 0, 0 }, { "Edge", 0, "bitmaps/textures/wood4.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 0, 0, 12, 1000, 0, 0 }, { "Edge", 0, "bitmaps/textures/wood.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 2, 4, 9, 988, 0, 0 }, { "Edge", 0, "bitmaps/textures/wood.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 990, 4, 10, 988, 0, 0 }, } }; /*static dispatcher dispatch[DEVICE_COUNT]; */ static void postMemory(guiSynth *synth) { brightonEvent event; int i; /* * We have a couple of settings to force into their targetted values, * namely the radio buttons. * Each Osc transpose * Synth transpose * LFO waveform */ event.value = 1; if (synth->mem.param[0]) i = 0; else if (synth->mem.param[1]) i = 1; else if (synth->mem.param[2]) i = 2; else i = 3; brightonParamChange(synth->win, 0, i, &event); if (synth->mem.param[9]) i = 9; else if (synth->mem.param[10]) i = 10; else if (synth->mem.param[11]) i = 11; else i = 12; brightonParamChange(synth->win, 0, i, &event); if (synth->mem.param[18]) i = 18; else if (synth->mem.param[19]) i = 19; else if (synth->mem.param[20]) i = 20; else i = 21; brightonParamChange(synth->win, 0, i, &event); if (synth->mem.param[53]) i = 53; else if (synth->mem.param[54]) i = 54; else if (synth->mem.param[55]) i = 55; else if (synth->mem.param[56]) i = 56; else i = 57; brightonParamChange(synth->win, 0, i, &event); if (synth->mem.param[86]) i = 86; else if (synth->mem.param[87]) i = 87; else i = 88; brightonParamChange(synth->win, 0, i, &event); } int memoogloadMemory(guiSynth *synth, char *algo, char *name, int location, int active, int skip, int flags) { loadMemory(synth, "memoryMoog", 0, location, synth->mem.active, 0, 0); postMemory(synth); return(0); } static int MMmidiCallback(brightonWindow *win, int controller, int value, float n) { guiSynth *synth = findSynth(global.synths, win); printf("midi callback: %x, %i\n", controller, value); switch(controller) { case MIDI_PROGRAM: printf("midi program: %x, %i\n", controller, value); synth->location = value + synth->bank; loadMemory(synth, "memoryMoog", 0, synth->location, synth->mem.active, 0, 0); break; case MIDI_BANK_SELECT: printf("midi banksel: %x, %i\n", controller, value); synth->bank = value + 10; synth->location = (synth->location % 10) + synth->bank; loadMemory(synth, "memoryMoog", 0, synth->location, synth->mem.active, 0, 0); break; } postMemory(synth); return(0); } static int memMoogModCallback(brightonWindow *win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); /*printf("memMoogModCallback(%x, %i, %i, %f)\n", synth, panel, index, value); */ /* * If this is controller 0 it is the frequency control, otherwise a * generic controller 1. The depth of the bend wheel is a parameter, so * we need to scale the value here. */ if (index == 0) { float bend = synth->mem.param[89]; /* * Value is between 0 and 1 latching at 0.5. Have to scale the value * and subtrace if from the mid point */ bristolMidiSendMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_PITCH, 0, (int) (((0.5 - bend / 2) + (value * bend)) * C_RANGE_MIN_1)); } else { bristolMidiControl(global.controlfd, synth->midichannel, 0, 1, ((int) (value * C_RANGE_MIN_1)) >> 7); } return(0); } static int memMoogMidiSendMsg(void *synth, int fd, int chan, int c, int o, int v) { /*printf("%i, %i, %i\n", c, o, v); */ bristolMidiSendMsg(fd, chan, c, o, v); return(0); } static void memMoogMemory(guiSynth *synth, int fd, int chan, int c, int o, int v) { int cmem = synth->location; if (synth->flags & MEM_LOADING) return; switch (c) { default: case 0: synth->location = synth->location * 10 + o; if (synth->location >= 1000) synth->location = o; if (loadMemory(synth, "memoryMoog", 0, synth->location, synth->mem.active, 0, BRISTOL_STAT) < 0) displayPanelText(synth, "FRE", synth->location, 0, DISPLAY); else displayPanelText(synth, "PRG", synth->location, 0, DISPLAY); break; case 1: loadMemory(synth, "memoryMoog", 0, synth->location, synth->mem.active, 0, 0); postMemory(synth); displayPanelText(synth, "PRG", synth->location, 0, DISPLAY); synth->location = 0; break; case 2: saveMemory(synth, "memoryMoog", 0, synth->location, 0); displayPanelText(synth, "PRG", synth->location, 0, DISPLAY); synth->location = 0; break; case 3: while (loadMemory(synth, "memoryMoog", 0, --synth->location, synth->mem.active, 0, 0) < 0) { if (synth->location < 0) synth->location = 1000; if (synth->location == cmem) break; } postMemory(synth); displayPanelText(synth, "PRG", synth->location, 0, DISPLAY); break; case 4: while (loadMemory(synth, "memoryMoog", 0, ++synth->location, synth->mem.active, 0, 0) < 0) { if (synth->location > 999) synth->location = -1; if (synth->location == cmem) break; } postMemory(synth); displayPanelText(synth, "PRG", synth->location, 0, DISPLAY); break; } } static void memMoogMidi(guiSynth *synth, int fd, int chan, int c, int o, int v) { int newchan; if ((synth->flags & OPERATIONAL) == 0) return; if (c == 1) { if ((newchan = synth->midichannel - 1) < 0) { synth->midichannel = 0; displayPanelText(synth, "MIDI", synth->midichannel + 1, 0, DISPLAY); return; } } else { if ((newchan = synth->midichannel + 1) >= 15) { synth->midichannel = 15; displayPanelText(synth, "MIDI", synth->midichannel + 1, 0, DISPLAY); return; } } if (global.libtest == 0) { bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_MIDICHANNEL|newchan); } synth->midichannel = newchan; displayPanelText(synth, "MIDI", synth->midichannel + 1, 0, DISPLAY); } /* * For the sake of ease of use, links have been placed here to be called * by any of the devices created. They would be better in some other file, * perhaps with this as a dispatch. * * Param refers to the device index in the locations table given below. */ static int memMoogCallback(brightonWindow * win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); int sendvalue; /*printf("memMoogCallback(%i, %f): %x\n", index, value, synth); */ if (synth == 0) return(0); if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0)) return(0); if (memMoogApp.resources[panel].devlocn[index].to == 1) sendvalue = value * C_RANGE_MIN_1; else sendvalue = value; synth->mem.param[index] = value; if ((!global.libtest) || (index >= ACTIVE_DEVS)) synth->dispatch[index].routine(synth, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #ifdef DEBUG else printf("dispatch[%x,%i](%i, %i, %i, %i, %i)\n", synth, index, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #endif return(0); } static void memMoogOsc3LFO(guiSynth *synth, int fd, int chan, int c, int o, int v) { int value = 0; if (v == 0) { /* * LFO off, find the desired transpose */ if (synth->mem.param[18]) value = 0; else if (synth->mem.param[19]) value = 1; else if (synth->mem.param[20]) value = 2; else if (synth->mem.param[21]) value = 3; } else { /* * LFO on */ bristolMidiSendMsg(fd, chan, 2, 1, 10); return; } bristolMidiSendMsg(fd, chan, 2, 1, value); } static void memMoogOscTranspose(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; int value; if (synth->flags & MEM_LOADING) return; /* * We need to configure the radio set and then request the tranpose value. */ if (synth->dispatch[c].other2) { synth->dispatch[c].other2 = 0; return; } if (synth->dispatch[c].other1 != -1) { event.type = BRIGHTON_FLOAT; synth->dispatch[c].other2 = 1; if (synth->dispatch[c].other1 != o) event.value = 0; else event.value = 1; brightonParamChange(synth->win, synth->panel, synth->dispatch[c].other1, &event); } synth->dispatch[c].other1 = o; if (o > 17) { /* * Osc 3 - tranpose depends on mem[27] */ if (synth->mem.param[27]) return; else value = o - 18; } else if (o > 4) value = o - 9; else value = o; bristolMidiSendMsg(fd, chan, c, 1, value); } static void memMoogLFOWave(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; if (synth->flags & MEM_LOADING) return; /* * We need to configure the radio set and then request the tranpose value. */ if (synth->dispatch[c].other2) { synth->dispatch[c].other2 = 0; return; } if (synth->dispatch[c].other1 != -1) { event.type = BRIGHTON_FLOAT; synth->dispatch[c].other2 = 1; if (synth->dispatch[c].other1 != o) event.value = 0; else event.value = 1; brightonParamChange(synth->win, synth->panel, synth->dispatch[c].other1, &event); } synth->dispatch[c].other1 = o; bristolMidiSendMsg(fd, chan, 126, 4, o - 53); } static void memMoogTranspose(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; if (synth->flags & MEM_LOADING) return; /* * We need to configure the radio set and then request the tranpose value. */ if (synth->dispatch[c].other2) { synth->dispatch[c].other2 = 0; return; } if (synth->dispatch[c].other1 != -1) { event.type = BRIGHTON_FLOAT; synth->dispatch[c].other2 = 1; if (synth->dispatch[c].other1 != o) event.value = 0; else event.value = 1; brightonParamChange(synth->win, synth->panel, synth->dispatch[c].other1, &event); } synth->dispatch[c].other1 = o; synth->transpose = 24 + (o - 86) * 12; } static void multiTune(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; /* * Configures all the tune settings to zero (ie, 0.5). Do the Osc-A first, * since it is not visible, and then request the GUI to configure Osc-B. */ /* bristolMidiSendMsg(fd, synth->sid, 0, 2, 8192); */ event.type = BRIGHTON_FLOAT; event.value = 0.5; brightonParamChange(synth->win, synth->panel, 13, &event); brightonParamChange(synth->win, synth->panel, 22, &event); brightonParamChange(synth->win, synth->panel, 94, &event); } static void keyHold(guiSynth *synth) { if ((synth->flags & OPERATIONAL) == 0) return; if (synth->mem.param[82]) bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_HOLD|1); else bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_HOLD|0); } static void memoryGlide(guiSynth *synth, int fd, int chan, int c, int o, int v) { if ((synth->flags & OPERATIONAL) == 0) return; if (c == 126) { if (synth->mem.param[85] != 0) bristolMidiSendMsg(fd, chan, 126, 0, v); return; } if (v != 0) bristolMidiSendMsg(fd, chan, 126, 0, (int) (synth->mem.param[84] * C_RANGE_MIN_1)); else bristolMidiSendMsg(fd, chan, 126, 0, 0); } static void filterTrack(guiSynth *synth, int fd, int chan, int c, int o, int v) { float value; value = (synth->mem.param[40] + synth->mem.param[41] * 2) * C_RANGE_MIN_1 / 3; bristolMidiSendMsg(fd, chan, 3, 3, (int) value); } static void jointRelease(guiSynth *synth, int fd, int chan, int c, int o, int v) { if (c == 45) { if (synth->mem.param[49] == 0) bristolMidiSendMsg(fd, chan, 6, 3, v); return; } if (v == 0) bristolMidiSendMsg(fd, chan, 6, 3, (int) (synth->mem.param[45] * C_RANGE_MIN_1)); else bristolMidiSendMsg(fd, chan, 6, 3, 10); } /* * Any location initialisation required to run the callbacks. For bristol, this * will connect to the engine, and give it some base parameters. * May need to generate some application specific menus. * Will also then make specific requests to some of the devices to alter their * rendering. */ static int memMoogInit(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); dispatcher *dispatch; int i; if (synth == 0) { synth = findSynth(global.synths, 0); if (synth == 0) { printf("cannot init\n"); return(0); } } synth->win = win; printf("Initialise the memMoog link to bristol: %p\n", synth->win); synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float)); synth->mem.count = DEVICE_COUNT; synth->mem.active = ACTIVE_DEVS; synth->dispatch = (dispatcher *) brightonmalloc(DEVICE_COUNT * sizeof(dispatcher)); dispatch = synth->dispatch; /* * We really want to have three connection mechanisms. These should be * 1. Unix named sockets. * 2. UDP sockets. * 3. MIDI pipe. */ synth->voices = 6; if (!global.libtest) if ((synth->sid = initConnection(&global, synth)) < 0) return(-1); for (i = 0; i < DEVICE_COUNT; i++) synth->dispatch[i].routine = memMoogMidiSendMsg; /* Osc - first transpose options */ dispatch[0].controller = 0; dispatch[0].operator = 0; dispatch[1].controller = 0; dispatch[1].operator = 1; dispatch[2].controller = 0; dispatch[2].operator = 2; dispatch[3].controller = 0; dispatch[3].operator = 3; dispatch[9].controller = 1; dispatch[9].operator = 9; dispatch[10].controller = 1; dispatch[10].operator = 10; dispatch[11].controller = 1; dispatch[11].operator = 11; dispatch[12].controller = 1; dispatch[12].operator = 12; dispatch[18].controller = 2; dispatch[18].operator = 18; dispatch[19].controller = 2; dispatch[19].operator = 19; dispatch[20].controller = 2; dispatch[20].operator = 20; dispatch[21].controller = 2; dispatch[21].operator = 21; dispatch[0].routine = dispatch[1].routine = dispatch[2].routine = dispatch[3].routine = dispatch[9].routine = dispatch[10].routine = dispatch[11].routine = dispatch[12].routine = dispatch[18].routine = dispatch[19].routine = dispatch[20].routine = dispatch[21].routine = (synthRoutine) memMoogOscTranspose; /* Osc Options. */ dispatch[4].controller = 1; dispatch[4].operator = 7; dispatch[5].controller = 0; dispatch[5].operator = 0; dispatch[6].controller = 0; dispatch[6].operator = 6; dispatch[7].controller = 0; dispatch[7].operator = 4; dispatch[8].controller = 0; dispatch[8].operator = 5; /* Osc 2 */ dispatch[13].controller = 1; dispatch[13].operator = 2; dispatch[14].controller = 1; dispatch[14].operator = 0; dispatch[15].controller = 1; dispatch[15].operator = 6; dispatch[16].controller = 1; dispatch[16].operator = 4; dispatch[17].controller = 1; dispatch[17].operator = 5; /* Osc 3 */ dispatch[22].controller = 2; dispatch[22].operator = 2; dispatch[23].controller = 2; dispatch[23].operator = 0; dispatch[24].controller = 2; dispatch[24].operator = 6; dispatch[25].controller = 2; dispatch[25].operator = 4; dispatch[26].controller = 2; dispatch[26].operator = 5; /* LFO/KBD */ dispatch[27].controller = 126; dispatch[27].operator = 1; dispatch[27].routine = (synthRoutine) memMoogOsc3LFO; dispatch[28].controller = 126; dispatch[28].operator = 7; /* Mixer */ dispatch[29].controller = 126; dispatch[29].operator = 30; dispatch[30].controller = 126; dispatch[30].operator = 31; dispatch[31].controller = 126; dispatch[31].operator = 32; dispatch[32].controller = 126; dispatch[32].operator = 33; /* Filter */ dispatch[33].controller = 3; dispatch[33].operator = 0; dispatch[34].controller = 3; dispatch[34].operator = 1; dispatch[35].controller = 126; dispatch[35].operator = 17; /* Filter Env */ dispatch[36].controller = 4; dispatch[36].operator = 0; dispatch[37].controller = 4; dispatch[37].operator = 1; dispatch[38].controller = 4; dispatch[38].operator = 2; dispatch[39].controller = 4; dispatch[39].operator = 3; /* Filter Key tracking */ dispatch[40].controller = 126; dispatch[40].operator = 1; dispatch[41].controller = 126; dispatch[41].operator = 2; dispatch[40].routine = dispatch[41].routine = (synthRoutine) filterTrack; /* AMP ENV */ dispatch[42].controller = 6; dispatch[42].operator = 0; dispatch[43].controller = 6; dispatch[43].operator = 1; dispatch[44].controller = 6; dispatch[44].operator = 2; dispatch[45].controller = 45; dispatch[45].operator = 3; dispatch[45].routine = (synthRoutine) jointRelease; /* AMP ENV Options */ dispatch[46].controller = 6; dispatch[46].operator = 6; dispatch[47].controller = 6; dispatch[47].operator = 7; dispatch[48].controller = 6; dispatch[48].operator = 8; dispatch[49].controller = 126; dispatch[49].operator = 101; dispatch[49].routine = (synthRoutine) jointRelease; /* Prog volume */ dispatch[50].controller = 6; dispatch[50].operator = 4; /* Aux? We don't have aux out or headphones, so use this for panning. */ dispatch[51].controller = 100; dispatch[51].operator = 0; /* Mods - LFO freq first */ dispatch[52].controller = 8; dispatch[52].operator = 0; dispatch[53].controller = 3; dispatch[53].operator = 53; dispatch[54].controller = 3; dispatch[54].operator = 54; dispatch[55].controller = 3; dispatch[55].operator = 55; dispatch[56].controller = 3; dispatch[56].operator = 56; dispatch[57].controller = 3; dispatch[57].operator = 57; dispatch[53].routine = dispatch[54].routine = dispatch[55].routine = dispatch[56].routine = dispatch[57].routine = (synthRoutine) memMoogLFOWave; /* LFO Routing: */ dispatch[58].controller = 126; dispatch[58].operator = 8; dispatch[59].controller = 126; dispatch[59].operator = 9; dispatch[60].controller = 126; dispatch[60].operator = 10; dispatch[61].controller = 126; dispatch[61].operator = 11; dispatch[62].controller = 126; dispatch[62].operator = 12; dispatch[63].controller = 126; dispatch[63].operator = 13; dispatch[64].controller = 126; dispatch[64].operator = 14; /* Poly mods */ dispatch[65].controller = 126; dispatch[65].operator = 20; dispatch[66].controller = 126; dispatch[66].operator = 21; dispatch[67].controller = 126; dispatch[67].operator = 27; dispatch[68].controller = 126; dispatch[68].operator = 28; /* Poly Routing */ dispatch[69].controller = 126; dispatch[69].operator = 22; dispatch[70].controller = 126; dispatch[70].operator = 23; dispatch[71].controller = 126; dispatch[71].operator = 24; dispatch[72].controller = 126; dispatch[72].operator = 25; dispatch[73].controller = 126; dispatch[73].operator = 26; /* Pedals */ dispatch[74].controller = 126; dispatch[74].operator = 40; dispatch[75].controller = 126; dispatch[75].operator = 41; dispatch[76].controller = 126; dispatch[76].operator = 42; dispatch[77].controller = 126; dispatch[77].operator = 43; dispatch[78].controller = 126; dispatch[78].operator = 44; dispatch[79].controller = 126; dispatch[79].operator = 45; dispatch[80].controller = 126; dispatch[80].operator = 46; /* Main - Mono/Hold/Multi */ dispatch[81].controller = 126; dispatch[81].operator = 2; dispatch[82].routine = (synthRoutine) keyHold; dispatch[83].controller = 126; dispatch[83].operator = 6; /* Glide */ dispatch[84].controller = 126; dispatch[84].operator = 0; dispatch[85].controller = 127; dispatch[85].operator = 0; dispatch[84].routine = dispatch[85].routine = (synthRoutine) memoryGlide; /* Transpose */ dispatch[86].controller = 4; dispatch[86].operator = 86; dispatch[87].controller = 4; dispatch[87].operator = 87; dispatch[88].controller = 4; dispatch[88].operator = 88; dispatch[86].routine = dispatch[87].routine = dispatch[88].routine = (synthRoutine) memMoogTranspose; /* Depth controls */ dispatch[89].controller = 126; dispatch[89].operator = 47; dispatch[90].controller = 126; dispatch[90].operator = 3; /* Effects depth */ dispatch[91].controller = 100; dispatch[91].operator = 1; /* Master, Autotune and tune */ dispatch[92].controller = 126; dispatch[92].operator = 16; dispatch[93].routine = (synthRoutine) multiTune; dispatch[94].controller = 126; dispatch[94].operator = 1; dispatch[MEM_START +0].routine = dispatch[MEM_START +1].routine = dispatch[MEM_START +2].routine = dispatch[MEM_START +3].routine = dispatch[MEM_START +4].routine = dispatch[MEM_START +5].routine = dispatch[MEM_START +6].routine = dispatch[MEM_START +7].routine = dispatch[MEM_START +8].routine = dispatch[MEM_START +9].routine = dispatch[MEM_START +10].routine = dispatch[MEM_START +11].routine = dispatch[MEM_START +12].routine = dispatch[MEM_START +13].routine = (synthRoutine) memMoogMemory; dispatch[MEM_START + 0].controller = 1; dispatch[MEM_START + 1].controller = 2; dispatch[MEM_START + 2].operator = 1; dispatch[MEM_START + 3].operator = 2; dispatch[MEM_START + 4].operator = 3; dispatch[MEM_START + 5].operator = 4; dispatch[MEM_START + 6].operator = 5; dispatch[MEM_START + 7].operator = 6; dispatch[MEM_START + 8].operator = 7; dispatch[MEM_START + 9].operator = 8; dispatch[MEM_START + 10].operator = 9; dispatch[MEM_START + 11].operator = 0; dispatch[MEM_START + 12].controller = 4; dispatch[MEM_START + 13].controller = 3; dispatch[MIDI_START].controller = 1; dispatch[MIDI_START + 1].controller = 2; dispatch[MIDI_START].routine = dispatch[MIDI_START + 1].routine = (synthRoutine) memMoogMidi; dispatch[OSC_1_RADIO].other1 = -1; dispatch[OSC_2_RADIO].other1 = -1; dispatch[OSC_3_RADIO].other1 = -1; /* Put in diverse defaults settings */ bristolMidiSendMsg(global.controlfd, synth->sid, 7, 0, 16383); /* Tune osc-1 */ bristolMidiSendMsg(global.controlfd, synth->sid, 0, 2, 8192); /* Gain on filter env - changed to fixed MOD on filter, variable Env. Then */ /* changed to fixed env with in-algo filter gain... */ bristolMidiSendMsg(global.controlfd, synth->sid, 3, 4, 4); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 2, C_RANGE_MIN_1); bristolMidiSendMsg(global.controlfd, synth->sid, 4, 4, C_RANGE_MIN_1); /* Filter env does not track velocity */ bristolMidiSendMsg(global.controlfd, synth->sid, 4, 5, 0); /* Waveform subosc */ /* bristolMidiSendMsg(global.controlfd, synth->sid, 1, 0, C_RANGE_MIN_1); */ /* bristolMidiSendMsg(global.controlfd, synth->sid, 1, 6, C_RANGE_MIN_1); */ /* LFO Env parameters. */ /* bristolMidiSendMsg(global.controlfd, synth->sid, 8, 1, 12000); */ /* bristolMidiSendMsg(global.controlfd, synth->sid, 8, 2, 16383); */ /* bristolMidiSendMsg(global.controlfd, synth->sid, 8, 3, 0); */ /* bristolMidiSendMsg(global.controlfd, synth->sid, 8, 4, 16383); */ /* bristolMidiSendMsg(global.controlfd, synth->sid, 8, 5, 0); */ return(0); } /* * This will be called to make any routine specific parameters available. */ static int memMoogConfigure(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); brightonEvent event; if (synth == 0) { printf("problems going operational\n"); return(-1); } if (synth->flags & OPERATIONAL) return(0); printf("going operational\n"); synth->flags |= OPERATIONAL; synth->keypanel = 1; synth->keypanel2 = -1; synth->transpose = 48; synth->bank = 0; event.value = 1; /* Poly */ loadMemory(synth, "memoryMoog", 0, synth->location, synth->mem.active, 0, 0); postMemory(synth); brightonPut(win, "bitmaps/blueprints/memMoogshade.xpm", 0, 0, win->width, win->height); /* * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only * occurs on first paint, so we suppress the first paint, and then request * an expose here. */ event.type = BRIGHTON_EXPOSE; event.intvalue = 1; brightonParamChange(synth->win, KEY_PANEL, -1, &event); event.type = BRIGHTON_FLOAT; event.value = 0.5; brightonParamChange(synth->win, 0, 93, &event); event.value = 1.0; brightonParamChange(synth->win, 0, 92, &event); /* Volume */ brightonParamChange(synth->win, 0, 74, &event); /* pedalamt1 */ brightonParamChange(synth->win, 0, 78, &event); /* pedalamt2 */ configureGlobals(synth); synth->loadMemory = (loadRoutine) memoogloadMemory; return(0); } bristol-0.60.11/brighton/brightonMini.h0000644000175000017500000001114411746476475014722 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #ifndef BRIGHTONMINI_H #define BRIGHTONMINI_H #include "brighton.h" #include "brightoninternals.h" #include "bristol.h" #define BRIGHTON_POLYPHONIC 0 #define BRIGHTON_LNP 1 #define BRIGHTON_HNP 2 extern int configureGlobals(); extern int initConnection(); extern void cleanupBristol(); extern void cleanupBristolQuietly(); extern int bristolMidiSendControlMsg(); extern int bristolMidiSendNRP(); extern int bristolMidiSendRP(); extern int bristolMidiSendMsg(); extern int destroySynth(brightonWindow *); typedef int (*synthRoutine)(void *, int, int, int, int, int); typedef int (*saveRoutine)(void *, char *, char *, int, int); typedef int (*loadRoutine)(void *, char *, char *, int, int, int, int); typedef struct miniDispatch { int controller; int operator; int other1; int other2; synthRoutine routine; } dispatcher; typedef struct Memory { char algo[32]; char name[32]; short count; short vers; short active; short pad; float *param; } memory; #define BRISTOL_NOCALLS 0x01 #define BRISTOL_STAT 0x02 #define BRISTOL_FORCE 0x04 #define BRISTOL_SID2 0x08 #define BRISTOL_SEQLOAD 0x10 #define BRISTOL_SEQFORCE 0x20 #define OPERATIONAL 0x00000001 #define BANK_SELECT 0x00000002 #define MEM_LOADING 0x00000004 #define SUPPRESS 0x00000008 #define NO_KEYTRACK 0x00000010 #define REQ_MIDI_DEBUG 0x00000020 #define MIDI_NRP 0x00000040 #define REQ_MIDI_DEBUG2 0x00000080 #define REQ_EXIT 0x00000100 #define REQ_FORWARD 0x00000200 #define REQ_LOCAL_FORWARD 0x00000400 #define REQ_REMOTE_FORWARD 0x00000800 #define REQ_DEBUG_MASK 0x0000f000 #define REQ_DEBUG_1 0x00001000 #define REQ_DEBUG_2 0x00002000 #define REQ_DEBUG_3 0x00004000 #define REQ_DEBUG_4 0x00008000 #define LADI_ENABLE 0x00010000 #define GUI_NRP 0x00020000 #define NO_LATCHING_KEYS 0x00040000 typedef struct GuiSynth { struct GuiSynth *next, *last; unsigned int flags; char name[32]; int sid; int sid2; /* for GUIs with dual manual connections. */ int midichannel; int velocity; int synthtype; int voices; brightonWindow *win; int mbi; int bank; int location; int panel; int transpose; memory mem; memory seq1; memory seq2; brightonApp *resources; dispatcher *dispatch; struct guiSynth *second; /* Dual manual keyboards */ struct guimain *manual; /* Dual manual keyboards */ int gain; int detune; int pwd; int keypanel; int keypanel2; int lowkey; int highkey; int glide; int lwf; int notepref; int notetrig; int legatovelocity; saveRoutine saveMemory; loadRoutine loadMemory; int firstDev; int cmem; int lmem; /* LADI support */ int ladimode; int ladimem; char *ladiStateFile; } guiSynth; #define BRIGHTON_NOENGINE 0x80000000 #define BRIGHTON_NRP 0x40000000 typedef struct guiMain { unsigned int flags; char *home; int controlfd; int enginePID; int libtest; int voices; guiSynth *synths; char *host; int port; int manualfd; struct guiMain *manual; } guimain; extern guiSynth *findSynth(guiSynth *, brightonWindow *); extern int bristolMemoryImport(int, char *, char *); extern int bristolMemoryExport(int, char *, char *); extern int loadMemory(guiSynth *, char *, char *, int, int, int, int); extern int loadSequence(memory *, char *, int, int); extern int chordInsert(arpeggiatorMemory *, int, int); extern int seqInsert(arpeggiatorMemory *, int, int); extern int fillSequencer(guiSynth *, arpeggiatorMemory *, int); extern int saveSequence(guiSynth *, char *, int, int); extern int saveMemory(guiSynth *, char *, char *, int, int); extern int displayText(guiSynth *, char *, int, int); extern void displayPanel(guiSynth *, char *, int, int, int); extern int displayPanelText(guiSynth *, char *, int, int, int); extern void brightonReadConfiguration(brightonWindow *, brightonApp *, int, char *, char *); extern void brightonWriteConfiguration(brightonWindow *, char *, int, char *); extern int doAlarm(); #endif /* BRIGHTONMINI_H */ bristol-0.60.11/brighton/brightonPoly800.c0000644000175000017500000017162511746476475015207 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* * We have 64 params available of which 50 are from the original and 12 others * are defined to be: * * chorus params 47 58 68 78 * LFO single multi 85 * Osc PW - 1&2 34 36 * Osc PWM - 1&2 35 37 * Osc Sync - 2 28 * Env velocities 57 * Detune globally 38 * * DE 67/77 are currently unused. Add Glide? * * We have one more from seq clock 88 := config OMNI * * Poly/Chord/Hold options OK * * Check Sync OK * * Bend Implemented but check dynamics OK * * Clear up diags output REQ * * Check all the parameters audibly. * * Check depth on current detune * * Check out click on note off events. */ #include #include "brighton.h" #include "brightonMini.h" #include "brightoninternals.h" static int poly800Init(); static int poly800Configure(); static int poly800Callback(brightonWindow *, int, int, float); static int midiCallback(brightonWindow *, int, int, float); static int poly800KeyCallback(brightonWindow *, int, int, float); extern guimain global; static guimain manual; #include "brightonKeys.h" #define SYNTH_NAME synth->resources->name #define ACTIVE_DEVS 89 #define MEM_MGT ACTIVE_DEVS #define MIDI_MGT (MEM_MGT + 12) #define ENTRY_POT 18 #define MODS_COUNT 32 #define DEVICE_COUNT (ACTIVE_DEVS + MODS_COUNT) #define KEY_PANEL 1 #define MODS_PANEL 2 #define DISPLAY_DEV (MODS_COUNT - 6) #define MODE_SINGLE 0 #define MODE_SPLIT 1 #define MODE_LAYER 2 static int dc, mbh = 0, crl = 0; /* * This structure is for device definition. The structure is defined in * include/brighton.h, further definitions in brighton/brightonDevtable.h and * include/brightoninternals.h * * typedef int (*brightonCallback)(int, float); * typedef struct BrightonLocations { * int device; 0=rotary, 1=scale, etc. * float relx, rely; relative position with regards to 1000 by 1000 window * float relw, relh; relative height. * int from, to; * brightonCallback callback; specific to this dev * char *image; bitmap. If zero take a device default. * int flags; * } brightonLocations; * * This example is for a poly800Bristol type synth interface. */ #define S1 418 #define S2 312 #define S3 228 #define S4 644 #define S5 262 #define S6 558 #define S7 644 #define S8 600 #define D1 42 #define W1 33 /* * We really need to define parameter types and ranges here to make the * interface complete. For example, the midi channels only go from 1 to 16 and * when selected as the input then the pot should configure this range. * * Similarly, if this is a button it should be 0 for the first half and 1 for * the second half. * * This only applies to the displays, not to the parameters. * * Continuous controllers actually deliver a value between 0 and 1 to the * engine - the Inc/Dec buttons actually do the steps emulating the original * by going from 0.0 to 1.0 in the given number of stages. The pot, however, * is continuous. Memories save the floating point value between 0 and 1.0, * the stepped values are firstly put on the display and sent to the engine * as the last stage of interpretation. * * The stepped controllers deliver integer values along the given range. */ #define POLY800_CONTINUOUS 0 #define POLY800_STEPPED 1 #define P800_INACTIVE 0x001 /* Skip this parameter */ #define P800_INHERIT_PRI 0x002 /* Copy from the primary layer when loading */ #define P800_INACTIVE_PEER 0x004 /* Not active in upper (second load) layer */ #define P800_USE_PRI 0x008 /* Take value from primary only */ #define P800_ALWAYS 0x010 /* All editing in double/split mode */ #define P800_INHERIT_SEC 0x020 /* Copy to the primary layer when changing */ #define P800_NO_LOAD 0x040 /* All editing in double/split mode */ #define P800_REZERO 0x080 /* Normalise signal to engine back to zero */ typedef struct P800range { int type; float min; float max; int op; int cont; /* link to the engine code */ int flags; } p800range; /* * STEPPED controllers are sent as that integer value. CONTINUOUS are sent * as values from 0 to 1.0 but the range values specify how they are displayed * on the LEDs. * * We only use 64 parameters, numbered 11 through 88 using just 8 digits. Of * these 50 are selectable from the 'membrane', the rest from the prog digits. * * The Mods: */ p800range poly800Range[DEVICE_COUNT] = { {POLY800_STEPPED, 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry */ {POLY800_STEPPED, 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry */ {POLY800_STEPPED, 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry */ {POLY800_STEPPED, 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry */ {POLY800_STEPPED, 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry */ {POLY800_STEPPED, 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry */ {POLY800_STEPPED, 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry */ {POLY800_STEPPED, 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry */ {POLY800_STEPPED, 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry */ {POLY800_STEPPED, 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry */ {POLY800_STEPPED, 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry 10 */ {POLY800_STEPPED, 1, 3, 0, 101, P800_REZERO}, /* Octave shim */ {POLY800_CONTINUOUS, 1, 2, 0, 102, P800_REZERO}, /* Waveform shim */ {POLY800_CONTINUOUS, 0, 1, 0, 4, 0}, /* 16 */ {POLY800_CONTINUOUS, 0, 1, 0, 5, 0}, /* 8 */ {POLY800_CONTINUOUS, 0, 1, 0, 6, 0}, /* 4 */ {POLY800_CONTINUOUS, 0, 1, 0, 7, 0}, /* 2 */ {POLY800_CONTINUOUS, 0, 31, 4, 9, 0}, /* Level = gain of env */ {POLY800_STEPPED, 1, 2, 126, 10, P800_REZERO}, /* Double */ {POLY800_STEPPED, 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry */ {POLY800_STEPPED, 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry 20 */ {POLY800_STEPPED, 1, 3, 1, 101, P800_REZERO}, /* Octave */ {POLY800_CONTINUOUS, 1, 2, 1, 102, P800_REZERO}, /* Waveform */ {POLY800_CONTINUOUS, 0, 1, 1, 4, 0}, /* 16 */ {POLY800_CONTINUOUS, 0, 1, 1, 5, 0}, /* 8 */ {POLY800_CONTINUOUS, 0, 1, 1, 6, 0}, /* 4 */ {POLY800_CONTINUOUS, 0, 1, 1, 7, 0}, /* 2 */ {POLY800_CONTINUOUS, 0, 31, 5, 9, 0}, /* Level = gain of env */ {POLY800_STEPPED, 0, 1, 126, 13, 0}, /* DE Sync */ {POLY800_STEPPED, 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry */ {POLY800_STEPPED, 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry 30 */ {POLY800_STEPPED, 0, 12, 2, 102, P800_REZERO}, /* Interval */ {POLY800_CONTINUOUS, 0, 3, 1, 9, 0}, /* Detune - shim to half a semi */ {POLY800_CONTINUOUS, 0, 15, 3, 0, 0}, /* Noise level - shim it down? */ {POLY800_CONTINUOUS, 0, 99, 0, 13, 0}, /* DCO1 PW entry */ {POLY800_CONTINUOUS, 0, 99, 126, 4, 0}, /* DCO1 PWM entry */ {POLY800_CONTINUOUS, 0, 99, 1, 13, 0}, /* DCO2 PW entry */ {POLY800_CONTINUOUS, 0, 99, 126, 5, 0}, /* DCO2 PWM entry */ {POLY800_CONTINUOUS, 0, 99, 16, 101, 0}, /* Detune entry */ {POLY800_STEPPED, 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry */ {POLY800_STEPPED, 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry 40 */ {POLY800_CONTINUOUS, 0, 99, 2, 0, 0}, /* Filter Cutoff */ {POLY800_CONTINUOUS, 0, 15, 2, 1, 0}, /* Filter res */ {POLY800_CONTINUOUS, 0, 2, 2, 3, 0}, /* KBD tracking */ {POLY800_STEPPED, 1, 2, 126, 20, P800_REZERO}, /* Env polarity */ {POLY800_CONTINUOUS, 0, 15, 126, 21, 0}, /* Env Amount */ {POLY800_STEPPED, 1, 2, 6, 12, P800_REZERO}, /* Env Trigger */ {POLY800_CONTINUOUS, 0, 99, 100, 3, 0}, /* Chorus P-3 Multi */ {POLY800_STEPPED, 0, 1, 100, 3, 0}, /* Chorus On/Off shim */ {POLY800_STEPPED, 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry */ {POLY800_STEPPED, 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry 50 */ {POLY800_CONTINUOUS, 0, 31, 4, 1, 0}, /* Env-1 */ {POLY800_CONTINUOUS, 0, 31, 4, 3, 0}, /* Env-1 */ {POLY800_CONTINUOUS, 0, 31, 4, 4, 0}, /* Env-1 */ {POLY800_CONTINUOUS, 0, 31, 4, 5, 0}, /* Env-1 */ {POLY800_CONTINUOUS, 0, 31, 4, 6, 0}, /* Env-1 */ {POLY800_CONTINUOUS, 0, 31, 4, 7, 0}, /* Env-1 */ {POLY800_STEPPED, 0, 7, 126, 101, 0}, /* Env-1 touch */ {POLY800_CONTINUOUS, 0, 99, 100, 0, 0}, /* DE 58 Chorus-0 entry */ {POLY800_STEPPED, 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry */ {POLY800_STEPPED, 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry 60 */ {POLY800_CONTINUOUS, 0, 31, 5, 1, 0}, /* Env-2 */ {POLY800_CONTINUOUS, 0, 31, 5, 3, 0}, /* Env-2 */ {POLY800_CONTINUOUS, 0, 31, 5, 4, 0}, /* Env-2 */ {POLY800_CONTINUOUS, 0, 31, 5, 5, 0}, /* Env-2 */ {POLY800_CONTINUOUS, 0, 31, 5, 6, 0}, /* Env-2 */ {POLY800_CONTINUOUS, 0, 31, 5, 7, 0}, /* Env-2 */ {POLY800_CONTINUOUS, 0, 1, 126, 0, 0}, /* Glide */ {POLY800_CONTINUOUS, 0, 99, 100, 1, 0}, /* DE 58 Chorus-1 entry */ {POLY800_STEPPED, 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry */ {POLY800_STEPPED, 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry 70 */ {POLY800_CONTINUOUS, 0, 31, 6, 1, 0}, /* Env-3 */ {POLY800_CONTINUOUS, 0, 31, 6, 3, 0}, /* Env-3 */ {POLY800_CONTINUOUS, 0, 31, 6, 4, 0}, /* Env-3 */ {POLY800_CONTINUOUS, 0, 31, 6, 5, 0}, /* Env-3 */ {POLY800_CONTINUOUS, 0, 31, 6, 6, 0}, /* Env-3 */ {POLY800_CONTINUOUS, 0, 31, 6, 7, 0}, /* Env-3 */ {POLY800_STEPPED, 0, 1, 6, 10, 0}, /* FREE */ {POLY800_CONTINUOUS, 0, 99, 100, 2, 0}, /* DE 58 Chorus-2 entry */ {POLY800_STEPPED, 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry */ {POLY800_STEPPED, 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry 80 */ {POLY800_CONTINUOUS, 0, 15, 8, 0, 0}, /* LFO Freq */ {POLY800_CONTINUOUS, 0, 15, 126, 24, 0}, /* LFO Delay */ {POLY800_CONTINUOUS, 0, 15, 126, 22, 0}, /* DCO */ {POLY800_CONTINUOUS, 0, 15, 126, 23, 0}, /* VCF */ {POLY800_STEPPED, 0, 1, 126, 11, 0}, /* LFO Multi entry */ {POLY800_STEPPED, 1, 16, 126, 126, P800_REZERO}, /* Midi Chan Shim */ {POLY800_STEPPED, 0, 1, 126, 126, 0}, /* Midi Prog Change */ {POLY800_STEPPED, 1, 2, 126, 126, P800_REZERO}, /* OMNI */ }; #define P8H 410 #define P8W 39 #define PR1 13 #define PR2 513 #define C1 3 #define C2 (C1 + P8W + 1) #define C3 (C2 + P8W + 0) #define C4 (C3 + P8W + 1) #define C5 (C4 + P8W + 1) #define C6 (C5 + P8W + 0) #define C7 (C6 + P8W + 1) #define C8 (C7 + P8W + 1) #define C9 (C8 + P8W + 2) #define C10 (C9 + P8W + 1) #define C11 (C10 + P8W + 1) #define C12 (C11 + P8W + 0) #define C13 (C12 + P8W + 0) #define C14 (C13 + P8W + 1) #define C15 (C14 + P8W + 0) #define C16 (C15 + P8W - 1) #define C17 (C16 + P8W + 3) #define C18 (C17 + P8W + 2) #define C19 (C18 + P8W + 4) #define C20 (C19 + P8W + 1) #define C21 (C20 + P8W - 1) #define C22 (C21 + P8W + 0) #define C23 (C22 + P8W + 3) #define C24 (C23 + P8W + 0) #define C25 (C24 + P8W + 1) #define LC1 3 #define LC2 (LC1 + P8W + 1) #define LC3 (LC2 + P8W + 1) #define LC4 (LC3 + P8W + 0) #define LC5 (LC4 + P8W + 1) #define LC6 (LC5 + P8W + 0) #define LC7 (LC6 + P8W + 3) #define LC8 (LC7 + P8W + 1) #define LC9 (LC8 + P8W + 1) #define LC10 (LC9 + P8W + 0) #define LC11 (LC10 + P8W + 1) #define LC12 (LC11 + P8W + 0) #define LC13 (LC12 + P8W + 3) #define LC14 (LC13 + P8W + 1) #define LC15 (LC14 + P8W + 0) #define LC16 (LC15 + P8W + 1) #define LC17 (LC16 + P8W + 0) #define LC18 (LC17 + P8W + 1) #define LC19 (LC18 + P8W + 3) #define LC20 (LC19 + P8W + 1) #define LC21 (LC20 + P8W + 0) #define LC22 (LC21 + P8W + 1) #define LC23 (LC22 + P8W + 2) #define LC24 (LC23 + P8W + 0) #define LC25 (LC24 + P8W + 0) static brightonLocations locations[DEVICE_COUNT] = { /* * The first are dummies, count starts at 11 */ {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"DCO1 Octave", 9, C1, PR1, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"DCO1 Wave", 9, C2, PR1, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"DCO1 16'", 9, C3, PR1, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"DCO1 8'", 9, C4, PR1, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"DCO1 4'", 9, C5, PR1, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"DCO1 2'", 9, C6, PR1, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"DCO1 Level", 9, C7, PR1, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, /* Noise 18 */ {"DCO Mode", 9, C8, PR1, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, /* DCO 21 */ {"DCO2 Octave", 9, C9, PR1, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"DCO2 Wave", 9, C10, PR1, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"DCO2 16'", 9, C11, PR1, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"DCO2 8'", 9, C12, PR1, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"DCO2 4'", 9, C13, PR1, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"DCO2 2'", 9, C14, PR1, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"DCO2 Level", 9, C15, PR1, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, /* DCO 2 31 */ {"DCO2 Interval", 9, C16, PR1, P8W + 2, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"DCO2 Detune", 9, C17, PR1, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, /* Noise 33 */ {"Noise", 9, C18, PR1, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, /* VCF 41 */ {"VCF Cutoff", 9, C19, PR1, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"VCF Resonance", 9, C20, PR1, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"VCF KBD", 9, C21, PR1, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"VCF EnvPolarity", 9, C22, PR1, P8W + 2, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"VCF EngTrack", 9, C23, PR1, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"VCF Env Trigger", 9, C24, PR1, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"On/Off", 9, C25, PR1, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, /* DEG 1 51 */ {"DEG1 Attack", 9, LC1, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"DEG1 Decay", 9, LC2, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"DEG1 Break", 9, LC3, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"DEG1 Slope", 9, LC4, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"DEG1 Sustain", 9, LC5, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"DEG1 Release", 9, LC6, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, /* DEG 2 61 */ {"DEG2 Attack", 9, LC7, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"DEG2 Decay", 9, LC8, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"DEG2 Break", 9, LC9, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"DEG2 Slope", 9, LC10, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"DEG2 Sustain", 9, LC11, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"DEG2 Release", 9, LC12, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, /* DEG 3 71 */ {"DEG3 Attack", 9, LC13, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"DEG3 Decay", 9, LC14, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"DEG3 Break", 9, LC15, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"DEG3 Slope", 9, LC16, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"DEG3 Sustain", 9, LC17, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"DEG3 Release", 9, LC18, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, /* Mod 81 */ {"LFO Freq", 9, LC19, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"LFO Delay", 9, LC20, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"LFO DCO", 9, LC21, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"LFO VCF", 9, LC22, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"MidiChannel", 9, LC23, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"ProgEnable", 9, LC24, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"OmniOnOff", 9, LC25, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, /* Done */ {"", 9, 5, 5, 5, 5, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_WITHDRAWN}, {"", 9, LC25, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_WITHDRAWN}, {"", 9, LC25, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_WITHDRAWN}, {"", 9, LC25, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_WITHDRAWN}, {"", 9, LC25, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_WITHDRAWN}, {"", 9, LC25, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_WITHDRAWN}, {"", 9, LC25, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_WITHDRAWN}, {"", 9, LC25, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_WITHDRAWN}, {"", 9, LC25, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_WITHDRAWN}, {"", 9, LC25, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_WITHDRAWN}, {"", 9, LC25, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_WITHDRAWN}, {"", 9, LC25, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_WITHDRAWN}, {"", 9, LC25, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_WITHDRAWN}, {"", 9, LC25, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_WITHDRAWN}, {"", 9, LC25, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_WITHDRAWN}, {"", 9, LC25, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_WITHDRAWN}, {"", 9, LC25, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_WITHDRAWN}, {"", 9, LC25, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_WITHDRAWN}, {"", 9, LC25, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_WITHDRAWN}, {"", 9, LC25, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_WITHDRAWN}, {"", 9, LC25, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_WITHDRAWN}, {"", 9, LC25, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_WITHDRAWN}, {"", 9, LC25, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_WITHDRAWN}, {"", 9, LC25, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_WITHDRAWN}, {"", 9, LC25, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_WITHDRAWN}, {"", 9, LC25, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_WITHDRAWN}, {"", 9, LC25, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_WITHDRAWN}, {"", 9, LC25, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_WITHDRAWN}, {"", 9, LC25, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_WITHDRAWN}, {"", 9, LC25, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_WITHDRAWN}, {"", 9, LC25, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_WITHDRAWN}, {"", 9, LC25, PR2, P8W, P8H, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_WITHDRAWN}, }; #define PMW 40 #define PMH 130 static brightonLocations p800mods[MODS_COUNT] = { /* Bank */ {"", 2, 647, 820, 100, 33, 0, 1, 0, "bitmaps/buttons/polyblue.xpm", "bitmaps/buttons/polyredV.xpm", BRIGHTON_CHECKBUTTON}, /* Digits 1 */ {"", 2, 600, 700, 50, 40, 0, 1, 0, "bitmaps/buttons/polyblue.xpm", "bitmaps/buttons/polyredV.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 670, 700, 50, 40, 0, 1, 0, "bitmaps/buttons/polyblue.xpm", "bitmaps/buttons/polyredV.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 740, 700, 50, 40, 0, 1, 0, "bitmaps/buttons/polyblue.xpm", "bitmaps/buttons/polyredV.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 600, 590, 50, 40, 0, 1, 0, "bitmaps/buttons/polyblue.xpm", "bitmaps/buttons/polyredV.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 670, 590, 50, 40, 0, 1, 0, "bitmaps/buttons/polyblue.xpm", "bitmaps/buttons/polyredV.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 740, 590, 50, 40, 0, 1, 0, "bitmaps/buttons/polyblue.xpm", "bitmaps/buttons/polyredV.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 600, 460, 50, 40, 0, 1, 0, "bitmaps/buttons/polyblue.xpm", "bitmaps/buttons/polyredV.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 670, 460, 50, 40, 0, 1, 0, "bitmaps/buttons/polyblue.xpm", "bitmaps/buttons/polyredV.xpm", BRIGHTON_CHECKBUTTON}, /* Prog button 9 */ {"", 2, 740, 460, 50, 40, 0, 1, 0, "bitmaps/buttons/polywhiteH.xpm", "bitmaps/buttons/polyredV.xpm", BRIGHTON_CHECKBUTTON}, {"MasterVolume", 0, 210, 645, 130, 180, 0, 1, 0, "bitmaps/knobs/line.xpm", 0, BRIGHTON_REDRAW|BRIGHTON_NOSHADOW}, {"", 1, 190, 500, 150, 35, 0, 1, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_VERTICAL|BRIGHTON_REVERSE|BRIGHTON_NOTCH|BRIGHTON_NOSHADOW}, {"", 1, 362, 540, 15, 300, 0, 11, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 2, 430, 530, 25, 200, 0, 1, 0, "bitmaps/buttons/polywhiteV.xpm", "bitmaps/buttons/polyredV.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 490, 530, 25, 200, 0, 1, 0, "bitmaps/buttons/polywhiteV.xpm", "bitmaps/buttons/polyredV.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 550, 530, 25, 200, 0, 1, 0, "bitmaps/buttons/polywhiteV.xpm", "bitmaps/buttons/polyredV.xpm", BRIGHTON_CHECKBUTTON}, // 16 {"", 2, 835, 530, 25, 200, 0, 1, 0, "bitmaps/buttons/polywhiteV.xpm", "bitmaps/buttons/polyredV.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 885, 530, 25, 200, 0, 1, 0, "bitmaps/buttons/polywhiteV.xpm", "bitmaps/buttons/polyredV.xpm", BRIGHTON_CHECKBUTTON}, /* Entry pot 18 */ {"DataEntry", 0, 835, 750, 100, 140, 0, 1, 0, "bitmaps/knobs/knob1.xpm", 0, 0}, /* Midi is now in the memory */ {"", 2, 0, 0, 25, 140, 0, 1, 0, "bitmaps/buttons/polywhiteV.xpm", "bitmaps/buttons/polyredV.xpm",BRIGHTON_CHECKBUTTON|BRIGHTON_WITHDRAWN}, {"", 2, 600, 340, 18, 35, 0, 1, 0, "bitmaps/textures/p8b.xpm", "bitmaps/images/led.xpm", BRIGHTON_NOSHADOW}, {"", 2, 940, 530, 25, 140, 0, 1, 0, "bitmaps/buttons/polyredV.xpm", "bitmaps/buttons/polyblue.xpm", BRIGHTON_CHECKBUTTON}, /* Joystick 22 - we need to keep the dummy since it dispatches X/Y events */ {"", 5, 3, 620, 150, 240, 0, 1, 0, "bitmaps/images/sphere.xpm", 0, BRIGHTON_WIDE}, {"", 0, 0, 0, 10, 10, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, /* DUMMY */ /* Two LED for denoting prog or param - 24*/ {"", 2, 693, 340, 18, 35, 0, 1, 0, "bitmaps/textures/p8b.xpm", "bitmaps/images/led.xpm", BRIGHTON_NOSHADOW}, {"", 2, 843, 340, 18, 35, 0, 1, 0, "bitmaps/textures/p8b.xpm", "bitmaps/images/led.xpm", BRIGHTON_NOSHADOW}, {"", 8, 610, 200, PMW, PMH, 0, 9, 0, 0, 0, 0}, {"", 8, 610 + PMW + 5, 200, PMW, PMH, 0, 9, 0, 0, 0, 0}, {"", 8, 750, 200, PMW, PMH, 0, 9, 0, 0, 0, 0}, {"", 8, 750 + PMW + 5, 200, PMW, PMH, 0, 9, 0, 0, 0, 0}, {"", 8, 890, 200, PMW, PMH, 0, 9, 0, 0, 0, 0}, {"", 8, 890 + PMW + 5, 200, PMW, PMH, 0, 9, 0, 0, 0, 0}, }; /* * This is a set of globals for the main window rendering. Again taken from * include/brighton.h * Hm, the bit-1 was black, and the bit 99 was in various builds including a * white one, but also a black one and a black one with wood panels. I would * like the black one with wood panels, so that will have to be the bit-1, the * bit-99 will be white with thin metal panels. */ brightonApp poly800App = { "poly800", 0, /* no blueprint on wood background. */ "bitmaps/textures/p8b.xpm", BRIGHTON_STRETCH, poly800Init, poly800Configure, /* 3 callbacks, unused? */ midiCallback, destroySynth, {8, 100, 2, 2, 5, 520, 0, 0}, 1016, 370, 0, 0, 3, /* one panel only */ { { "Poly800", "bitmaps/blueprints/poly800.xpm", "bitmaps/textures/p8b.xpm", BRIGHTON_STRETCH, /* flags */ 0, 0, poly800Callback, 317, 40, 674, 444, DEVICE_COUNT, locations }, { "Keyboard", 0, // "bitmaps/keys/kbg.xpm", "bitmaps/newkeys/nkbg.xpm", 0x020|BRIGHTON_STRETCH, 0, 0, poly800KeyCallback, 32, 550, 952, 430, KEY_COUNT_4OCTAVE, keys4octave2 // KEY_COUNT, // keysprofile2 }, { "Poly800Mods", "bitmaps/blueprints/poly800mods.xpm", "bitmaps/textures/p8b.xpm", BRIGHTON_STRETCH, /* flags */ 0, 0, poly800Callback, 7, 20, 300, 444, MODS_COUNT, p800mods }, } }; /* * The next two should come out of here and go into a separate arpeggiator file * or failing that into brightonRoutines.c * * This has been commented out until it is integrated into the p800 emulator * static int poly800seqInsert(arpeggiatorMemory *seq, int note, int transpose) { printf("arpeg %i + %i at %i\n", note, transpose, (int) seq->s_max); if (seq->s_max == 0) seq->s_dif = note + transpose; seq->sequence[(int) (seq->s_max)] = (float) (note + transpose - seq->s_dif); if ((seq->s_max += 1) >= BRISTOL_SEQ_MAX) { seq->s_max = BRISTOL_SEQ_MAX; return(-1); } return(0); } static void poly800SeqRelearn(guiSynth *synth, int fd, int chan, int c, int o, int v) { if (v != 0) { bristolMidiSendMsg(fd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_ENABLE, 0); bristolMidiSendMsg(fd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RESEQ, 1); synth->seq1.param[BRISTOL_AM_SMAX] = 0; return; } bristolMidiSendMsg(fd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RESEQ, 0); } */ static void poly800ChordRelearn(guiSynth *synth, int fd, int chan, int c, int o, int v) { if (synth->seq1.param == NULL) loadSequence(&synth->seq1, SYNTH_NAME, 0, 0); if (synth->seq2.param == NULL) loadSequence(&synth->seq2, SYNTH_NAME, 0, BRISTOL_SID2); // We need to turn off chording to do this and reset one index if (v != 0) { bristolMidiSendMsg(fd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_CHORD_ENABLE, 0); bristolMidiSendMsg(fd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_CHORD_RESEQ, 1); synth->seq1.param[BRISTOL_AM_CCOUNT] = 0; return; } bristolMidiSendMsg(fd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_CHORD_RESEQ, 0); } static int poly800ChordInsert(arpeggiatorMemory *seq, int note, int transpose) { //printf("chord %i + %i at %i\n", note, transpose, (int) seq->c_count); if (seq->c_count == 0) seq->c_dif = note + transpose; seq->chord[(int) (seq->c_count)] = (float) (note + transpose - seq->c_dif); if ((seq->c_count += 1) >= BRISTOL_CHORD_MAX) { seq->c_count = BRISTOL_CHORD_MAX; crl = 0; return(-1); } return(0); } /* * We really want to just use one midi channel and let the midi library decide * that we have multiple synths on the channel with their own split points. * The lower layer should define the midi channel, split point and transpose * of upper layer. */ static int poly800KeyCallback(brightonWindow *win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); /* if ((synth->mem.param[155] != 0) && (value != 0)) { seqInsert((arpeggiatorMemory *) synth->seq1.param, (int) index, synth->transpose); } */ if (crl) { poly800ChordInsert((arpeggiatorMemory *) synth->seq1.param, (int) index, synth->transpose); } if (global.libtest) return(0); /* * So we have a single key event and two MIDI channels. Just send the * event on both channels, no need to be difficult about it since if this * was a split configuration the library filters out the events. */ if (value) { bristolMidiSendMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_KEYON, 0, index + synth->transpose); } else { bristolMidiSendMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_KEYOFF, 0, index + synth->transpose); } return(0); } /* * At this point we have loaded a memory so we need to send those actual new * parameters to the engine. This is an issue for MIDI program load, perhaps * we should consider dual load above memory 74 as per the original? * * The path of least resistance here is to scan through the the memory table * incrementing the input selector and delivering the memory value to the * data entry pot..... */ static void loadMemoryShim(guiSynth *synth, int from) { int i, current; brightonEvent event; current = synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 2] * 10 + synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 3]; loadMemory(synth, SYNTH_NAME, 0, from, synth->mem.active, 0, BRISTOL_FORCE|BRISTOL_NOCALLS); synth->flags |= MEM_LOADING; event.type = BRIGHTON_FLOAT; for (i = 0; i < synth->mem.active; i++) { if (poly800Range[i].flags & P800_NO_LOAD) continue; synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 2] = i / 10; synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 3] = i % 10; event.value = synth->mem.param[i]; brightonParamChange(synth->win, MODS_PANEL, ENTRY_POT, &event); } synth->flags &= ~MEM_LOADING; synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 2] = current / 10; synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 3] = current % 10; event.value = synth->mem.param[current]; brightonParamChange(synth->win, MODS_PANEL, ENTRY_POT, &event); } int p800loadMemory(guiSynth *synth, char *algo, char *name, int location, int active, int skip, int flags) { loadMemoryShim(synth, location); return(0); } static int midiCallback(brightonWindow *win, int controller, int value, float n) { guiSynth *synth = findSynth(global.synths, win); switch(controller) { case MIDI_PROGRAM: if (synth->mem.param[87] == 0) return(0); /* * We should accept 0..74 as lower layer and above that as dual * loading requests. */ printf("midi program: %x, %i\n", controller, value); synth->location = value; loadMemoryShim(synth, synth->location); break; case MIDI_BANK_SELECT: printf("midi banksel: %x, %i\n", controller, value); synth->bank = value; break; } return(0); } static int poly800UpdateDisplayDec(guiSynth *synth, int fd, int chan, int c, int o, int v) { int ho, lo, dev = DISPLAY_DEV + o; brightonEvent event; /* printf("Dec %i %i %i\n", c, o, v); */ if (v < 0) { ho = lo = -10; } else { lo = v % 10; ho = v / 10; } event.type = BRIGHTON_FLOAT; event.value = (float) ho; brightonParamChange(synth->win, MODS_PANEL, dev, &event); event.value = (float) lo; brightonParamChange(synth->win, MODS_PANEL, dev + 1, &event); return(0); } static int poly800UpdateDisplay(guiSynth *synth, int fd, int chan, int c, int o, int v) { int ho, lo, dev = DISPLAY_DEV + o; brightonEvent event; /* printf("Disp %i %i %i\n", c, o, v); */ if (v < 0) { ho = lo = -10; } else { ho = v * 100 / (CONTROLLER_RANGE + 1); lo = ho % 10; ho = ho / 10; } event.type = BRIGHTON_FLOAT; event.value = (float) ho; brightonParamChange(synth->win, MODS_PANEL, dev, &event); event.value = (float) lo; brightonParamChange(synth->win, MODS_PANEL, dev + 1, &event); synth->mem.param[ACTIVE_DEVS + dev] = ho; synth->mem.param[ACTIVE_DEVS + dev + 1] = lo; return(0); } static int poly800MidiNull(void *synth, int fd, int chan, int c, int o, int v) { if (global.libtest) printf("This is a null callback on panel 0 id 0\n"); return(0); } static void poly800MidiShim(guiSynth *synth, int fd, int chan, int c, int o, int v) { bristolMidiSendMsg(fd, synth->sid, c, o, v); } static int poly800MidiSendMsg(guiSynth *synth, int fd, int chan, int o, int c, int v) { c = poly800Range[o].cont; o = poly800Range[o].op; if (global.libtest) return(0); bristolMidiSendMsg(fd, synth->sid, o, c, v); return(0); } static int poly800EntryPot(guiSynth *synth, int fd, int chan, int o, int c, float v) { int index; float decimal; int value; //printf("EP %f %f: %f\n", synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 2], synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 3], v); /* * Get the param index from the second display */ if ((index = synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 2] * 10 + synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 3]) < 11) return(0); if (poly800Range[index].flags & P800_INACTIVE) { v = 0; decimal = 0; } synth->mem.param[index] = v; /* * We have a value for the pot position and that has to be worked into * the entry range. * * This was originally wrong: decimal = poly800Range[index].min + (v + 0.00001) * (poly800Range[index].max - poly800Range[index].min); * This only changes at the limits, rather than halfway through a range * which appears better - it truncates whilst it should round... */ decimal = (float) ((int) (0.5 + poly800Range[index].min + (v + 0.00001) * (poly800Range[index].max - poly800Range[index].min))); /* if ((synth->flags & MEM_LOADING) != 0) { synth->mem.param[index] = v; poly800UpdateDisplayDec(synth, fd, chan, c, 4, decimal); return(0); } */ if (poly800Range[index].type == POLY800_STEPPED) { value = (int) decimal; if (poly800Range[index].flags & P800_REZERO) value -= poly800Range[index].min; } else value = (int) (v * C_RANGE_MIN_1); //printf("EP %i %f = send %i\n", index, decimal, value); if ((synth->flags & MEM_LOADING) == 0) poly800UpdateDisplayDec(synth, fd, chan, c, 4, decimal); if (synth->dispatch[index].routine != NULL) synth->dispatch[index].routine(synth, global.controlfd, synth->sid, poly800Range[index].op, poly800Range[index].cont, value); else poly800MidiSendMsg(synth, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, value); return(0); } static int poly800Select(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; poly800UpdateDisplay(synth, fd, chan, c, 2, (c + 1) * CONTROLLER_RANGE / 100); event.type = BRIGHTON_FLOAT; event.value = synth->mem.param[c]; brightonParamChange(synth->win, MODS_PANEL, ENTRY_POT, &event); /* Select Param entry */ event.value = 1; brightonParamChange(synth->win, MODS_PANEL, 25, &event); event.value = 0; brightonParamChange(synth->win, MODS_PANEL, 24, &event); return(0); } static int memSave = -1; static int bankHold = 0; static void poly800Memory(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; if (synth->flags & MEM_LOADING) return; if ((synth->flags & OPERATIONAL) == 0) return; /* * Saving memories requires that we take a peek at the split/double settings * and then select the memory location accordingly. These are not going to * be performance parameters so we only save a single memory at a time. */ if (c == 0) { /* * This is not a doubeClick: Select write, then select two digits for * the location if (brightonDoubleClick(dc) != 0) poly800SaveMemory(synth); */ if (memSave < 0) return; if ((memSave = 1 - memSave) != 0) { poly800UpdateDisplayDec(synth, fd, chan, c, 0, -1); } else { /* * Put back original memory */ if (synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV] <= 0) poly800UpdateDisplayDec(synth, fd, chan, c, 0, synth->bank * 10 + synth->location); } return; } if (c == 1) { /* * Enter digit: * If memSave selected, display digits, when two save mem. * * If Bank hold is selected then single digit will load the memory. * * Otherwise two digits are required */ if (memSave) { if (synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV] <= 0) { event.type = BRIGHTON_FLOAT; event.value = o; brightonParamChange(synth->win, MODS_PANEL, DISPLAY_DEV, &event); } else { event.type = BRIGHTON_FLOAT; event.value = o; brightonParamChange(synth->win, MODS_PANEL, DISPLAY_DEV + 1, &event); synth->bank = synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV]; synth->location = o; saveMemory(synth, SYNTH_NAME, 0, mbh + synth->bank * 10 + o, 0); memSave = 0; } return; } if (bankHold) { /* Load memory */ synth->location = o; event.type = BRIGHTON_FLOAT; event.value = o; brightonParamChange(synth->win, MODS_PANEL, DISPLAY_DEV + 1, &event); loadMemoryShim(synth, mbh + synth->bank * 10 + synth->location); /* Even though we have now set all the parameters we need to return * our Prog status */ event.type = BRIGHTON_FLOAT; event.value = 1; brightonParamChange(synth->win, MODS_PANEL, 24, &event); event.value = 0; brightonParamChange(synth->win, MODS_PANEL, 25, &event); memSave = 0; return; } if (synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 1] > 0) { event.type = BRIGHTON_FLOAT; event.value = o; brightonParamChange(synth->win, MODS_PANEL, DISPLAY_DEV, &event); event.type = BRIGHTON_FLOAT; event.value = -1; brightonParamChange(synth->win, MODS_PANEL, DISPLAY_DEV+1, &event); synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 1] = -1; } else { event.type = BRIGHTON_FLOAT; event.value = o; brightonParamChange(synth->win, MODS_PANEL, DISPLAY_DEV+1, &event); synth->bank = synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV]; synth->location = o; loadMemoryShim(synth, mbh + synth->bank * 10 + synth->location); /* Even though we have now set all the parameters we need to return * our Prog status */ event.type = BRIGHTON_FLOAT; event.value = 1; brightonParamChange(synth->win, MODS_PANEL, 24, &event); event.value = 0; brightonParamChange(synth->win, MODS_PANEL, 25, &event); memSave = 0; } } } static void poly800ParamSelect(guiSynth *synth, int v) { brightonEvent event; if (synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 3] > 0) { /* First digit */ event.type = BRIGHTON_FLOAT; event.value = v; brightonParamChange(synth->win, MODS_PANEL, DISPLAY_DEV + 2, &event); event.type = BRIGHTON_FLOAT; event.value = -1; brightonParamChange(synth->win, MODS_PANEL, DISPLAY_DEV + 3, &event); synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 3] = -1; } else { /* Second digit */ event.type = BRIGHTON_FLOAT; event.value = v; brightonParamChange(synth->win, MODS_PANEL, DISPLAY_DEV + 3, &event); poly800Select(synth, synth->sid, synth->midichannel, synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 2] * 10 + synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 3], 0, 0); } } static int poly800ModCallback(brightonWindow *win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); int off = 24, on = 25; brightonEvent event; if (global.libtest) printf("poly800ModCallback(%i, %f)\n", index, value); synth->mem.param[ACTIVE_DEVS + index] = value; switch (index) { case 0: memSave = 1; poly800Memory(synth, synth->sid, synth->midichannel, 0, 0, 0); /* Bank hold button */ bankHold = 1 - bankHold; event.type = BRIGHTON_FLOAT; event.value = bankHold; brightonParamChange(win, MODS_PANEL, 20, &event); break; case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: /* Digits, dispatch according to prog button */ if (synth->mem.param[ACTIVE_DEVS + 24] != 0) { /* Program selectors */ poly800Memory(synth, synth->sid, synth->midichannel, 1, index, 0); } else { /* Param selectors */ poly800ParamSelect(synth, index); } break; case 21: /* Write */ if (synth->mem.param[ACTIVE_DEVS + 24] == 0) { event.type = BRIGHTON_FLOAT; event.value = 1; brightonParamChange(win, MODS_PANEL, 24, &event); event.value = 0; brightonParamChange(win, MODS_PANEL, 25, &event); } poly800Memory(synth, synth->sid, synth->midichannel, 0, index, 0); break; case 9: /* Prog button */ memSave = 1; poly800Memory(synth, synth->sid, synth->midichannel, 0, 0, 0); if (synth->mem.param[ACTIVE_DEVS + 24] == 0) { on = 24; off = 25; } event.type = BRIGHTON_FLOAT; event.value = 1; brightonParamChange(win, MODS_PANEL, on, &event); event.value = 0; brightonParamChange(win, MODS_PANEL, off, &event); break; case 10: /* Volume */ bristolMidiSendMsg(global.controlfd, synth->midichannel, 126, 2, (int) (value * C_RANGE_MIN_1)); break; case 11: /* Tune */ bristolMidiSendMsg(global.controlfd, synth->midichannel, 126, 1, (int) (value * C_RANGE_MIN_1)); break; case 12: /* Bend depth - make this glide */ bristolMidiSendRP(global.controlfd, synth->sid, MIDI_RP_PW, (int) (value) + 1); bristolMidiSendMsg(global.controlfd, synth->midichannel, 126, 6, (int) (value * C_RANGE_MIN_1 / 12)); break; case 13: /* Poly mode - cancel chord/hold */ bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_HOLD|0); bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_CHORD_ENABLE, 0); crl = 0; break; case 14: /* * Clear the sustain setting and start chord learning */ bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_HOLD|0); /* * Chord. To configure it you pressed hold, then the notes in the * chord, then pressed chord. We can't really use this so will try * to get the logic to go Hold->Chord->notes->Chord/Hold */ if (brightonDoubleClick(dc)) { printf("chord hold\n"); poly800ChordRelearn(synth, synth->sid, synth->midichannel, 0, 0, 1); crl = 1; break; } crl = 0; /* * Otherwise it is to enable chording. */ bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_CHORD_ENABLE, 1); break; case 15: /* Hold mode - sustain */ brightonDoubleClick(dc); bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_HOLD|1); bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_CHORD_ENABLE, 0); break; case ENTRY_POT: memSave = 1; poly800Memory(synth, synth->sid, synth->midichannel, 0, 0, 0); if (synth->mem.param[ACTIVE_DEVS + 24] != 0) { event.type = BRIGHTON_FLOAT; event.value = 0; brightonParamChange(win, MODS_PANEL, 24, &event); event.value = 1; brightonParamChange(win, MODS_PANEL, 25, &event); } poly800EntryPot(synth, synth->sid, synth->midichannel, 0, 0, value); break; case 17: /* * Inc * Get the current display value and move it up towards the limit. * Then convert this into an int and send it to the entry pot. */ event.type = BRIGHTON_FLOAT; index = synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 2] * 10 + synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 3]; value = synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 4] * 10 + synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 5] + 1; if (value > poly800Range[index].max) value = poly800Range[index].max; event.value = (value - poly800Range[index].min) / (poly800Range[index].max - poly800Range[index].min); //printf("%i: min %f max %f now %f/%f\n", index, //poly800Range[index].min, poly800Range[index].max, value, event.value); brightonParamChange(win, MODS_PANEL, ENTRY_POT, &event); break; case 16: /* Dec */ event.type = BRIGHTON_FLOAT; index = synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 2] * 10 + synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 3]; value = synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 4] * 10 + synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 5] - 1; if (value < poly800Range[index].min) value = poly800Range[index].min; event.value = (value - poly800Range[index].min) / ((float) poly800Range[index].max - poly800Range[index].min); //printf("%i: min %f max %f now %f/%f\n", index, //poly800Range[index].min, poly800Range[index].max, value, event.value); brightonParamChange(win, MODS_PANEL, ENTRY_POT, &event); break; case 22: /* Mod */ if (!global.libtest) bristolMidiSendControlMsg(global.controlfd, synth->midichannel, 1, ((int) (value * C_RANGE_MIN_1)) >> 7); break; case 23: /* Joystick X motion - pitchbend */ if (!global.libtest) bristolMidiSendMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_PITCH, 0, (int) (value * C_RANGE_MIN_1)); break; } return(0); } /* * For the sake of ease of use, links have been placed here to be called * by any of the devices created. They would be better in some other file, * perhaps with this as a dispatch. * * Param refers to the device index in the locations table given below. */ static int poly800Callback(brightonWindow *win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); int sendvalue; if (global.libtest) printf("poly800Callback(%i, %f)\n", index, value); if (synth == 0) return(0); if (panel == MODS_PANEL) return(poly800ModCallback(win, panel, index, value)); if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0)) return(0); if (poly800App.resources[0].devlocn[index].to == 1) sendvalue = value * C_RANGE_MIN_1; else sendvalue = value; if (index < 100) poly800Select(synth, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); return(0); } static void p800Detune(guiSynth *synth, int fd, int chan, int c, int o, int v) { int value = v; if (!global.libtest) { bristolMidiSendNRP(global.controlfd, synth->sid, BRISTOL_NRP_DETUNE, value / 50); } bristolMidiSendMsg(fd, synth->sid, 0, 3, value); bristolMidiSendMsg(fd, synth->sid, 1, 3, value); } static int pmc = -1; static void p800midichannel(guiSynth *synth, int fd, int chan, int c, int o, int v) { if (global.libtest) return; if (synth->mem.param[88] != 0) v = BRISTOL_CHAN_OMNI; else v = synth->mem.param[86] * 15; if (v == pmc) return; bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_MIDICHANNEL|v); pmc = v; } static void p800lfo(guiSynth *synth, int fd, int chan, int c, int o, int v) { /* * We have to configure the engine to generate one or more LFO but more * subtly we also have to tell the LFO not to synchronise to key_on. */ bristolMidiSendMsg(fd, synth->sid, 8, 1, v); bristolMidiSendMsg(fd, synth->sid, 126, 11, v); } static void p800filterEnv(guiSynth *synth, int fd, int chan, int c, int o, int v) { bristolMidiSendMsg(fd, synth->sid, 126, 12, v); /* May have to change envelope triggering as well? */ bristolMidiSendMsg(fd, synth->sid, 6, 12, v); } static void p800chorus(guiSynth *synth, int fd, int chan, int c, int o, int v) { if (synth->mem.param[48] <= 0.5) bristolMidiSendMsg(fd, synth->sid, 100, 3, 0); else bristolMidiSendMsg(fd, synth->sid, 100, 3, (int) (synth->mem.param[47] * C_RANGE_MIN_1)); } static void p800velocity(guiSynth *synth, int fd, int chan, int c, int o, int v) { int x = 0, y = 0, z = 0; if (v & 0x01) x = 1; if (v & 0x02) y = 1; if (v & 0x04) z = 1; bristolMidiSendMsg(fd, synth->sid, 4, 10, x); bristolMidiSendMsg(fd, synth->sid, 5, 10, y); bristolMidiSendMsg(fd, synth->sid, 6, 10, z); } static void p800detune(guiSynth *synth, int fd, int chan, int c, int o, int v) { //printf("detune %i %i %i\n", c, o, v); bristolMidiSendMsg(fd, synth->sid, 1, 0, 8192 + v / 2); } static void p800waveform(guiSynth *synth, int fd, int chan, int c, int o, int v) { //printf("waveform %i %i %i\n", c, o, v); bristolMidiSendMsg(fd, synth->sid, c, 9, (int) (C_RANGE_MIN_1 - v)); bristolMidiSendMsg(fd, synth->sid, c, 10, v); } static void p800octave(guiSynth *synth, int fd, int chan, int c, int o, int v) { /* * We are delivered 0, 1 or 2, need to multiply by 12 notes */ if (c == 0) bristolMidiSendMsg(fd, synth->sid, 0, 2, v * 12); else bristolMidiSendMsg(fd, synth->sid, 1, 2, ((int) (synth->mem.param[21] * 2)) * 12 + (int) (synth->mem.param[31] * 12)); } /* * Any location initialisation required to run the callbacks. For bristol, this * will connect to the engine, and give it some base parameters. * May need to generate some application specific menus. * Will also then make specific requests to some of the devices to alter their * rendering. */ static int poly800Init(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); dispatcher *dispatch; int i; if (synth == 0) { synth = findSynth(global.synths, 0); if (synth == 0) { printf("cannot init\n"); return(0); } } synth->win = win; printf("Initialise the poly800 link to bristol: %p\n", synth->win); synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float)); synth->mem.count = DEVICE_COUNT; synth->mem.active = ACTIVE_DEVS; synth->dispatch = (dispatcher *) brightonmalloc(DEVICE_COUNT * sizeof(dispatcher)); dispatch = synth->dispatch; /* * We really want to have three connection mechanisms. These should be * 1. Unix named sockets. * 2. UDP sockets (actually implements TCP unfortunately). * 3. MIDI pipe. */ if (!global.libtest) { bcopy(&global, &manual, sizeof(guimain)); if ((synth->sid = initConnection(&global, synth)) < 0) return(-1); manual.flags |= BRISTOL_CONN_FORCE|BRIGHTON_NOENGINE; manual.port = global.port; } for (i = 0; i < ACTIVE_DEVS; i++) { synth->dispatch[i].routine = NULL; synth->dispatch[i].controller = i; synth->dispatch[i].operator = i; } synth->dispatch[11].routine = (synthRoutine) p800octave; synth->dispatch[12].routine = (synthRoutine) p800waveform; synth->dispatch[21].routine = (synthRoutine) p800octave; synth->dispatch[22].routine = (synthRoutine) p800waveform; synth->dispatch[31].routine = (synthRoutine) p800octave; synth->dispatch[32].routine = (synthRoutine) p800detune; /* DCO-2 */ synth->dispatch[38].routine = (synthRoutine) p800Detune; /* Global */ synth->dispatch[46].routine = (synthRoutine) p800filterEnv; /* Global */ synth->dispatch[47].routine = (synthRoutine) p800chorus; /* Global */ synth->dispatch[48].routine = (synthRoutine) p800chorus; /* Global */ synth->dispatch[57].routine = (synthRoutine) p800velocity; synth->dispatch[85].routine = (synthRoutine) p800lfo; synth->dispatch[86].routine = (synthRoutine) p800midichannel; synth->dispatch[88].routine = (synthRoutine) p800midichannel; for (; i < DEVICE_COUNT; i++) synth->dispatch[i].routine = (synthRoutine) poly800MidiShim; synth->dispatch[0].routine = (synthRoutine) poly800MidiNull; /* Osc-1 settings */ bristolMidiSendMsg(global.controlfd, synth->sid, 0, 0, 8192); bristolMidiSendMsg(global.controlfd, synth->sid, 0, 1, 8192); bristolMidiSendMsg(global.controlfd, synth->sid, 0, 2, 0); bristolMidiSendMsg(global.controlfd, synth->sid, 0, 8, 0); /* No 32' */ bristolMidiSendMsg(global.controlfd, synth->sid, 0, 11, 0); /* No tri */ bristolMidiSendMsg(global.controlfd, synth->sid, 0, 12, 0); /* No sin */ bristolMidiSendMsg(global.controlfd, synth->sid, 0, 15, 0); /* P800 type */ bristolMidiSendMsg(global.controlfd, synth->sid, 1, 1, 8192); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 8, 0); /* No 32' */ bristolMidiSendMsg(global.controlfd, synth->sid, 1, 11, 0); /* No tri */ bristolMidiSendMsg(global.controlfd, synth->sid, 1, 12, 0); /* No sin */ bristolMidiSendMsg(global.controlfd, synth->sid, 1, 15, 0); /* P800 type */ /* Env settings */ bristolMidiSendMsg(global.controlfd, synth->sid, 4, 0, 0); bristolMidiSendMsg(global.controlfd, synth->sid, 4, 2, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 4, 8, 0); bristolMidiSendMsg(global.controlfd, synth->sid, 4, 11, 0); bristolMidiSendMsg(global.controlfd, synth->sid, 4, 12, 1); bristolMidiSendMsg(global.controlfd, synth->sid, 5, 0, 0); bristolMidiSendMsg(global.controlfd, synth->sid, 5, 2, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 5, 8, 0); bristolMidiSendMsg(global.controlfd, synth->sid, 5, 11, 0); bristolMidiSendMsg(global.controlfd, synth->sid, 5, 12, 1); bristolMidiSendMsg(global.controlfd, synth->sid, 6, 0, 0); bristolMidiSendMsg(global.controlfd, synth->sid, 6, 2, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 6, 8, 0); bristolMidiSendMsg(global.controlfd, synth->sid, 6, 9, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 6, 11, 1); /* Filter */ bristolMidiSendMsg(global.controlfd, synth->sid, 2, 2, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 2, 4, 4); bristolMidiSendMsg(global.controlfd, synth->sid, 2, 5, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 2, 6, 0); return(0); } /* * This will be called to make any routine specific parameters available. */ static int poly800Configure(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); brightonEvent event; if (synth == 0) { printf("problems going operational\n"); return(-1); } if (synth->location == 0) { synth->bank = 1; synth->location = 1; } else { mbh = (synth->location / 100) * 100; if ((synth->bank = synth->location / 10) > 10) synth->bank = synth->bank % 10; if (((synth->location = synth->location % 10) == 0) || (synth->location > 8)) synth->location = 1; } if (synth->flags & OPERATIONAL) return(0); printf("going operational\n"); synth->flags |= OPERATIONAL; synth->keypanel = 1; synth->keypanel2 = -1; synth->transpose = 24; brightonPut(win, "bitmaps/blueprints/poly800shade.xpm", 0, 0, win->width, win->height); /* * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only * occurs on first paint, so we suppress the first paint, and then request * an expose here. */ event.type = BRIGHTON_EXPOSE; event.intvalue = 1; brightonParamChange(synth->win, KEY_PANEL, -1, &event); configureGlobals(synth); /* Setup the displays */ event.value = 1; brightonParamChange(synth->win, MODS_PANEL, 24, &event); event.value = synth->bank; brightonParamChange(synth->win, MODS_PANEL, DISPLAY_DEV, &event); event.value = synth->location; brightonParamChange(synth->win, MODS_PANEL, DISPLAY_DEV + 1, &event); event.value = 1; brightonParamChange(synth->win, MODS_PANEL, DISPLAY_DEV + 2, &event); brightonParamChange(synth->win, MODS_PANEL, DISPLAY_DEV + 3, &event); /* Volume, tuning, bend */ event.value = 0.822646; brightonParamChange(synth->win, MODS_PANEL, 10, &event); event.value = 0.5; brightonParamChange(synth->win, MODS_PANEL, 11, &event); event.value = 0.05; brightonParamChange(synth->win, MODS_PANEL, 12, &event); loadMemoryShim(synth, mbh + synth->bank * 10 + synth->location); /* * Go into Prog rather than Param mode */ event.value = 1; brightonParamChange(synth->win, MODS_PANEL, 24, &event); event.value = 0; brightonParamChange(synth->win, MODS_PANEL, 25, &event); bristolMidiSendRP(global.controlfd, synth->sid, MIDI_RP_PW, 8192); bristolMidiSendMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_PITCH, 0, 8192); event.value = 2.0; brightonParamChange(synth->win, MODS_PANEL, 12, &event); dc = brightonGetDCTimer(2000000); memSave = 0; synth->loadMemory = (loadRoutine) p800loadMemory; return(0); } bristol-0.60.11/brighton/brightonMini.c0000644000175000017500000007165211746476475014727 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include #include "brighton.h" #include "brightonMini.h" #include "bristolmidi.h" #include "brightoninternals.h" static int miniInit(); static int miniConfigure(); static int midiCallback(brightonWindow *, int, int, float); static int miniCallback(brightonWindow * , int, int, float); extern guimain global; #include "brightonKeys.h" #define KEY_PANEL 1 #define FIRST_DEV 0 #define DEVICE_COUNT (61 + FIRST_DEV) #define ACTIVE_DEVS (42 + FIRST_DEV) #define R1 128 #define R5 698 #define R3 (R1 + (R5 - R1) / 2) #define R2 (R1 + (R3 - R1) / 2) #define R4 (R3 + (R5 - R3) / 2) #define R6 782 #define R7 889 #define C1 168 #define C2 234 #define C3 318 #define C4 398 #define C5 472 #define C6 548 #define C7 673 #define C8 753 #define C9 827 #define C10 905 #define C11 622 #define C12 140 #define S1 120 #define S2 170 #define S3 180 #define S4 35 #define S5 60 #define B1 40 #define B2 16 #define B3 110 /* * This structure is for device definition. The structure is defined in * include/brighton.h, further definitions in brighton/brightonDevtable.h and * include/brightoninternals.h * * typedef int (*brightonCallback)(int, float); * typedef struct BrightonLocations { * int device; 0=rotary, 1=scale, etc. * float relx, rely; relative position with regards to 1000 by 1000 window * float relw, relh; relative height. * int from, to; * brightonCallback callback; specific to this dev * char *image; bitmap. If zero take a device default. * int flags; * } brightonLocations; * * This example is for a miniBristol type synth interface. */ static brightonLocations locations[DEVICE_COUNT] = { /* CONTROL */ {"Tune", 0, 47, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, BRIGHTON_NOTCH}, {"Glide", 0, 18, R4, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"Mod", 0, 80, R4, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, /*3 */ /* OSCILATORS */ {"Osc1 Transpose", 0, C1, R1, S1, S1, 0, 5, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"Osc2 Transpose", 0, C1, R3, S1, S1, 0, 5, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"Osc3 Transpose", 0, C1, R5, S1, S1, 0, 5, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, /* {"", 0, C2, 382, S2, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, */ {"Osc2 Tuning", 0, C2, 382, S2, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, BRIGHTON_NOTCH}, {"Osc3 Tuning", 0, C2, 660, S2, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, BRIGHTON_NOTCH}, {"Osc1 Waveform", 0, C3, R1, S1, S1, 0, 5, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"Osc2 Waveform", 0, C3, R3, S1, S1, 0, 5, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"Osc3 Waveform", 0, C3, R5, S1, S1, 0, 5, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, /*11 */ /* MIXER */ {"Osc1 Mix lvl", 0, C4, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"Ext Mix lvl", 0, C6, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"Osc2 Mix lvl", 0, C4, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"Noise Mix lvl", 0, C6, R4, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"Osc3 Mix lvl", 0, C4, R5, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, /*16 */ /* FILTER */ {"Filter Freq", 0, C7, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"Filter Emph", 0, C8, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"Filter Contour", 0, C9, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, /*19 */ /* ADSR */ {"Filter Attack", 0, C7, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"Filter Decay", 0, C8, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"Filter Release", 0, C9, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, /*22 */ /* another ADSR */ {"Attack", 0, C7, R5, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"Decay", 0, C8, R5, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"Release", 0, C9, R5, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, /*25 */ /* MAIN OUT 25 */ {"MasterVolume", 0, C10, R1, S3, S3, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"On/Off", 2, C10 + 7, R1 - 92, B1, B1, 0, 1, 0, "bitmaps/buttons/rockerblue.xpm", 0, 0}, {"A-440", 2, C10 + 7, R2 + 75, B1, B1, 0, 1, 0, "bitmaps/buttons/rockerblue.xpm", 0, 0}, /*28 */ /* MIX BUTTONS - 28 */ {"Mix Osc1", 2, C5, R1 + 45, B1, B1, 0, 1, 0, "bitmaps/buttons/rockerblue.xpm", 0, 0}, {"Mix Ext", 2, C5, R2 + 45, B1, B1, 0, 1, 0, "bitmaps/buttons/rockerblue.xpm", 0, 0}, {"Mix Osc2", 2, C5, R3 + 45, B1, B1, 0, 1, 0, "bitmaps/buttons/rockerblue.xpm", 0, 0}, {"Mix Noise", 2, C5, R4 + 45, B1, B1, 0, 1, 0, "bitmaps/buttons/rockerblue.xpm", 0, 0}, {"Mix Osc3", 2, C5, R5 + 45, B1, B1, 0, 1, 0, "bitmaps/buttons/rockerblue.xpm", 0, 0}, /*33 */ /* NOISE BUTTON - 33 */ {"White/Pink", 2, C11 - 6, C6, B2, B3, 0, 1, 0, "bitmaps/buttons/rockerblue.xpm", 0, BRIGHTON_VERTICAL}, /*34 */ /* CONTROL BUTTONS - 34 */ {"Osc Mod 1", 2, C12 - 22, R2 - 13, B1, B1, 0, 1, 0, 0, 0, 0}, {"Osc Mod 2", 2, C12 - 22, R2 + 97, B1, B1, 0, 1, 0, 0, 0, 0}, {"Osc 3 LFO", 2, C12 - 9, R5 + 15, B2, B3, 0, 1, 0, 0, 0, BRIGHTON_VERTICAL}, {"Release", 2, 78, 765, B1, B1, 0, 1, 0, "bitmaps/buttons/rockerwhite.xpm", 0, 0}, {"Multitrig", 2, 78, 825, B1, B1, 0, 1, 0, "bitmaps/buttons/rockerwhite.xpm", 0, 0}, /*39 */ /* FILTER BUTTONS - 39 */ {"Filter Mod1", 2, C11 - 5, R1 + 30, B1, B1, 0, 1, 0, 0, 0, 0}, {"Filter Velocity", 2, C11 - 5, R1 + 170, B1, B1, 0, 1, 0, 0, 0, 0}, {"Filter KBD", 2, C11 - 5, R3, B1, B1, 0, 1, 0, 0, 0}, /*42 */ /* Memory tablet */ {"", 2, R7, R6 - S5 * 3, S4, S5, 0, 1, 0, "bitmaps/digits/L.xpm", 0, BRIGHTON_CHECKBUTTON}, {"", 2, R7 + S4 * 2, R6 - S5 * 3, S4, S5, 0, 1, 0, "bitmaps/digits/S.xpm", 0, BRIGHTON_CHECKBUTTON}, {"", 2, R7 + S4, R6 - S5 * 3, S4, S5, 0, 1, 0, "bitmaps/digits/0.xpm", 0, BRIGHTON_CHECKBUTTON}, {"", 2, R7, R6 - S5 * 2, S4, S5, 0, 1, 0, "bitmaps/digits/1.xpm", 0, BRIGHTON_CHECKBUTTON}, {"", 2, R7 + S4, R6 - S5 * 2, S4, S5, 0, 1, 0, "bitmaps/digits/2.xpm", 0, BRIGHTON_CHECKBUTTON}, {"", 2, R7 + S4 * 2, R6 - S5 * 2, S4, S5, 0, 1, 0, "bitmaps/digits/3.xpm", 0, BRIGHTON_CHECKBUTTON}, {"", 2, R7, R6 - S5, S4, S5, 0, 1, 0, "bitmaps/digits/4.xpm", 0, BRIGHTON_CHECKBUTTON}, {"", 2, R7 + S4, R6 - S5, S4, S5, 0, 1, 0, "bitmaps/digits/5.xpm", 0, BRIGHTON_CHECKBUTTON}, {"", 2, R7 + S4 * 2, R6 - S5, S4, S5, 0, 1, 0, "bitmaps/digits/6.xpm", 0, BRIGHTON_CHECKBUTTON}, {"", 2, R7, R6, S4, S5, 0, 1, 0, "bitmaps/digits/7.xpm", 0, BRIGHTON_CHECKBUTTON}, {"", 2, R7 + S4, R6, S4, S5, 0, 1, 0, "bitmaps/digits/8.xpm", 0, BRIGHTON_CHECKBUTTON}, {"", 2, R7 + S4 * 2, R6, S4, S5, 0, 1, 0, "bitmaps/digits/9.xpm", 0, BRIGHTON_CHECKBUTTON}, /* Up down midi */ {"", 2, R7 + S4, 415, S4, S5, 0, 1, 0, "bitmaps/digits/Down.xpm", 0, BRIGHTON_CHECKBUTTON}, {"", 2, R7 + S4 * 2, 415, S4, S5, 0, 1, 0, "bitmaps/digits/Up.xpm", 0, BRIGHTON_CHECKBUTTON}, /* Up Down memory */ {"", 2, R7, R6 + S5, S4, S5, 0, 1, 0, "bitmaps/digits/Down.xpm", 0, BRIGHTON_CHECKBUTTON}, {"", 2, R7 + S4 * 2, R6 + S5, S4, S5, 0, 1, 0, "bitmaps/digits/Up.xpm", 0, BRIGHTON_CHECKBUTTON}, {"", 3, R7, 430 + S5, 105, 54, 0, 1, 0, 0, "bitmaps/images/alphadisplay3.xpm", 0}, /*display 60 */ {"", 3, R7, 425 + S5 + 55, 105, 54, 0, 1, 0, 0, "bitmaps/images/alphadisplay2.xpm", 0}, /*display 60 */ {"", 4, 820, 1015, 175, 140, 0, 1, 0, "bitmaps/images/mini.xpm", 0, 0}, }; /* * This is a set of globals for the main window rendering. Again taken from * include/brighton.h */ brightonApp miniApp = { "mini", 0, /* no blueprint on wood background. */ "bitmaps/textures/wood6.xpm", 0, /*BRIGHTON_STRETCH, // default is tesselate */ miniInit, miniConfigure, /* 3 callbacks, unused? */ midiCallback, destroySynth, /* 0, */ {1, 100, 2, 2, 5, 520, 0, 0}, 700, 400, 0, 0, /*/367, */ 9, { { "Mini", "bitmaps/blueprints/mini.xpm", "bitmaps/textures/metal6.xpm", BRIGHTON_STRETCH, /* flags */ 0, miniConfigure, miniCallback, 15, 25, 970, 570, DEVICE_COUNT, locations }, { "Keyboard", 0, "bitmaps/newkeys/ekbg.xpm", 0x020|BRIGHTON_STRETCH|BRIGHTON_KEY_PANEL, 0, 0, keyCallback, 150, 700, 845, 280, KEY_COUNT_3OCTAVE, keys3octave }, { "Mods", "bitmaps/blueprints/mods.xpm", "bitmaps/textures/metal6.xpm", /* flags */ BRIGHTON_STRETCH, 0, 0, modCallback, 15, 700, 145, 280, 2, mods }, { "SP2", 0, "bitmaps/textures/wood4.xpm", 0, /*BRIGHTON_STRETCH|BRIGHTON_VERTICAL, // flags */ 0, 0, 0, 15, 0, 970, 25, 0, 0 }, { "SP1", 0, "bitmaps/textures/wood2.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 0, 0, 15, 1000, 0, 0 }, { "SP2", 0, "bitmaps/textures/wood2.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 985, 0, 17, 1000, 0, 0 }, { "SP2", 0, "bitmaps/textures/wood.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 2, 597, 11, 390, 0, 0 }, { "SP2", 0, "bitmaps/textures/wood.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 986, 597, 14, 390, 0, 0 }, { "SP2", 0, "bitmaps/textures/wood2.xpm", 0, /*BRIGHTON_STRETCH|BRIGHTON_VERTICAL, // flags */ 0, 0, 0, 15, 982, 970, 18, 0, 0 } } }; static int midiCallback(brightonWindow *win, int controller, int value, float n) { guiSynth *synth = findSynth(global.synths, win); //printf("midi callback: %x, %i\n", controller, value); switch(controller) { case MIDI_PROGRAM: //printf("midi program: %x, %i\n", controller, value); synth->location = value + synth->bank * 10; if (loadMemory(synth, synth->resources->name, 0, synth->location, synth->mem.active, FIRST_DEV, 0) < 0) displayText(synth, "FRE", synth->location, FIRST_DEV + 59); else displayText(synth, "PRG", synth->location, FIRST_DEV + 59); break; case MIDI_BANK_SELECT: //printf("midi banksel: %x, %i\n", controller, value); synth->bank = value; synth->location = (synth->location % 10) + value * 10; if (loadMemory(synth, synth->resources->name, 0, synth->location, synth->mem.active, FIRST_DEV, 0) < 0) displayText(synth, "FRE", synth->location, FIRST_DEV + 59); else displayText(synth, "PRG", synth->location, FIRST_DEV + 59); break; } return(0); } /*static dispatcher dispatch[DEVICE_COUNT]; */ static int miniMidiSendMsg(void *synth, int fd, int chan, int c, int o, int v) { bristolMidiSendMsg(fd, chan, c, o, v); return(0); } static void miniDualFilterDecay(guiSynth *synth, int fd, int chan, int c, int o, int v) { bristolMidiSendMsg(fd, chan, c, 1, v); if (synth->mem.param[FIRST_DEV + 37]) bristolMidiSendMsg(fd, chan, c, 3, v); else bristolMidiSendMsg(fd, chan, c, 3, 1024); } static void miniDualDecay(guiSynth *synth, int fd, int chan, int c, int o, int v) { bristolMidiSendMsg(fd, chan, 5, 1, (int) (synth->mem.param[FIRST_DEV + 23] * C_RANGE_MIN_1)); if (synth->mem.param[FIRST_DEV + 37]) bristolMidiSendMsg(fd, chan, 5, 3, (int) (synth->mem.param[FIRST_DEV + 23] * C_RANGE_MIN_1)); else bristolMidiSendMsg(fd, chan, 5, 3, 1024); } static void miniMemory(guiSynth *synth, int fd, int chan, int c, int o, int v) { /* printf("miniMemory(%i %i %i %i %i)\n", fd, chan, c, o, v); */ switch (c) { default: case 0: synth->location = synth->location * 10 + o; if (synth->location >= 1000) synth->location = o; if (loadMemory(synth, "mini", 0, synth->location, synth->mem.active, FIRST_DEV, BRISTOL_STAT) < 0) displayText(synth, "FRE", synth->location, FIRST_DEV + 59); else displayText(synth, "PRG", synth->location, FIRST_DEV + 59); break; case 1: loadMemory(synth, "mini", 0, synth->location, synth->mem.active, FIRST_DEV, 0); displayText(synth, "PRG", synth->location, FIRST_DEV + 59); /* synth->location = 0; */ break; case 2: saveMemory(synth, "mini", 0, synth->location, FIRST_DEV); displayText(synth, "PRG", synth->location, FIRST_DEV + 59); /* synth->location = 0; */ break; case 3: while (loadMemory(synth, "mini", 0, --synth->location, synth->mem.active, FIRST_DEV, 0) < 0) { if (synth->location < 0) { synth->location = 1000; break; } } displayText(synth, "PRG", synth->location, FIRST_DEV + 59); break; case 4: while (loadMemory(synth, "mini", 0, ++synth->location, synth->mem.active, FIRST_DEV, 0) < 0) { if (synth->location > 999) { synth->location = -1; break; } } displayText(synth, "PRG", synth->location, FIRST_DEV + 59); break; } } static void miniMidi(guiSynth *synth, int fd, int chan, int c, int o, int v) { int newchan; /* printf("miniMidi(%x, %i %i %i %i %i)\n", synth, fd, chan, c, o, v); */ if ((synth->flags & OPERATIONAL) == 0) return; if (c == 1) { if ((newchan = synth->midichannel - 1) < 0) { synth->midichannel = 0; return; } } else { if ((newchan = synth->midichannel + 1) >= 16) { synth->midichannel = 15; return; } } if (global.libtest == 0) { bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_MIDICHANNEL|newchan); } synth->midichannel = newchan; displayText(synth, "MIDI", newchan + 1, FIRST_DEV + 58); } /* * For the sake of ease of use, links have been placed here to be called * by any of the devices created. They would be better in some other file, * perhaps with this as a dispatch. * * Param refers to the device index in the locations table given below. */ static int miniCallback(brightonWindow * win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); int sendvalue; /* printf("miniCallback(%x(%x), %i, %i, %f): %i %x\n", */ /* win, synth, panel, index, value, synth); */ if (synth == 0) return(0); if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0)) return(0); if (synth->dispatch[index].controller >= DEVICE_COUNT) return(0); if (miniApp.resources[0].devlocn[index].to == 1.0) sendvalue = value * (CONTROLLER_RANGE - 1); else sendvalue = value; synth->mem.param[index] = value; if ((!global.libtest) || (index >= ACTIVE_DEVS)) synth->dispatch[index].routine(synth, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); /* else printf("dispatch[%x,%i](%i, %i, %i, %i, %i)\n", synth, index, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); */ return(0); } /* * Any location initialisation required to run the callbacks. For bristol, this * will connect to the engine, and give it some base parameters. * May need to generate some application specific menus. * Will also then make specific requests to some of the devices to alter their * rendering. */ static int miniInit(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); dispatcher *dispatch; int i; if (synth == 0) { synth = findSynth(global.synths, (int) 0); if (synth == 0) { printf("cannot init\n"); return(0); } } synth->win = win; printf("Initialise the mini link to bristol: %p\n", synth->win); synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float)); synth->mem.count = DEVICE_COUNT; synth->mem.active = ACTIVE_DEVS; synth->dispatch = (dispatcher *) brightonmalloc(DEVICE_COUNT * sizeof(dispatcher)); dispatch = synth->dispatch; /* * We really want to have three connection mechanisms. These should be * 1. Unix named sockets. * 2. UDP sockets. * 3. MIDI pipe. */ if (!global.libtest) if ((synth->sid = initConnection(&global, synth)) < 0) return(-1); for (i = 0; i < DEVICE_COUNT; i++) synth->dispatch[i].routine = miniMidiSendMsg; /* Tune, Glide, Modmix */ dispatch[FIRST_DEV + 0].controller = 10; dispatch[FIRST_DEV + 0].operator = 0; dispatch[FIRST_DEV + 1].controller = 9; dispatch[FIRST_DEV + 1].operator = 0; dispatch[FIRST_DEV + 2].controller = 11; dispatch[FIRST_DEV + 2].operator = 1; /* Osc */ dispatch[FIRST_DEV + 3].controller = 0; dispatch[FIRST_DEV + 3].operator = 1; dispatch[FIRST_DEV + 4].controller = 1; dispatch[FIRST_DEV + 4].operator = 1; dispatch[FIRST_DEV + 5].controller = 2; dispatch[FIRST_DEV + 5].operator = 1; dispatch[FIRST_DEV + 6].controller = 1; dispatch[FIRST_DEV + 6].operator = 2; dispatch[FIRST_DEV + 7].controller = 2; dispatch[FIRST_DEV + 7].operator = 2; dispatch[FIRST_DEV + 8].controller = 0; dispatch[FIRST_DEV + 8].operator = 0; dispatch[FIRST_DEV + 9].controller = 1; dispatch[FIRST_DEV + 9].operator = 0; dispatch[FIRST_DEV + 10].controller = 2; dispatch[FIRST_DEV + 10].operator = 0; /* MIX */ dispatch[FIRST_DEV + 11].controller = 0; dispatch[FIRST_DEV + 11].operator = 3; dispatch[FIRST_DEV + 12].controller = 8; dispatch[FIRST_DEV + 12].operator = 0; dispatch[FIRST_DEV + 13].controller = 1; dispatch[FIRST_DEV + 13].operator = 3; dispatch[FIRST_DEV + 14].controller = 7; dispatch[FIRST_DEV + 14].operator = 0; dispatch[FIRST_DEV + 15].controller = 2; dispatch[FIRST_DEV + 15].operator = 3; dispatch[FIRST_DEV + 16].controller = 4; dispatch[FIRST_DEV + 16].operator = 0; dispatch[FIRST_DEV + 17].controller = 4; dispatch[FIRST_DEV + 17].operator = 1; dispatch[FIRST_DEV + 18].controller = 4; dispatch[FIRST_DEV + 18].operator = 2; dispatch[FIRST_DEV + 19].controller = 3; dispatch[FIRST_DEV + 19].operator = 0; dispatch[FIRST_DEV + 20].controller = 3; dispatch[FIRST_DEV + 20].operator = 1; /* special */ dispatch[FIRST_DEV + 20].routine = (synthRoutine) miniDualFilterDecay; dispatch[FIRST_DEV + 21].controller = 3; dispatch[FIRST_DEV + 21].operator = 2; dispatch[FIRST_DEV + 22].controller = 5; dispatch[FIRST_DEV + 22].operator = 0; dispatch[FIRST_DEV + 23].controller = 5; dispatch[FIRST_DEV + 23].operator = 1; /* special */ dispatch[FIRST_DEV + 23].routine = (synthRoutine) miniDualDecay; dispatch[FIRST_DEV + 24].controller = 5; dispatch[FIRST_DEV + 24].operator = 2; dispatch[FIRST_DEV + 25].controller = 5; dispatch[FIRST_DEV + 25].operator = 4; dispatch[FIRST_DEV + 26].controller = 12; dispatch[FIRST_DEV + 26].operator = 7; dispatch[FIRST_DEV + 27].controller = 12; dispatch[FIRST_DEV + 27].operator = 6; dispatch[FIRST_DEV + 28].controller = 12; dispatch[FIRST_DEV + 28].operator = 10; dispatch[FIRST_DEV + 29].controller = 12; dispatch[FIRST_DEV + 29].operator = 13; dispatch[FIRST_DEV + 30].controller = 12; dispatch[FIRST_DEV + 30].operator = 11; dispatch[FIRST_DEV + 31].controller = 12; dispatch[FIRST_DEV + 31].operator = 14; dispatch[FIRST_DEV + 32].controller = 12; dispatch[FIRST_DEV + 32].operator = 12; dispatch[FIRST_DEV + 33].controller = 7; dispatch[FIRST_DEV + 33].operator = 1; dispatch[FIRST_DEV + 34].controller = 12; dispatch[FIRST_DEV + 34].operator = 1; dispatch[FIRST_DEV + 35].controller = 12; dispatch[FIRST_DEV + 35].operator = 4; dispatch[FIRST_DEV + 36].controller = 12; dispatch[FIRST_DEV + 36].operator = 0; dispatch[FIRST_DEV + 37].routine = (synthRoutine) miniDualDecay; dispatch[FIRST_DEV + 38].controller = 12; dispatch[FIRST_DEV + 38].operator = 15; dispatch[FIRST_DEV + 39].controller = 12; dispatch[FIRST_DEV + 39].operator = 2; dispatch[FIRST_DEV + 40].controller = 4; dispatch[FIRST_DEV + 40].operator = 3; dispatch[FIRST_DEV + 41].controller = 5; dispatch[FIRST_DEV + 41].operator = 5; dispatch[ACTIVE_DEVS +0].routine = dispatch[ACTIVE_DEVS +1].routine = dispatch[ACTIVE_DEVS +2].routine = dispatch[ACTIVE_DEVS +3].routine = dispatch[ACTIVE_DEVS +4].routine = dispatch[ACTIVE_DEVS +5].routine = dispatch[ACTIVE_DEVS +6].routine = dispatch[ACTIVE_DEVS +7].routine = dispatch[ACTIVE_DEVS +8].routine = dispatch[ACTIVE_DEVS +9].routine = dispatch[ACTIVE_DEVS +10].routine = dispatch[ACTIVE_DEVS +11].routine = dispatch[ACTIVE_DEVS +14].routine = dispatch[ACTIVE_DEVS +15].routine = (synthRoutine) miniMemory; dispatch[ACTIVE_DEVS + 0].controller = 1; dispatch[ACTIVE_DEVS + 1].controller = 2; dispatch[ACTIVE_DEVS + 2].operator = 0; dispatch[ACTIVE_DEVS + 3].operator = 1; dispatch[ACTIVE_DEVS + 4].operator = 2; dispatch[ACTIVE_DEVS + 5].operator = 3; dispatch[ACTIVE_DEVS + 6].operator = 4; dispatch[ACTIVE_DEVS + 7].operator = 5; dispatch[ACTIVE_DEVS + 8].operator = 6; dispatch[ACTIVE_DEVS + 9].operator = 7; dispatch[ACTIVE_DEVS + 10].operator = 8; dispatch[ACTIVE_DEVS + 11].operator = 9; dispatch[ACTIVE_DEVS + 14].controller = 3; dispatch[ACTIVE_DEVS + 15].controller = 4; dispatch[ACTIVE_DEVS + 12].controller = 1; dispatch[ACTIVE_DEVS + 13].controller = 2; dispatch[ACTIVE_DEVS + 12].routine = dispatch[ACTIVE_DEVS + 13].routine = (synthRoutine) miniMidi; /* Tune osc-1 */ bristolMidiSendMsg(global.controlfd, synth->sid, 0, 2, 8192); /* Gain on filter contour */ bristolMidiSendMsg(global.controlfd, synth->sid, 3, 4, CONTROLLER_RANGE - 1); /* * Filter type, this selects a Houvilainen filter */ bristolMidiSendMsg(global.controlfd, synth->sid, 4, 4, 4); /* * Pink filter configuration */ bristolMidiSendMsg(global.controlfd, synth->sid, 7, 2, 4096); return(0); } static void configureKeylatch(guiSynth *synth) { if (synth->keypanel < 0) return; if (synth->flags & NO_LATCHING_KEYS) { int i, p = synth->keypanel; for (i = 0; i < synth->win->app->resources[p].ndevices; i++) synth->win->app->resources[p].devlocn[i].flags |= BRIGHTON_NO_TOGGLE; if (synth->keypanel2 < 0) return; p = synth->keypanel2; for (i = 0; i < synth->win->app->resources[p].ndevices; i++) synth->win->app->resources[p].devlocn[i].flags |= BRIGHTON_NO_TOGGLE; } } /* * These aught to be moved into a more common file, brightonRoutines.c or * similar. */ int configureGlobals(guiSynth *synth) { if (global.libtest) { int count = 10; printf("libtest flagged"); while (global.libtest) { usleep(100000); if (--count == 0) break; } if (count) printf(", cleared\n"); else printf("\n"); } if (!global.libtest) { configureKeylatch(synth); if (synth->flags & REQ_MIDI_DEBUG) { bristolMidiSendNRP(global.controlfd, synth->midichannel, BRISTOL_NRP_DEBUG, 1); if (synth->sid2 != 0) bristolMidiSendNRP(global.manualfd, synth->midichannel+1, BRISTOL_NRP_DEBUG, 1); } if (synth->flags & REQ_MIDI_DEBUG2) { bristolMidiSendNRP(global.controlfd, synth->midichannel, BRISTOL_NRP_DEBUG, 2); if (synth->sid2 != 0) bristolMidiSendNRP(global.manualfd, synth->midichannel+1, BRISTOL_NRP_DEBUG, 2); } /* Send debug level request to engine and also setup local debugging */ bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_SYSTEM, 0, BRISTOL_REQ_DEBUG|((synth->flags&REQ_DEBUG_MASK)>>12)); if (synth->sid2 != 0) bristolMidiSendMsg(global.manualfd, synth->sid2, BRISTOL_SYSTEM, 0, BRISTOL_REQ_DEBUG|((synth->flags&REQ_DEBUG_MASK)>>12)); bristolMidiOption(global.controlfd, BRISTOL_NRP_DEBUG, (synth->flags&REQ_DEBUG_MASK)>>12); if (synth->sid2 != 0) bristolMidiOption(global.manualfd, BRISTOL_NRP_DEBUG, (synth->flags&REQ_DEBUG_MASK)>>12); bristolMidiSendNRP(global.controlfd, synth->midichannel, BRISTOL_NRP_GLIDE, synth->glide * C_RANGE_MIN_1 / 30); bristolMidiSendNRP(global.controlfd, synth->midichannel, BRISTOL_NRP_GAIN, synth->gain); bristolMidiSendNRP(global.controlfd, synth->midichannel, BRISTOL_NRP_DETUNE, synth->detune); bristolMidiSendRP(global.controlfd, synth->midichannel, MIDI_RP_PW, synth->pwd); bristolMidiSendNRP(global.controlfd, synth->midichannel, BRISTOL_NRP_VELOCITY, synth->velocity); bristolMidiSendNRP(global.controlfd, synth->midichannel, BRISTOL_NRP_LWF, synth->lwf); bristolMidiSendNRP(global.controlfd, synth->midichannel, BRISTOL_NRP_MNL_PREF, synth->notepref); bristolMidiSendNRP(global.controlfd, synth->midichannel, BRISTOL_NRP_MNL_TRIG, synth->notetrig); bristolMidiSendNRP(global.controlfd, synth->midichannel, BRISTOL_NRP_MNL_VELOC, synth->legatovelocity); /* Global message forwarding on/off */ bristolMidiSendNRP(global.controlfd, synth->midichannel, BRISTOL_NRP_FORWARD, synth->flags & REQ_FORWARD? 1:0); bristolMidiOption(global.controlfd, BRISTOL_NRP_FORWARD, synth->flags & REQ_FORWARD? 1:0); if (synth->flags & MIDI_NRP) bristolMidiSendNRP(global.controlfd, synth->midichannel, BRISTOL_NRP_ENABLE_NRP, 1); else bristolMidiSendNRP(global.controlfd, synth->midichannel, BRISTOL_NRP_ENABLE_NRP, 0); bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_LOWKEY|synth->lowkey); bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_HIGHKEY|synth->highkey); if (synth->sid2 != 0) { bristolMidiSendNRP(global.controlfd, synth->midichannel+1, BRISTOL_NRP_GLIDE, synth->glide * C_RANGE_MIN_1 / 30); bristolMidiSendNRP(global.controlfd, synth->midichannel+1, BRISTOL_NRP_GAIN, synth->gain); bristolMidiSendNRP(global.controlfd, synth->midichannel+1, BRISTOL_NRP_DETUNE, synth->detune); bristolMidiSendRP(global.controlfd, synth->midichannel+1, MIDI_RP_PW, synth->pwd); bristolMidiSendNRP(global.controlfd, synth->midichannel+1, BRISTOL_NRP_VELOCITY, synth->velocity); bristolMidiSendNRP(global.controlfd, synth->midichannel+1, BRISTOL_NRP_LWF, synth->lwf); if (synth->flags & MIDI_NRP) bristolMidiSendNRP(global.controlfd, synth->midichannel+1, BRISTOL_NRP_ENABLE_NRP, 1); else bristolMidiSendNRP(global.controlfd, synth->midichannel+1, BRISTOL_NRP_ENABLE_NRP, 0); bristolMidiSendMsg(global.controlfd, synth->sid2, 127, 0, BRISTOL_LOWKEY|synth->lowkey); bristolMidiSendMsg(global.controlfd, synth->sid2, 127, 0, BRISTOL_HIGHKEY|synth->highkey); } if (synth->flags & REQ_LOCAL_FORWARD) { bristolMidiOption(global.controlfd, BRISTOL_NRP_FORWARD, 1); bristolMidiOption(global.controlfd, BRISTOL_NRP_MIDI_GO, 1); bristolMidiOption(global.controlfd, BRISTOL_NRP_REQ_FORWARD, 1); } /* Forwarding options for this emulator */ if (synth->flags & REQ_REMOTE_FORWARD) bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_SYSTEM, 0, BRISTOL_REQ_FORWARD|1); /* Forwarding options disabled for second manual, local and remote */ if (global.manualfd != 0) { bristolMidiOption(global.manualfd, BRISTOL_NRP_REQ_SYSEX, 1); bristolMidiSendMsg(global.manualfd, synth->sid2, BRISTOL_SYSTEM, 0, BRISTOL_REQ_FORWARD); } bristolMidiSendNRP(global.controlfd, synth->midichannel, BRISTOL_NRP_MIDI_GO, 1024); } /* * We should consider seeding the synth with a short note blip if ((global.synths->notepref == BRIGHTON_HNP) || (global.synths->notepref == BRIGHTON_LNP)) { sleep(1); bristolMidiSendMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_KEYON, 0, 5); sleep(1); bristolMidiSendMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_KEYOFF, 0, 5); } */ return(0); } /* * This will be called to make any routine specific parameters available. */ static int miniConfigure(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); brightonEvent event; memset(&event, 0, sizeof(brightonEvent)); if (synth == 0) { printf("problems going operational\n"); return(-1); } if (synth->flags & OPERATIONAL) return(0); printf("going operational: %p, %p\n", synth, win); synth->flags |= OPERATIONAL; synth->transpose = 36; synth->keypanel = KEY_PANEL; synth->keypanel2 = -1; /* * We now want to set a couple of parameters provided by switches in the * 0.9 release but configurable per synth. These are detune and gain to * start with. Some of this code could be separated as it is likely to be * common to each synth. These parameters will be sent to the engine using * midi non-registered parameters. These will be sent as NRP-98/99 and Data * Entry-6/38. To simplify the interface we should be able to make one call * send a NRP including the number and its 14 bit value. It is up to the * interface to decide how to send it depending on whether it is a repeat * message or not. */ configureGlobals(synth); loadMemory(synth, "mini", 0, synth->location, synth->mem.active, FIRST_DEV, 0); brightonPut(win, "bitmaps/blueprints/minishade.xpm", 0, 0, win->width, win->height); /* * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only * occurs on first paint, so we suppress the first paint and then request * an expose here. */ event.type = BRIGHTON_EXPOSE; event.intvalue = 1; brightonParamChange(synth->win, KEY_PANEL, -1, &event); return(0); } bristol-0.60.11/brighton/brightonSAks.c0000644000175000017500000007066511746476475014677 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* Synthi Sound alike */ #include #include #include "brighton.h" #include "brightonMini.h" #include "brightoninternals.h" static int sAksInit(); static int sAksConfigure(); static int sAksCallback(brightonWindow *, int, int, float); extern guimain global; #include "brightonKeys.h" #define DEVICE_COUNT (81 + 256) #define ACTIVE_DEVS (59 + 256) #define DISPLAY (DEVICE_COUNT - 1) #define MEM_START (ACTIVE_DEVS + 5) #define MIDI_START (MEM_START + 14) /* * This structure is for device definition. The structure is defined in * include/brighton.h, further definitions in brighton/brightonDevtable.h and * include/brightoninternals.h * * typedef int (*brightonCallback)(int, float); * typedef struct BrightonLocations { * int device; 0=rotary, 1=scale, etc. * float relx, rely; relative position with regards to 1000 by 1000 window * float relw, relh; relative height. * int from, to; * brightonCallback callback; specific to this dev * char *image; bitmap. If zero take a device default. * int flags; * } brightonLocations; * * This example is for a sAksBristol type synth interface. */ #define CD1 88 #define CC1 83 #define CC2 (CC1 + CD1) #define CC3 (CC2 + CD1) #define CC4 (CC3 + CD1) #define CC5 (CC4 + CD1) #define CC6 (CC5 + CD1) #define CC7 (CC6 + CD1) #define CC8 (CC7 + CD1) #define CC9 (CC8 + CD1) #define CC10 (CC9 + CD1) #define CC4b (CC3 + CD1 + 45) #define CC5b (CC4 + CD1 + 45) #define CC6b (CC5 + CD1 + 45) #define CC7b (CC6 + CD1 + 45) #define RD1 140 #define RD2 190 #define R0 129 #define R1 (R0 + RD1) #define R2 (R1 + RD1) #define R3 (R2 + RD1) #define R4 (R3 + RD1) #define R5 (R4 + RD1) #define S1 75 #define S2 75 #define S3 95 #define S4 25 #define PSPX 508 #define PSPY 500 #define PS1 ((float) 250 / 16.1f) #define PS2 ((float) 349 / 16.1f) #define PATCHBUS(y) \ {"", 2, PSPX + PS1 * 0 - 1, PSPY + PS2 * y, PS1, PS2, 0, 2, 0, \ "patchonSA", 0 , BRIGHTON_NOSHADOW|BRIGHTON_FIVEWAY},\ {"", 2, PSPX + PS1 * 1, PSPY + PS2 * y, PS1, PS2, 0, 2, 0, \ "patchonSA", "patchonSA", BRIGHTON_NOSHADOW|BRIGHTON_FIVEWAY},\ {"", 2, PSPX + PS1 * 2, PSPY + PS2 * y, PS1, PS2, 0, 2, 0, \ "patchonSA", "patchonSA", BRIGHTON_NOSHADOW|BRIGHTON_FIVEWAY},\ {"", 2, PSPX + PS1 * 3, PSPY + PS2 * y, PS1, PS2, 0, 2, 0, \ "patchonSA", "patchonSA", BRIGHTON_NOSHADOW|BRIGHTON_FIVEWAY},\ {"", 2, PSPX + PS1 * 4, PSPY + PS2 * y, PS1, PS2, 0, 2, 0, \ "patchonSA", "patchonSA", BRIGHTON_NOSHADOW|BRIGHTON_FIVEWAY},\ {"", 2, PSPX + PS1 * 5, PSPY + PS2 * y, PS1, PS2, 0, 2, 0, \ "patchonSA", "patchonSA", BRIGHTON_NOSHADOW|BRIGHTON_FIVEWAY},\ {"", 2, PSPX + PS1 * 6, PSPY + PS2 * y, PS1, PS2, 0, 2, 0, \ "patchonSA", "patchonSA", BRIGHTON_NOSHADOW|BRIGHTON_FIVEWAY},\ {"", 2, PSPX + PS1 * 7, PSPY + PS2 * y, PS1, PS2, 0, 2, 0, \ "patchonSA", "patchonSA", BRIGHTON_NOSHADOW|BRIGHTON_FIVEWAY},\ {"", 2, PSPX + PS1 * 8, PSPY + PS2 * y, PS1, PS2, 0, 2, 0, \ "patchonSA", "patchonSA", BRIGHTON_NOSHADOW|BRIGHTON_FIVEWAY},\ {"", 2, PSPX + PS1 * 9, PSPY + PS2 * y, PS1, PS2, 0, 2, 0, \ "patchonSA", "patchonSA", BRIGHTON_NOSHADOW|BRIGHTON_FIVEWAY},\ {"", 2, PSPX + PS1 * 10, PSPY + PS2 * y, PS1, PS2, 0, 2, 0, \ "patchonSA", "patchonSA", BRIGHTON_NOSHADOW|BRIGHTON_FIVEWAY},\ {"", 2, PSPX + PS1 * 11, PSPY + PS2 * y, PS1, PS2, 0, 2, 0, \ "patchonSA", "patchonSA", BRIGHTON_NOSHADOW|BRIGHTON_FIVEWAY},\ {"", 2, PSPX + PS1 * 12, PSPY + PS2 * y, PS1, PS2, 0, 2, 0, \ "patchonSA", "patchonSA", BRIGHTON_NOSHADOW|BRIGHTON_FIVEWAY},\ {"", 2, PSPX + PS1 * 13, PSPY + PS2 * y, PS1, PS2, 0, 2, 0, \ "patchonSA", "patchonSA", BRIGHTON_NOSHADOW|BRIGHTON_FIVEWAY},\ {"", 2, PSPX + PS1 * 14, PSPY + PS2 * y, PS1, PS2, 0, 2, 0, \ "patchonSA", "patchonSA", BRIGHTON_NOSHADOW|BRIGHTON_FIVEWAY},\ {"", 2, PSPX + PS1 * 15, PSPY + PS2 * y, PS1, PS2, 0, 2, 0, \ "patchonSA", "patchonSA", BRIGHTON_NOSHADOW|BRIGHTON_FIVEWAY},\ static brightonLocations locations[DEVICE_COUNT] = { /* 0 Filter Check controller 50 that adjusts filter/fine. */ {"", 0, CC4b, R0, S1 - 3, S2 - 3, 0, 1, 0, "bitmaps/knobs/knobbluenew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, CC5b, R0, S1, S2, 0, 1, 0, "bitmaps/knobs/knobyellownew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, CC6b, R0, S1, S2, 0, 1, 0, "bitmaps/knobs/knobgreynew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, /* Ring Mod */ {"", 0, CC7b, R0, S1, S2, 0, 1, 0, "bitmaps/knobs/knobgreynew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, /* 4 osc 1 Inner and outer tuners first. */ {"", 0, CC1 + 1, R1 + 0, S1 - 3, S2 - 3, 0, 1, 0, "bitmaps/knobs/knobbluenew.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_NOSHADOW}, {"", 0, CC1 - 7, R1 - 10, S3, S3, 0, 1, 0, "bitmaps/knobs/knobhollownew.xpm", 0, 0}, {"", 0, CC2, R1, S1, S2, 0, 1, 0, "bitmaps/knobs/knobgreennew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, CC3, R1, S1, S2, 0, 1, 0, "bitmaps/knobs/knobgreynew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, CC4, R1, S1, S2, 0, 1, 0, "bitmaps/knobs/knobgreynew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, /* 9 Env */ {"", 0, CC5, R1, S1, S2, 0, 1, 0, "bitmaps/knobs/knobrednew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, CC6, R1, S1, S2, 0, 1, 0, "bitmaps/knobs/knobrednew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, CC7, R1, S1, S2, 0, 1, 0, "bitmaps/knobs/knobrednew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, CC8, R1, S1, S2, 0, 1, 0, "bitmaps/knobs/knobrednew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, CC9, R1, S1, S2, 0, 1, 0, "bitmaps/knobs/knobgreynew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, CC10, R1, S1, S2, 0, 1, 0, "bitmaps/knobs/knobgreynew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, /* 15 Osc 2 */ {"", 0, CC1 + 1, R2 + 0, S1 - 3, S2 - 3, 0, 1, 0, "bitmaps/knobs/knobbluenew.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_NOSHADOW}, {"", 0, CC1 - 7, R2 - 10, S3, S3, 0, 1, 0, "bitmaps/knobs/knobhollownew.xpm", 0, 0}, {"", 0, CC2, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knobgreennew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, CC3, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knobgreynew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, CC4, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knobgreynew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, CC9, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knobgreennew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, CC10, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knobgreynew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, /* 22 Osc 3 */ {"", 0, CC1 + 1, R3 + 0, S1 - 3, S2 - 3, 0, 1, 0, "bitmaps/knobs/knobbluenew.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_NOSHADOW}, {"", 0, CC1 - 7, R3 - 10, S3, S3, 0, 1, 0, "bitmaps/knobs/knobhollownew.xpm", 0, 0}, {"", 0, CC2, R3, S1, S2, 0, 1, 0, "bitmaps/knobs/knobgreennew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, CC3, R3, S1, S2, 0, 1, 0, "bitmaps/knobs/knobgreynew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, CC4, R3, S1, S2, 0, 1, 0, "bitmaps/knobs/knobgreynew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, CC9, R3, S1, S2, 0, 1, 0, "bitmaps/knobs/knobgreynew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, CC10, R3, S1, S2, 0, 1, 0, "bitmaps/knobs/knobgreynew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, /* Noise 29 */ {"", 0, CC1, R4, S1, S2, 0, 1, 0, "bitmaps/knobs/knobbluenew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, CC2, R4, S1, S2, 0, 1, 0, "bitmaps/knobs/knobgreynew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, CC3, R4, S1, S2, 0, 1, 0, "bitmaps/knobs/knobyellownew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, CC4, R4, S1, S2, 0, 1, 0, "bitmaps/knobs/knobyellownew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, CC9 - 15, R4, S1, S2, 0, 1, 0, "bitmaps/knobs/knobgreennew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, CC10, R4, S1, S2, 0, 1, 0, "bitmaps/knobs/knobgreennew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, /* 35 */ {"", 0, CC1, R5, S1, S2, 0, 1, 0, "bitmaps/knobs/knobgreynew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, CC2, R5, S1, S2, 0, 1, 0, "bitmaps/knobs/knobgreennew.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_NOTCH}, {"", 0, CC3, R5, S1, S2, 0, 1, 0, "bitmaps/knobs/knobgreennew.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_NOTCH}, {"", 0, CC4, R5, S1, S2, 0, 1, 0, "bitmaps/knobs/knobgreynew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, /* 39 - Filter Fine. */ /*{"", 0, CC4b, R0, S1, S2, 0, 1, 0, "bitmaps/knobs/knobbluenew.xpm", */ {"", 0, CC4b - 7, R0 - 10, S3, S3, 0, 1, 0, "bitmaps/knobs/knobhollownew.xpm", 0, 0}, /* 40 - 19 Dummies for later use. */ {"", 0, CC4, R5, S1, S2, 0, 1, 0, "bitmaps/knobs/knobgreynew.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, CC4, R5, S1, S2, 0, 1, 0, "bitmaps/knobs/knobgreynew.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 923, 890, 40, 40, 0, 1.0, 0, "bitmaps/knobs/knob2.xpm", 0, BRIGHTON_WITHDRAWN}, {"", 0, CC4, R5, S1, S2, 0, 1, 0, "bitmaps/knobs/knobgreynew.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, CC4, R5, S1, S2, 0, 1, 0, "bitmaps/knobs/knobgreynew.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, CC4, R5, S1, S2, 0, 1, 0, "bitmaps/knobs/knobgreynew.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, CC4, R5, S1, S2, 0, 1, 0, "bitmaps/knobs/knobgreynew.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, CC4, R5, S1, S2, 0, 1, 0, "bitmaps/knobs/knobgreynew.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, CC4, R5, S1, S2, 0, 1, 0, "bitmaps/knobs/knobgreynew.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, CC4, R5, S1, S2, 0, 1, 0, "bitmaps/knobs/knobgreynew.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, CC4, R5, S1, S2, 0, 1, 0, "bitmaps/knobs/knobgreynew.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, CC4, R5, S1, S2, 0, 1, 0, "bitmaps/knobs/knobgreynew.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 923, 890, 40, 40, 0, 1.0, 0, "bitmaps/knobs/knob2.xpm", 0, BRIGHTON_WITHDRAWN}, {"", 0, CC4, R5, S1, S2, 0, 1, 0, "bitmaps/knobs/knobgreynew.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, CC4, R5, S1, S2, 0, 1, 0, "bitmaps/knobs/knobgreynew.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, CC4, R5, S1, S2, 0, 1, 0, "bitmaps/knobs/knobgreynew.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, CC4, R5, S1, S2, 0, 1, 0, "bitmaps/knobs/knobgreynew.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, CC4, R5, S1, S2, 0, 1, 0, "bitmaps/knobs/knobgreynew.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, CC4, R5, S1, S2, 0, 1, 0, "bitmaps/knobs/knobgreynew.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, /* From 59 - the patch matrix */ PATCHBUS(0.0f) PATCHBUS(1.0f) PATCHBUS(2.0f) PATCHBUS(3.0f) PATCHBUS(4.0f) PATCHBUS(5.0f) PATCHBUS(6.0f) PATCHBUS(7.0f) PATCHBUS(8.0f) PATCHBUS(9.0f) PATCHBUS(10.0f) PATCHBUS(11.0f) PATCHBUS(12.0f) PATCHBUS(13.0f) PATCHBUS(14.0f) PATCHBUS(15.0f) /* 315 (59 + 256) Touch panel */ {"", 5, 810, 814, 79, 128, 0, 1, 0, "bitmaps/images/sphere.xpm", 0, BRIGHTON_WIDE}, {"", 5, 810, 814, 79, 128, 0, 1, 0, "bitmaps/images/sphere.xpm", 0, BRIGHTON_WITHDRAWN}, /* 317 Monitor switches */ {"", 2, 130, RD2, 37, 18, 0, 2, 0, "switch", 0, BRIGHTON_VERTICAL|BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW}, {"", 2, 850, RD2, 37, 18, 0, 2, 0, "switch", 0, BRIGHTON_VERTICAL|BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW}, /* 319 Trigger switch */ {"", 2, 928, 850, 20, 30, 0, 1.01, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlo.xpm", BRIGHTON_NOSHADOW}, #define C18 230 #define C19 260 #define C20 306 #define C21 334 #define C22 362 #define R1_1 87 #define R21_0 120 #define R21_1 154 #define R22_1 186 #define S5 17 #define S6 20 /* Memory/Midi */ /* Load/Save */ {"", 2, C20, R22_1, S5, S6, 0, 1, 0, "bitmaps/buttons/touchnl.xpm", "bitmaps/buttons/touchgb.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, {"", 2, C22, R22_1, S5, S6, 0, 1, 0, "bitmaps/buttons/touchnlo.xpm", "bitmaps/buttons/touchgb.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, /* 1 - 3 */ /* {"", 2, C20, R1_1, S5, S6, 0, 1, 0, "bitmaps/digits/1.xpm", */ {"", 2, C20, R1_1, S5, S6, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchgb.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, {"", 2, C21, R1_1, S5, S6, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchgb.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, {"", 2, C22, R1_1, S5, S6, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchgb.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, /* 4 - 6 */ {"", 2, C20, R21_0, S5, S6, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchgb.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, {"", 2, C21, R21_0, S5, S6, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchgb.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, {"", 2, C22, R21_0, S5, S6, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchgb.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, /* 7 - 9 */ {"", 2, C20, R21_1, S5, S6, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchgb.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, {"", 2, C21, R21_1, S5, S6, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchgb.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, {"", 2, C22, R21_1, S5, S6, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchgb.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, /* 0 */ {"", 2, C21, R22_1, S5, S6, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchgb.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, /* mem/midi Up/down */ {"", 2, C19, R21_1, S5, S6, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchgb.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, {"", 2, C19, R22_1, S5, S6, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchgb.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, {"", 2, C18, R22_1, S5, S6, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchgb.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, {"", 2, C18, R21_1, S5, S6, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchgb.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, {"", 3, 199, R1_1 + 23, 106, 25, 0, 1, 0, 0, "bitmaps/images/alphadisplay3.xpm", 0} }; /* */ /* * This is a set of globals for the main window rendering. Again taken from * include/brighton.h */ brightonApp sAksApp = { "aks", 0, /* no blueprint on wood background. */ "bitmaps/textures/metal6.xpm", 0, sAksInit, sAksConfigure, /* 3 callbacks, unused? */ 0, destroySynth, {1, 0, 2, 2, 5, 520, 0, 0}, 700, 500, 0, 0, 1, /* Panels */ { { "synthi", "bitmaps/blueprints/sAks.xpm", "bitmaps/textures/metal1.xpm", BRIGHTON_STRETCH, /* flags */ 0, 0, sAksCallback, 0, 0, 1000, 1000, DEVICE_COUNT, locations }, } }; /*static dispatcher dispatch[DEVICE_COUNT]; */ static void sAksReverb(guiSynth *synth, int fd, int chan, int c, int o, int v) { v = v >> 1; bristolMidiSendMsg(fd, chan, 8, 0, v); bristolMidiSendMsg(fd, chan, 8, 1, v); bristolMidiSendMsg(fd, chan, 8, 2, v >> 1); } static void aksManualStart(guiSynth *synth, int fd, int chan, int c, int o, int v) { printf("trigger %i\n", v); if (v == 0) bristolMidiSendMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_KEYOFF, 0, 6); else bristolMidiSendMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_KEYON, 0, 6); } static int sAksMidiSendMsg(void *synth, int fd, int chan, int c, int o, int v) { /*printf("%i, %i, %i\n", c, o, v); */ bristolMidiSendMsg(fd, chan, c, o, v); return(0); } static void sAksMemory(guiSynth *synth, int fd, int chan, int c, int o, int v) { int cmem = synth->location; /*printf("mem(%i, %i, %i)\n", c, o, v); */ if (synth->flags & MEM_LOADING) return; switch (c) { default: case 0: synth->location = synth->location * 10 + o; if (synth->location >= 1000) synth->location = o; if (loadMemory(synth, "aks", 0, synth->location, synth->mem.active, 0, BRISTOL_STAT) < 0) displayPanelText(synth, "FRE", synth->location, 0, DISPLAY); else displayPanelText(synth, "PRG", synth->location, 0, DISPLAY); break; case 1: loadMemory(synth, "aks", 0, synth->location, synth->mem.active, 0, 0); displayPanelText(synth, "PRG", synth->location, 0, DISPLAY); synth->location = 0; break; case 2: saveMemory(synth, "aks", 0, synth->location, 0); displayPanelText(synth, "PRG", synth->location, 0, DISPLAY); synth->location = 0; break; case 3: while (loadMemory(synth, "aks", 0, --synth->location, synth->mem.active, 0, 0) < 0) { if (synth->location < 0) synth->location = 1000; if (synth->location == cmem) break; } displayPanelText(synth, "PRG", synth->location, 0, DISPLAY); break; case 4: while (loadMemory(synth, "aks", 0, ++synth->location, synth->mem.active, 0, 0) < 0) { if (synth->location > 999) synth->location = -1; if (synth->location == cmem) break; } displayPanelText(synth, "PRG", synth->location, 0, DISPLAY); break; } } static void sAksPatchPanel(guiSynth *synth, int fd, int chan, int c, int o, int v) { int value = C_RANGE_MIN_1; /* if (v != 0) */ /* printf("requested %i, %i, %i\n", c, o, v); */ /* * values: * * 4 = 5% * 3 = -6dB * 2 = 1% * 1 = invert. * 0 = 0 * * These are sent such that the sent value of 0.5 is off. below that is * negative, and above that tends to one. */ switch (v) { case 0: /* Value zero, send zero to turn pin off */ bristolMidiSendMsg(fd, chan, c + 100, o, 0); break; case 1: /* when the value is 1 send 1, which will invert the signal. */ /* Trust me, see the engine code for this synth. */ bristolMidiSendMsg(fd, chan, c + 100, o, C_RANGE_MIN_1); break; case 2: /* Accurate mapping */ value = C_RANGE_MIN_1 * 98 / 100 + ((C_RANGE_MIN_1 / 50) * (rand() >> 17)) / C_RANGE_MIN_1; bristolMidiSendMsg(fd, chan, c + 100, o, value * 19 / 20); break; case 3: /* damped by about -6dB */ bristolMidiSendMsg(fd, chan, c + 100, o, (C_RANGE_MIN_1 >> 2)); break; case 4: /* * Some half random value, perhaps with a 10% margin to emulate the * resistor accuracy of the original synth. */ value = C_RANGE_MIN_1 * 9 / 10 + ((C_RANGE_MIN_1 / 10) * (rand() >> 17)) / C_RANGE_MIN_1; printf("requested %i, %i, %i\n", c, o, value); bristolMidiSendMsg(fd, chan, c + 100, o, value); break; } } static int sAksMidi(guiSynth *synth, int fd, int chan, int c, int o, int v) { int newchan; if ((synth->flags & OPERATIONAL) == 0) return(0); if (c == 1) { if ((newchan = synth->midichannel - 1) < 0) { synth->midichannel = 0; displayPanelText(synth, "MIDI", synth->midichannel + 1, 0, DISPLAY); return(0); } } else { if ((newchan = synth->midichannel + 1) >= 15) { synth->midichannel = 15; displayPanelText(synth, "MIDI", synth->midichannel + 1, 0, DISPLAY); return(0); } } if (global.libtest == 0) { bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_MIDICHANNEL|newchan); } synth->midichannel = newchan; displayPanelText(synth, "MIDI", synth->midichannel + 1, 0, DISPLAY); return(0); } /* * For the sake of ease of use, links have been placed here to be called * by any of the devices created. They would be better in some other file, * perhaps with this as a dispatch. * * Param refers to the device index in the locations table given below. */ static int sAksCallback(brightonWindow * win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); int sendvalue; /*printf("sAksCallback(%i, %f): %x\n", index, value, synth); */ if (synth == 0) return(0); if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0)) return(0); if (sAksApp.resources[panel].devlocn[index].to == 1) sendvalue = value * C_RANGE_MIN_1; else sendvalue = value; synth->mem.param[index] = value; if ((!global.libtest) || (index >= ACTIVE_DEVS)) synth->dispatch[index].routine(synth, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #ifdef DEBUG else printf("dispatch[%p,%i](%i, %i, %i, %i, %i)\n", synth, index, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #endif return(0); } /* * Any location initialisation required to run the callbacks. For bristol, this * will connect to the engine, and give it some base parameters. * May need to generate some application specific menus. * Will also then make specific requests to some of the devices to alter their * rendering. */ static int sAksInit(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); dispatcher *dispatch; int i, in, out; if (synth == 0) { synth = findSynth(global.synths, 0); if (synth == 0) { printf("cannot init\n"); return(0); } } synth->win = win; printf("Initialise the sAks link to bristol: %p\n", synth->win); synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float)); synth->mem.count = DEVICE_COUNT; synth->mem.active = ACTIVE_DEVS; synth->dispatch = (dispatcher *) brightonmalloc(DEVICE_COUNT * sizeof(dispatcher)); dispatch = synth->dispatch; /* * We really want to have three connection mechanisms. These should be * 1. Unix named sockets. * 2. UDP sockets. * 3. MIDI pipe. */ synth->voices = 1; if (!global.libtest) if ((synth->sid = initConnection(&global, synth)) < 0) return(-1); for (i = 0; i < DEVICE_COUNT; i++) synth->dispatch[i].routine = sAksMidiSendMsg; /* Filter */ dispatch[0].controller = 3; dispatch[0].operator = 0; dispatch[1].controller = 3; dispatch[1].operator = 1; dispatch[2].controller = 3; dispatch[2].operator = 5; /* Ring mod gain */ dispatch[3].controller = 7; dispatch[3].operator = 2; /* Osc1 tuning */ dispatch[4].controller = 0; dispatch[4].operator = 0; dispatch[5].controller = 0; dispatch[5].operator = 1; dispatch[6].controller = 0; dispatch[6].operator = 2; dispatch[7].controller = 0; dispatch[7].operator = 3; dispatch[8].controller = 0; dispatch[8].operator = 4; /* ENV controllers */ dispatch[9].controller = 4; dispatch[9].operator = 0; dispatch[10].controller = 4; dispatch[10].operator = 1; dispatch[11].controller = 4; dispatch[11].operator = 2; dispatch[12].controller = 4; dispatch[12].operator = 3; dispatch[13].controller = 126; dispatch[13].operator = 16; dispatch[14].controller = 126; dispatch[14].operator = 17; /* Osc2 tuning */ dispatch[15].controller = 1; dispatch[15].operator = 0; dispatch[16].controller = 1; dispatch[16].operator = 1; dispatch[17].controller = 1; dispatch[17].operator = 2; dispatch[18].controller = 1; dispatch[18].operator = 3; dispatch[19].controller = 1; dispatch[19].operator = 4; /* Reverb */ dispatch[20].controller = 8; dispatch[20].operator = 0; /* This should be a compound controller for delay and feedback */ dispatch[20].routine = (synthRoutine) sAksReverb; dispatch[21].controller = 8; dispatch[21].operator = 4; /* Osc3 tuning */ dispatch[22].controller = 2; dispatch[22].operator = 0; dispatch[23].controller = 2; dispatch[23].operator = 1; dispatch[24].controller = 2; dispatch[24].operator = 2; dispatch[25].controller = 2; dispatch[25].operator = 3; dispatch[26].controller = 2; dispatch[26].operator = 4; /* Input gain */ dispatch[27].controller = 126; dispatch[27].operator = 2; dispatch[28].controller = 126; dispatch[28].operator = 3; /* Noise */ dispatch[29].controller = 6; dispatch[29].operator = 2; dispatch[30].controller = 6; dispatch[30].operator = 0; /* Output */ dispatch[31].controller = 126; dispatch[31].operator = 4; dispatch[32].controller = 126; dispatch[32].operator = 5; /* Range */ dispatch[33].controller = 126; dispatch[33].operator = 6; dispatch[34].controller = 126; dispatch[34].operator = 7; /* Mix */ dispatch[35].controller = 126; dispatch[35].operator = 8; dispatch[36].controller = 126; dispatch[36].operator = 9; dispatch[37].controller = 126; dispatch[37].operator = 10; dispatch[38].controller = 126; dispatch[38].operator = 11; /* filter fine */ dispatch[39].controller = 3; dispatch[39].operator = 2; /* Patch panel */ i = 59; for (out = 0; out < 16; out++) { for (in = 0; in < 16; in++) { dispatch[i].controller = in; dispatch[i].operator = out; dispatch[i].routine = (synthRoutine) sAksPatchPanel; i++; } } dispatch[ACTIVE_DEVS + 0].controller = 126; dispatch[ACTIVE_DEVS + 0].operator = 12; /* dispatch[ACTIVE_DEVS + 0].routine = (synthRoutine) sAksHShift; */ dispatch[ACTIVE_DEVS + 1].controller = 126; dispatch[ACTIVE_DEVS + 1].operator = 13; /* dispatch[ACTIVE_DEVS + 1].routine = (synthRoutine) sAksHShift; */ /* Switches */ dispatch[ACTIVE_DEVS + 2].controller = 126; dispatch[ACTIVE_DEVS + 2].operator = 14; dispatch[ACTIVE_DEVS + 3].controller = 126; dispatch[ACTIVE_DEVS + 3].operator = 15; dispatch[ACTIVE_DEVS + 4].routine = (synthRoutine) aksManualStart; dispatch[MEM_START +0].routine = dispatch[MEM_START +1].routine = dispatch[MEM_START +2].routine = dispatch[MEM_START +3].routine = dispatch[MEM_START +4].routine = dispatch[MEM_START +5].routine = dispatch[MEM_START +6].routine = dispatch[MEM_START +7].routine = dispatch[MEM_START +8].routine = dispatch[MEM_START +9].routine = dispatch[MEM_START +10].routine = dispatch[MEM_START +11].routine = dispatch[MEM_START +12].routine = dispatch[MEM_START +13].routine = (synthRoutine) sAksMemory; dispatch[MEM_START + 0].controller = 1; dispatch[MEM_START + 1].controller = 2; dispatch[MEM_START + 2].operator = 1; dispatch[MEM_START + 3].operator = 2; dispatch[MEM_START + 4].operator = 3; dispatch[MEM_START + 5].operator = 4; dispatch[MEM_START + 6].operator = 5; dispatch[MEM_START + 7].operator = 6; dispatch[MEM_START + 8].operator = 7; dispatch[MEM_START + 9].operator = 8; dispatch[MEM_START + 10].operator = 9; dispatch[MEM_START + 11].operator = 0; dispatch[MEM_START + 12].controller = 4; dispatch[MEM_START + 13].controller = 3; dispatch[MIDI_START].controller = 1; dispatch[MIDI_START + 1].controller = 2; dispatch[MIDI_START].routine = dispatch[MIDI_START + 1].routine = (synthRoutine) sAksMidi; /* Set the oscillator indeces */ bristolMidiSendMsg(global.controlfd, synth->sid, 1, 5, 1); bristolMidiSendMsg(global.controlfd, synth->sid, 2, 5, 2); /* Pink noise source (is variable with filter) */ bristolMidiSendMsg(global.controlfd, synth->sid, 6, 1, 1); /* bristolMidiSendMsg(global.controlfd, synth->sid, 1, 6, C_RANGE_MIN_1); */ /* LFO Env parameters. */ /* bristolMidiSendMsg(global.controlfd, synth->sid, 8, 1, 12000); */ /* bristolMidiSendMsg(global.controlfd, synth->sid, 8, 2, 16383); */ /* bristolMidiSendMsg(global.controlfd, synth->sid, 8, 3, 0); */ /* bristolMidiSendMsg(global.controlfd, synth->sid, 8, 4, 16383); */ /* bristolMidiSendMsg(global.controlfd, synth->sid, 8, 5, 0); */ return(0); } /* * This will be called to make any routine specific parameters available. */ static int sAksConfigure(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); brightonEvent event; if (synth == 0) { printf("problems going operational\n"); return(-1); } if (synth->flags & OPERATIONAL) return(0); printf("going operational\n"); synth->flags |= OPERATIONAL; synth->keypanel = synth->keypanel2 = -1; synth->transpose = 48; synth->bank = 0; event.value = 1; /* Poly */ loadMemory(synth, "aks", 0, synth->location, synth->mem.active, 0, 0); /* event.type = BRIGHTON_PARAMCHANGE; */ /* event.value = 1.0; */ /* brightonParamChange(synth->win, 0, ACTIVE_DEVS, &event); */ configureGlobals(synth); return(0); } bristol-0.60.11/brighton/Makefile.in0000644000175000017500000006062012073601233014140 00000000000000# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = brighton$(EXEEXT) subdir = brighton DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) am_brighton_OBJECTS = brightonArp2600.$(OBJEXT) brightonAxxe.$(OBJEXT) \ brighton.$(OBJEXT) brightonControllers.$(OBJEXT) \ brightonDX.$(OBJEXT) brightonExplorer.$(OBJEXT) \ brightonHammondB3.$(OBJEXT) brightonHammond.$(OBJEXT) \ brightonJuno.$(OBJEXT) brightonMemoryMoog.$(OBJEXT) \ brightonMini.$(OBJEXT) brightonMixer.$(OBJEXT) \ brightonMixerMemory.$(OBJEXT) brightonMixerMenu.$(OBJEXT) \ brightonMS20.$(OBJEXT) brightonOBXa.$(OBJEXT) \ brightonOBX.$(OBJEXT) brightonOdyssey.$(OBJEXT) \ brightonPoly6.$(OBJEXT) brightonPoly.$(OBJEXT) \ brightonProphet10.$(OBJEXT) brightonProphet52.$(OBJEXT) \ brightonProphet.$(OBJEXT) brightonRhodesBass.$(OBJEXT) \ brightonRhodes.$(OBJEXT) brightonRoutines.$(OBJEXT) \ brightonSAks.$(OBJEXT) brightonVox.$(OBJEXT) \ brightonSolina.$(OBJEXT) brightonRoadRunner.$(OBJEXT) \ brightonGranular.$(OBJEXT) brightonRealistic.$(OBJEXT) \ brightonVoxM2.$(OBJEXT) brightonJupiter.$(OBJEXT) \ brightonBitOne.$(OBJEXT) brightonMaster.$(OBJEXT) \ brightonCS80.$(OBJEXT) brightonProOne.$(OBJEXT) \ brightonVoyager.$(OBJEXT) brightonSonic6.$(OBJEXT) \ brightonTrilogy.$(OBJEXT) brightonStratus.$(OBJEXT) \ brightonPoly800.$(OBJEXT) brightonBME700.$(OBJEXT) \ brightonBassMaker.$(OBJEXT) brightonSID.$(OBJEXT) \ brightonSID2.$(OBJEXT) brightonCLI.$(OBJEXT) brighton_OBJECTS = $(am_brighton_OBJECTS) brighton_DEPENDENCIES = brighton_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(brighton_LDFLAGS) \ $(LDFLAGS) -o $@ DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(brighton_SOURCES) DIST_SOURCES = $(brighton_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALSA_CFLAGS = @ALSA_CFLAGS@ ALSA_LIBS = @ALSA_LIBS@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BRIGHTON_HAS_AUTOZOOM = @BRIGHTON_HAS_AUTOZOOM@ BRIGHTON_HAS_SHMIMAGE = @BRIGHTON_HAS_SHMIMAGE@ BRIGHTON_HAS_X11 = @BRIGHTON_HAS_X11@ BRIGHTON_HAS_XIMAGE = @BRIGHTON_HAS_XIMAGE@ BRIGHTON_LIBB11 = @BRIGHTON_LIBB11@ BRIGHTON_LIBX11 = @BRIGHTON_LIBX11@ BRIGHTON_LIBXEXT = @BRIGHTON_LIBXEXT@ BRIGHTON_LIBXLIBS = @BRIGHTON_LIBXLIBS@ BRIGHTON_X11_DIR = @BRIGHTON_X11_DIR@ BRISTOL_BARRIER = @BRISTOL_BARRIER@ BRISTOL_DIR = @BRISTOL_DIR@ BRISTOL_HAS_ALSA = @BRISTOL_HAS_ALSA@ BRISTOL_HAS_DRAIN = @BRISTOL_HAS_DRAIN@ BRISTOL_HAS_JACK = @BRISTOL_HAS_JACK@ BRISTOL_HAS_JACK_MIDI = @BRISTOL_HAS_JACK_MIDI@ BRISTOL_HAS_JACK_SESSION = @BRISTOL_HAS_JACK_SESSION@ BRISTOL_HAS_LIBLO = @BRISTOL_HAS_LIBLO@ BRISTOL_HAS_OSS = @BRISTOL_HAS_OSS@ BRISTOL_HAS_PA = @BRISTOL_HAS_PA@ BRISTOL_JACK_DEFAULT = @BRISTOL_JACK_DEFAULT@ BRISTOL_JACK_DEFAULT_MIDI = @BRISTOL_JACK_DEFAULT_MIDI@ BRISTOL_JACK_MULTI_CLOSE = @BRISTOL_JACK_MULTI_CLOSE@ BRISTOL_LIBPALIBS = @BRISTOL_LIBPALIBS@ BRISTOL_LIB_PA = @BRISTOL_LIB_PA@ BRISTOL_LIN_ATTACK = @BRISTOL_LIN_ATTACK@ BRISTOL_MAJOR_VERSION = @BRISTOL_MAJOR_VERSION@ BRISTOL_MICRO_VERSION = @BRISTOL_MICRO_VERSION@ BRISTOL_MINOR_VERSION = @BRISTOL_MINOR_VERSION@ BRISTOL_PA_DIR = @BRISTOL_PA_DIR@ BRISTOL_SEMAPHORE = @BRISTOL_SEMAPHORE@ BRISTOL_SEM_OPEN = @BRISTOL_SEM_OPEN@ BRISTOL_SO_VERSION = @BRISTOL_SO_VERSION@ BRISTOL_VERSION = @BRISTOL_VERSION@ BRR = @BRR@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFAULT_AUDIO_FLAG = @DEFAULT_AUDIO_FLAG@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JACK_CFLAGS = @JACK_CFLAGS@ JACK_LIBS = @JACK_LIBS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBLO_CFLAGS = @LIBLO_CFLAGS@ LIBLO_LIBS = @LIBLO_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ _BRISTOL_VOICES = @_BRISTOL_VOICES@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = foreign AM_CFLAGS = -pthread -Wall -g -I$(srcdir)/../include/brighton -I$(srcdir)/../include/bristol -DBRISTOL_HAS_ALSA=@BRISTOL_HAS_ALSA@ @BRIGHTON_HAS_X11@ -DBRISTOL_VOICECOUNT=@_BRISTOL_VOICES@ brighton_LDFLAGS = -Bdynamic -L../libbrighton/ -L../libbristolmidi/.libs @BRIGHTON_LIBXLIBS@ -L/usr/X11R6/lib -L../libbvg brighton_LDADD = -lbrighton -lbvg @BRIGHTON_LIBB11@ @BRIGHTON_LIBX11@ @BRIGHTON_LIBXEXT@ -lbristolmidi @ALSA_LIBS@ -lm -lpthread brighton_SOURCES = brightonArp2600.c brightonAxxe.c brighton.c brightonControllers.c brightonDX.c brightonExplorer.c brightonHammondB3.c brightonHammond.c brightonJuno.c brightonMemoryMoog.c brightonMini.c brightonMixer.c brightonMixerMemory.c brightonMixerMenu.c brightonMS20.c brightonOBXa.c brightonOBX.c brightonOdyssey.c brightonPoly6.c brightonPoly.c brightonProphet10.c brightonProphet52.c brightonProphet.c brightonRhodesBass.c brightonRhodes.c brightonRoutines.c brightonSAks.c brightonVox.c brightonKeyboards.h brightonKeys.h brightonMini.h brightonMixer.h brightonMixerMemory.h brightonhelp.h brightonSolina.c brightonRoadRunner.c brightonGranular.c brightonRealistic.c brightonVoxM2.c brightonJupiter.c brightonBitOne.c brightonMaster.c brightonCS80.c brightonProOne.c brightonVoyager.c brightonSonic6.c brightonTrilogy.c brightonStratus.c brightonPoly800.c brightonBME700.c brightonBassMaker.c brightonSID.c brightonSID2.c brightonSID2.h brightonreadme.h brightonCLI.c brightonVImages.h all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign brighton/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign brighton/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p || test -f $$p1; \ then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list brighton$(EXEEXT): $(brighton_OBJECTS) $(brighton_DEPENDENCIES) $(EXTRA_brighton_DEPENDENCIES) @rm -f brighton$(EXEEXT) $(brighton_LINK) $(brighton_OBJECTS) $(brighton_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brighton.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonArp2600.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonAxxe.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonBME700.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonBassMaker.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonBitOne.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonCLI.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonCS80.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonControllers.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonDX.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonExplorer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonGranular.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonHammond.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonHammondB3.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonJuno.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonJupiter.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonMS20.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonMaster.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonMemoryMoog.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonMini.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonMixer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonMixerMemory.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonMixerMenu.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonOBX.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonOBXa.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonOdyssey.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonPoly.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonPoly6.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonPoly800.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonProOne.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonProphet.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonProphet10.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonProphet52.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonRealistic.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonRhodes.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonRhodesBass.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonRoadRunner.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonRoutines.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonSAks.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonSID.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonSID2.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonSolina.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonSonic6.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonStratus.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonTrilogy.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonVox.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonVoxM2.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonVoyager.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) installdirs: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ clean-generic clean-libtool ctags distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-binPROGRAMS install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am tags uninstall uninstall-am \ uninstall-binPROGRAMS # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: bristol-0.60.11/brighton/brightonSonic6.c0000644000175000017500000011603011746476475015162 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* * Highkey/Lowkey will govern glide only. * Integrate ADSR - GUI Done * Add mod to GenX/Y - GUI Done * Add PWM * Add options for LFO multi/uni * Add modwheel - GUI Done * Add LFO for LFO gain? * Add stereo reverb? * * Add global tuning. * * Octave is -/+2 */ #include #include "brighton.h" #include "brightonMini.h" #include "brightoninternals.h" int initmem = 0; int sonic6Init(); int sonic6Configure(); int sonic6Callback(brightonWindow *, int, int, float); static int midiCallback(brightonWindow *, int, int, float); static int sonic6ModCallback(brightonWindow *, int, int, float); extern guimain global; extern int empty; #include "brightonKeys.h" #define KEY_PANEL 1 #define FIRST_DEV 0 #define DEVICE_COUNT 85 #define ACTIVE_DEVS 60 #define MEM_START (ACTIVE_DEVS + 8) #define DISPLAY_DEV (DEVICE_COUNT - 1) #define S1 80 #define S2 60 #define S3 13 #define S4 60 #define S5 25 #define S6 30 #define S7 70 #define B1 15 #define B2 110 #define B3 37 #define B4 42 #define R14 200 #define R24 400 #define R34 600 #define R44 800 #define R15 200 #define R25 350 #define R35 500 #define R45 650 #define R55 800 #define C1 25 #define C2 90 #define C3 155 #define C4 220 #define C5 285 #define C6 350 #define C6I 395 #define C7 615 #define C8 665 #define C9 742 #define C10 810 #define C11 875 #define C12 945 /* * This structure is for device definition. The structure is defined in * include/brighton.h, further definitions in brighton/brightonDevtable.h and * include/brightoninternals.h * * typedef int (*brightonCallback)(int, float); * typedef struct BrightonLocations { * int device; 0=rotary, 1=scale, etc. * float relx, rely; relative position with regards to 1000 by 1000 window * float relw, relh; relative height. * int from, to; * brightonCallback callback; specific to this dev * char *image; bitmap. If zero take a device default. * int flags; * } brightonLocations; * * This example is for a sonic6Bristol type synth interface. */ static brightonLocations locations[DEVICE_COUNT] = { /* LFO Master - 0*/ {"LFO-MasterF", 1, 114, 490, 13, 180, 0, 1, 0, "bitmaps/knobs/sliderArpBlack.xpm", 0, 0}, /* LFO 1 */ {"LFO-X-Wave", 0, 40, 253, S1, S1, 0, 3, 0, "bitmaps/knobs/knob4.xpm", 0, BRIGHTON_STEPPED}, {"LFO-X-Rate", 1, 90, 230, 13, 180, 0, 1, 0, "bitmaps/knobs/sliderArpBlack.xpm", 0, 0}, {"LFO-Dest", 2, 40, 370, S3, S4, 0, 2, 0, "sonicrocker", 0, BRIGHTON_THREEWAY}, /* LFO 2 - 4*/ {"LFO-Y-Rate", 1, 135, 230, 13, 180, 0, 1, 0, "bitmaps/knobs/sliderArpBlack.xpm", 0, 0}, {"LFO-Wave", 0, 168, 253, S1, S1, 0, 3, 0, "bitmaps/knobs/knob4.xpm", 0, BRIGHTON_STEPPED}, {"LFO-Dest", 2, 188, 370, S3, S4, 0, 2, 0, "sonicrocker", 0, BRIGHTON_THREEWAY}, /* LFO Mix */ {"LFO-MIX", 0, 106, 88, S2, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, BRIGHTON_NOTCH}, /* Osc 1 - 8 */ {"OscA-Tuning", 0, 230, 260, S2, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, BRIGHTON_NOTCH}, {"OscA-PW", 0, 230, 360, S2, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"OscA-Transpose", 2, 278, 280, S5, S6, 0, 2, 0, "sonicrocker", 0, BRIGHTON_VERTICAL|BRIGHTON_THREEWAY}, /* This can replace the previous for a 5 octave span */ // {"OscA-F", 0, 278, 260, S2, S2, 0, 4, 0, // "bitmaps/knobs/knob4.xpm", 0, BRIGHTON_STEPPED}, {"OscA-Waveform", 2, 278, 380, S5, S6, 0, 2, 0, "sonicrocker", 0, BRIGHTON_VERTICAL|BRIGHTON_THREEWAY}, {"dummy", 0, 0, 0, S2, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, BRIGHTON_WITHDRAWN}, {"dummy", 0, 0, 0, S2, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, BRIGHTON_WITHDRAWN}, {"OscA-FM-XY", 0, 230, 518, S2, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"OscA-FM-ADSR", 0, 285, 518, S2, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"OscA-Mode", 2, 260, 640, S5, S6, 0, 2, 0, "sonicrocker", 0, BRIGHTON_VERTICAL|BRIGHTON_THREEWAY}, /* Osc 2 - 17 */ {"OscB-Tuning", 0, 390, 260, S2, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, BRIGHTON_NOTCH}, {"OscB-PW", 0, 390, 360, S2, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"OscB-Transpose", 2, 337, 280, S5, S6, 0, 2, 0, "sonicrocker", 0, BRIGHTON_VERTICAL|BRIGHTON_THREEWAY}, /* This can replace the previous for a 5 octave span */ // {"OscA-F", 0, 337, 260, S2, S2, 0, 4, 0, // "bitmaps/knobs/knob4.xpm", 0, BRIGHTON_STEPPED}, {"OscB-Waveform", 2, 337, 380, S5, S6, 0, 2, 0, "sonicrocker", 0, BRIGHTON_VERTICAL|BRIGHTON_THREEWAY}, {"dummy", 0, 0, 0, S2, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, BRIGHTON_WITHDRAWN}, {"dummy", 0, 0, 0, S2, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, BRIGHTON_WITHDRAWN}, {"OscB-FM-XY", 0, 335, 518, S2, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"OscB-FM-OscA", 0, 390, 518, S2, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"OscB-PWM", 0, 362, 616, S2, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, /* Osc Mix - 26 */ {"Osc-A/B-Mix", 0, 309, 88, S2, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, BRIGHTON_NOTCH}, /* Ring Mod */ {"RM-Src1", 2, 460, 274, S5, S6, 0, 1, 0, "bitmaps/buttons/sonicrocker1.xpm", "bitmaps/buttons/sonicrocker3.xpm", BRIGHTON_VERTICAL}, {"RM-Src2", 2, 460, 380, S5, S6, 0, 1, 0, "bitmaps/buttons/sonicrocker1.xpm", "bitmaps/buttons/sonicrocker3.xpm", BRIGHTON_VERTICAL}, /* Noise */ {"WhitePink", 2, 469, 580, S3, S4 + 10, 0, 1, 0, "bitmaps/buttons/sonicrocker3.xpm", "bitmaps/buttons/sonicrocker1.xpm", 0}, /* Mixer - 30 */ {"Mix-OscA/B", 0, 548, 260, S2, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"Mix-RM", 0, 548, 370, S2, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"Mix-Ext", 0, 548, 480, S2, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"Mix-Noise", 0, 548, 590, S2, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, /* Bypass */ {"Bypass", 2, 646, 225, S5, S6, 0, 1, 0, "bitmaps/buttons/sonicrocker1.xpm", "bitmaps/buttons/sonicrocker3.xpm", BRIGHTON_VERTICAL}, /* Env - 35 */ {"Attack", 0, 625, 88, S2, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"Decay", 0, 677, 88, S2, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"Sustain", 0, 729, 88, S2, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"Release", 0, 781, 88, S2, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, /* Env Type */ {"EnvType", 0, 647, 420, S2, S2, 0, 3, 0, "bitmaps/knobs/knob4.xpm", 0, BRIGHTON_STEPPED}, {"Velocity", 2, 648, 495, S5, S6, 0, 1, 0, "bitmaps/buttons/sonicrocker1.xpm", "bitmaps/buttons/sonicrocker3.xpm", BRIGHTON_VERTICAL}, /* Filter - 41 */ {"VCF-Cutoff", 1, 740, 260, 13, 270, 0, 1, 0, "bitmaps/knobs/sliderArpBlack.xpm", 0, 0}, {"VCF-Res", 1, 784, 260, 13, 270, 0, 1, 0, "bitmaps/knobs/sliderArpBlack.xpm", 0, 0}, /* Direct output mixer */ {"Direct-OscA", 0, 845, 88, S2, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"Direct-OscB", 0, 890, 88, S2, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"Direct-Ringmod", 0, 935, 88, S2, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, /* Triggers */ {"TriggerKBD", 2, 625, 612, S3, S4 + 10, 0, 1, 0, "bitmaps/buttons/sonicrocker1.xpm", "bitmaps/buttons/sonicrocker3.xpm", 0}, {"TriggerLFO-X", 2, 655, 612, S3, S4 + 10, 0, 1, 0, "bitmaps/buttons/sonicrocker1.xpm", "bitmaps/buttons/sonicrocker3.xpm", 0}, {"TriggerLFO-Y", 2, 685, 612, S3, S4 + 10, 0, 1, 0, "bitmaps/buttons/sonicrocker1.xpm", "bitmaps/buttons/sonicrocker3.xpm", 0}, /* Pitch control - 49 */ {"Osc1-FM-ADSR", 0, 728, 616, S2, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"Osc1-FM-KBD", 2, 762, 612, S3, S4 + 10, 0, 1, 0, "bitmaps/buttons/sonicrocker1.xpm", "bitmaps/buttons/sonicrocker3.xpm", 0}, {"Osc1-FM-X/Y", 0, 787, 616, S2, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, /* Memories dummies - 52 */ /* Multi LFO-X */ {"LFO-X-Multi", 2, 150, 884, S3, S4 + 4, 0, 1, 0, "bitmaps/buttons/sonicrocker1.xpm", "bitmaps/buttons/sonicrocker3.xpm", 0}, /* Multi LFO-X */ {"LFO-Y-Multi", 2, 180, 884, S3, S4 + 4, 0, 1, 0, "bitmaps/buttons/sonicrocker1.xpm", "bitmaps/buttons/sonicrocker3.xpm", 0}, {"is dummydummy", 0, 100, 880, S7, S7, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, BRIGHTON_WITHDRAWN}, {"FX-1", 0, 807, 880, S7, S7, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"FX-2", 0, 842, 880, S7, S7, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"FX-3", 0, 877, 880, S7, S7, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"FX-4", 0, 912, 880, S7, S7, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"dummy", 0, 0, 0, S2, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, BRIGHTON_WITHDRAWN}, /* Global controls (not in memories - 60 */ {"Global", 0, 60, 880, S7, S7, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, BRIGHTON_NOTCH}, {"dummy", 0, 0, 0, S2, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, BRIGHTON_WITHDRAWN}, {"dummy", 0, 0, 0, S2, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, BRIGHTON_WITHDRAWN}, {"dummy", 0, 0, 0, S2, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, BRIGHTON_WITHDRAWN}, {"dummy", 0, 0, 0, S2, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, BRIGHTON_WITHDRAWN}, {"dummy", 0, 0, 0, S2, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, BRIGHTON_WITHDRAWN}, {"dummy", 0, 0, 0, S2, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, BRIGHTON_WITHDRAWN}, {"dummy", 0, 0, 0, S2, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, BRIGHTON_WITHDRAWN}, /* REST IN HERE - memory, MIDI */ /* memories */ {"", 2, 847, 300, 16, 50, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, 877, 300, 16, 50, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, 907, 300, 16, 50, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, 937, 300, 16, 50, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, 847, 380, 16, 50, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, 877, 380, 16, 50, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, 907, 380, 16, 50, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, 937, 380, 16, 50, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, /* Load Save, Bank */ {"", 2, 847, 460, 16, 50, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 877, 460, 16, 50, 0, 1, 0, "bitmaps/buttons/pressoffo.xpm", "bitmaps/buttons/pressono.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 847, 540, 16, 50, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, /* Mem search buttons */ {"", 2, 907, 540, 16, 50, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 907, 460, 16, 50, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 877, 540, 16, 50, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, /* {"", 2, 907, 460, 16, 50, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 847, 540, 16, 50, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 877, 540, 16, 50, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 907, 540, 16, 50, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, */ /* Midi, perhaps eventually file import/export buttons */ {"", 2, 937, 540, 16, 50, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 937, 460, 16, 50, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, /* display */ {"", 3, 835, 226, 130, 40, 0, 1, 0, 0, "bitmaps/images/alphadisplay3.xpm", 0}, }; /* * These are the Sonic mods, glide, volume and now two wheels */ #define SM_COUNT 4 static brightonLocations sonicmods[SM_COUNT] = { {"Glide", 1, 235, 30, 100, 580, 0, 1, 0, "bitmaps/knobs/sliderArpBlack.xpm", 0, 0}, {"Volume", 1, 690, 30, 100, 580, 0, 1, 0, "bitmaps/knobs/sliderArpBlack.xpm", 0, 0}, {"Bend", 1, 100, 715, 920, 55, 0, 1, 0, 0, 0, BRIGHTON_NOSHADOW|BRIGHTON_CENTER|BRIGHTON_VERTICAL|BRIGHTON_REVERSE}, {"Mod", 1, 100, 850, 920, 55, 0, 1, 0, 0, 0, BRIGHTON_NOSHADOW|BRIGHTON_VERTICAL|BRIGHTON_REVERSE}, }; /* * This is a set of globals for the main window rendering. Again taken from * include/brighton.h */ brightonApp sonic6App = { "sonic6", 0, "bitmaps/textures/leather.xpm", 0, sonic6Init, sonic6Configure, /* 3 callbacks, unused? */ midiCallback, destroySynth, {1, 100, 2, 2, 5, 520, 0, 0}, 900, 520, 0, 0, 3, { { "Sonic6", "bitmaps/blueprints/sonic6.xpm", 0, //"bitmaps/textures/metal6.xpm", BRIGHTON_STRETCH, /* flags */ 0, sonic6Configure, sonic6Callback, 0, 0, 1000, 670, DEVICE_COUNT, locations }, { "Keyboard", 0, "bitmaps/keys/kbg.xpm", 0x020|BRIGHTON_STRETCH, 0, 0, keyCallback, 160, 700, 810, 280, KEY_COUNT_4OCTAVE, keys4octave }, { "Mods", "bitmaps/blueprints/sonicmods.xpm", "bitmaps/textures/metal5.xpm", 0, 0, 0, sonic6ModCallback, 27, 685, 115, 280, SM_COUNT, sonicmods }, } }; static int sonic6ModCallback(brightonWindow *bwin, int c, int o, float value) { guiSynth *synth = findSynth(global.synths, bwin); switch (o) { case 0: /* Glide */ bristolMidiSendMsg(global.controlfd, synth->sid, 126, 0, (int) (value * C_RANGE_MIN_1)); break; case 1: /* Volume */ bristolMidiSendMsg(global.controlfd, synth->sid, 126, 1, (int) (value * C_RANGE_MIN_1)); break; case 2: /* Bend */ bristolMidiSendMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_PITCH, 0, (int) (value * C_RANGE_MIN_1)); break; case 3: /* Mod */ bristolMidiControl(global.controlfd, synth->midichannel, 0, 1, ((int) (value * (C_RANGE_MIN_1 - 1))) >> 7); break; } return(0); } static int midiCallback(brightonWindow *win, int controller, int value, float n) { guiSynth *synth = findSynth(global.synths, win); printf("midi callback: %x, %i\n", controller, value); switch(controller) { case MIDI_PROGRAM: printf("midi program: %x, %i\n", controller, value); synth->location = value; loadMemory(synth, "sonic6", 0, synth->bank + synth->location, synth->mem.active, FIRST_DEV, 0); break; case MIDI_BANK_SELECT: printf("midi banksel: %x, %i\n", controller, value); synth->bank = value; break; } return(0); } static int sonic6MidiSendMsg(void *synth, int fd, int chan, int c, int o, int v) { bristolMidiSendMsg(fd, chan, c, o, v); return(0); } /* * For the sake of ease of use, links have been placed here to be called * by any of the devices created. They would be better in some other file, * perhaps with this as a dispatch. * * Param refers to the device index in the locations table given below. */ int sonic6Callback(brightonWindow * win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); int sendvalue; /* printf("sonic6Callback(%i, %i, %f)\n", panel, index, value); */ if (synth == 0) return(0); if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0)) return(0); if (index >= DEVICE_COUNT) return(0); if (sonic6App.resources[0].devlocn[index].to == 1.0) sendvalue = value * (CONTROLLER_RANGE - 1); else sendvalue = value; synth->mem.param[index] = value; if ((!global.libtest) || (index >= ACTIVE_DEVS)) synth->dispatch[index].routine(synth, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); else printf("dispatch[%p,%i](%i, %i, %i, %i, %i)\n", synth, index, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); return(0); } static int sonic6Midi(guiSynth *synth, int fd, int chan, int c, int o, int value) { int newchan; if ((synth->flags & OPERATIONAL) == 0) return(0); if (c == 1) { if ((newchan = synth->midichannel - 1) < 0) newchan = synth->midichannel = 0; } else { if ((newchan = synth->midichannel + 1) >= 16) newchan = synth->midichannel = 15; } if (global.libtest == 0) { bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_MIDICHANNEL|newchan); } synth->midichannel = newchan; displayText(synth, "MIDI CH", synth->midichannel + 1, DISPLAY_DEV); return(0); } static void sonic6LFOFreq(guiSynth *synth, int fd, int chan, int o, int c, int v) { switch (o) { default: if (synth->mem.param[3] == 2) bristolMidiSendMsg(global.controlfd, synth->sid, 7, 0, (int) (synth->mem.param[0] * synth->mem.param[2] * C_RANGE_MIN_1)); else bristolMidiSendMsg(global.controlfd, synth->sid, 7, 0, (int) (synth->mem.param[2] * C_RANGE_MIN_1)); if (synth->mem.param[6] == 2) bristolMidiSendMsg(global.controlfd, synth->sid, 8, 0, (int) (synth->mem.param[0] * synth->mem.param[4] * C_RANGE_MIN_1)); else bristolMidiSendMsg(global.controlfd, synth->sid, 8, 0, (int) (synth->mem.param[4] * C_RANGE_MIN_1)); break; case 7: if (synth->mem.param[3] == 2) bristolMidiSendMsg(global.controlfd, synth->sid, 7, 0, (int) (synth->mem.param[0] * synth->mem.param[2] * C_RANGE_MIN_1)); else bristolMidiSendMsg(global.controlfd, synth->sid, 7, 0, (int) (synth->mem.param[2] * C_RANGE_MIN_1)); break; case 8: if (synth->mem.param[3] == 2) bristolMidiSendMsg(global.controlfd, synth->sid, 8, 0, (int) (synth->mem.param[0] * synth->mem.param[4] * C_RANGE_MIN_1)); else bristolMidiSendMsg(global.controlfd, synth->sid, 8, 0, (int) (synth->mem.param[4] * C_RANGE_MIN_1)); break; } } static void sonic6Transpose(guiSynth *synth, int fd, int chan, int o, int c, int v) { bristolMidiSendMsg(global.controlfd, synth->sid, o, c, 3 - v); } static void sonic6Waveform(guiSynth *synth, int fd, int chan, int o, int c, int v) { switch (v) { case 2: bristolMidiSendMsg(global.controlfd, synth->sid, o, 4, 0); bristolMidiSendMsg(global.controlfd, synth->sid, o, 5, 1); bristolMidiSendMsg(global.controlfd, synth->sid, o, 6, 0); break; case 1: bristolMidiSendMsg(global.controlfd, synth->sid, o, 4, 1); bristolMidiSendMsg(global.controlfd, synth->sid, o, 5, 0); bristolMidiSendMsg(global.controlfd, synth->sid, o, 6, 0); break; case 0: bristolMidiSendMsg(global.controlfd, synth->sid, o, 4, 0); bristolMidiSendMsg(global.controlfd, synth->sid, o, 5, 0); bristolMidiSendMsg(global.controlfd, synth->sid, o, 6, 1); break; } } static void sonic6Envelope(guiSynth *synth, int fd, int chan, int o, int c, int v) { /* * Shim for the different envelope types * param[39] as AR(0), ASR(1), ADSD(2), ADSR(3). * * AR/AD and ASR are the two types supported by the original device. * ADSD is a MiniMoog type envelope, really just three parameters * The last one is a full ADSR. */ switch (c) { case 1: /* * Decay */ switch ((int) synth->mem.param[39]) { case 0: bristolMidiSendMsg(global.controlfd, synth->sid, 3, 1, v); break; case 1: break; case 2: bristolMidiSendMsg(global.controlfd, synth->sid, 3, 1, v); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 3, v); break; default: bristolMidiSendMsg(global.controlfd, synth->sid, 3, 1, v); break; } break; case 2: /* Sustain */ switch ((int) synth->mem.param[39]) { case 0: case 1: break; case 2: default: bristolMidiSendMsg(global.controlfd, synth->sid, 3, 2, v); break; } break; case 3: /* Release */ switch ((int) synth->mem.param[39]) { case 0: /* Type 0 uses decay, not release */ break; case 1: bristolMidiSendMsg(global.controlfd, synth->sid, 3, 3, v); break; case 2: break; default: bristolMidiSendMsg(global.controlfd, synth->sid, 3, 3, v); break; } break; default: /* * If we change the envelope type we may need to reconfigure a set * of basic parameters to force the desired function */ switch ((int) synth->mem.param[39]) { case 0: /* AR - zero sustain, configure release=decay */ bristolMidiSendMsg(global.controlfd, synth->sid, 3, 2, 0); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 1, (int) (synth->mem.param[36] * C_RANGE_MIN_1)); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 3, (int) (synth->mem.param[36] * C_RANGE_MIN_1)); break; case 1: /* ASR - full sustain, configure decay=release */ bristolMidiSendMsg(global.controlfd, synth->sid, 3, 2, C_RANGE_MIN_1); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 1, (int) (synth->mem.param[38] * C_RANGE_MIN_1)); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 3, (int) (synth->mem.param[38] * C_RANGE_MIN_1)); break; case 2: /* ADSD - configured sustain, configure release=decay */ bristolMidiSendMsg(global.controlfd, synth->sid, 3, 2, (int) (synth->mem.param[37] * C_RANGE_MIN_1)); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 3, (int) (synth->mem.param[36] * C_RANGE_MIN_1)); break; default: /* ADSD - configured sustain, configure release=decay */ bristolMidiSendMsg(global.controlfd, synth->sid, 3, 1, (int) (synth->mem.param[36] * C_RANGE_MIN_1)); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 2, (int) (synth->mem.param[37] * C_RANGE_MIN_1)); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 3, (int) (synth->mem.param[38] * C_RANGE_MIN_1)); break; } break; } } static void sonic6Filter(guiSynth *synth, int fd, int chan, int o, int c, int v) { if (v == 0) bristolMidiSendMsg(global.controlfd, synth->sid, 4, 3, v); else bristolMidiSendMsg(global.controlfd, synth->sid, 4, 3, 8192); } static void sonic6Memory(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; int bank = synth->bank; int location = synth->location; event.value = 1.0; event.type = BRISTOL_FLOAT; if (synth->flags & MEM_LOADING) return; if ((synth->flags & OPERATIONAL) == 0) return; if (synth->dispatch[MEM_START].other2) { synth->dispatch[MEM_START].other2 = 0; return; } switch (c) { default: case 0: /* * We want to make these into memory buttons. To do so we need to * know what the last active button was, and deactivate its * display, then send any message which represents the most * recently configured value. Since this is a memory button we do * not have much issue with the message, but we are concerned with * the display. */ if (synth->dispatch[MEM_START].other1 != -1) { synth->dispatch[MEM_START].other2 = 1; if (synth->dispatch[MEM_START].other1 != o) event.value = 0; else event.value = 1; brightonParamChange(synth->win, synth->panel, synth->dispatch[MEM_START].other1 + MEM_START - 1, &event); } synth->dispatch[MEM_START].other1 = o; if (synth->flags & BANK_SELECT) { if ((synth->bank * 10 + o) >= 100) { synth->location = o; synth->flags &= ~BANK_SELECT; if (loadMemory(synth, "sonic6", 0, synth->bank * 10 + synth->location, synth->mem.active, 0, BRISTOL_STAT) < 0) displayText(synth, "FREE MEM", synth->bank * 10 + synth->location, DISPLAY_DEV); else displayText(synth, "PROGRAM", synth->bank * 10 + synth->location, DISPLAY_DEV); } else { synth->bank = synth->bank * 10 + o; displayText(synth, "BANK", synth->bank * 10 + synth->location, DISPLAY_DEV); } } else { if (synth->bank < 1) synth->bank = 1; synth->location = o; if (loadMemory(synth, "sonic6", 0, synth->bank * 10 + synth->location, synth->mem.active, 0, BRISTOL_STAT) < 0) displayText(synth, "FREE MEM", synth->bank * 10 + synth->location, DISPLAY_DEV); else displayText(synth, "PROGRAM", synth->bank * 10 + synth->location, DISPLAY_DEV); } break; case 1: if (synth->bank < 1) synth->bank = 1; if (synth->location == 0) synth->location = 1; if (loadMemory(synth, "sonic6", 0, synth->bank * 10 + synth->location, synth->mem.active, 0, BRISTOL_FORCE) < 0) displayText(synth, "FREE MEM", synth->bank * 10 + synth->location, DISPLAY_DEV); else displayText(synth, "PROGRAM", synth->bank * 10 + synth->location, DISPLAY_DEV); synth->flags &= ~BANK_SELECT; break; case 2: if (synth->bank < 1) synth->bank = 1; if (synth->location == 0) synth->location = 1; saveMemory(synth, "sonic6", 0, synth->bank * 10 + synth->location, 0); displayText(synth, "PROGRAM", synth->bank * 10 + synth->location, DISPLAY_DEV); synth->flags &= ~BANK_SELECT; break; case 3: if (synth->flags & BANK_SELECT) { synth->flags &= ~BANK_SELECT; if (loadMemory(synth, "sonic6", 0, synth->bank * 10 + synth->location, synth->mem.active, 0, BRISTOL_STAT) < 0) displayText(synth, "FREE MEM", synth->bank * 10 + synth->location, DISPLAY_DEV); else displayText(synth, "PROGRAM", synth->bank * 10 + synth->location, DISPLAY_DEV); } else { synth->bank = 0; displayText(synth, "BANK", synth->bank, DISPLAY_DEV); synth->flags |= BANK_SELECT; } break; case 4: if (--location < 1) { location = 8; if (--bank < 1) bank = 88; } while (loadMemory(synth, "sonic6", 0, bank * 10 + location, synth->mem.active, 0, BRISTOL_STAT) < 0) { if (--location < 1) { location = 8; if (--bank < 1) bank = 88; } if ((bank * 10 + location) == (synth->bank * 10 + synth->location)) break; } displayText(synth, "PROGRAM", bank * 10 + location, DISPLAY_DEV); synth->bank = bank; synth->location = location; loadMemory(synth, "sonic6", 0, bank * 10 + location, synth->mem.active, 0, BRISTOL_FORCE); brightonParamChange(synth->win, 0, MEM_START - 1 + synth->location, &event); break; case 5: if (++location > 8) { location = 1; if (++bank > 88) bank = 1; } while (loadMemory(synth, "sonic6", 0, bank * 10 + location, synth->mem.active, 0, BRISTOL_STAT) < 0) { if (++location > 8) { location = 1; if (++bank > 88) bank = 1; } if ((bank * 10 + location) == (synth->bank * 10 + synth->location)) break; } displayText(synth, "PROGRAM", bank * 10 + location, DISPLAY_DEV); synth->bank = bank; synth->location = location; loadMemory(synth, "sonic6", 0, bank * 10 + location, synth->mem.active, 0, BRISTOL_FORCE); brightonParamChange(synth->win, 0, MEM_START - 1 + synth->location, &event); break; case 6: /* Find the next free mem */ if (++location > 8) { location = 1; if (++bank > 88) bank = 1; } while (loadMemory(synth, "sonic6", 0, bank * 10 + location, synth->mem.active, 0, BRISTOL_STAT) >= 0) { if (++location > 8) { location = 1; if (++bank > 88) bank = 1; } if ((bank * 10 + location) == (synth->bank * 10 + synth->location)) break; } if (loadMemory(synth, "sonic6", 0, bank * 10 + location, synth->mem.active, 0, BRISTOL_STAT) >= 0) displayText(synth, "PROGRAM", bank * 10 + location, DISPLAY_DEV); else displayText(synth, "FREE MEM", bank * 10 + location, DISPLAY_DEV); synth->bank = bank; synth->location = location; brightonParamChange(synth->win, 0, MEM_START - 1 + synth->location, &event); break; } /* printf(" pro1Memory(B: %i L %i: %i)\n", */ /* synth->bank, synth->location, o); */ } /* * Any location initialisation required to run the callbacks. For bristol, this * will connect to the engine, and give it some base parameters. * May need to generate some application specific menus. * Will also then make specific requests to some of the devices to alter their * rendering. */ int sonic6Init(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); dispatcher *dispatch; int i; if (synth == 0) { synth = findSynth(global.synths, 0); if (synth == 0) { printf("cannot init\n"); return(0); } } if ((initmem = synth->location) == 0) initmem = 11; synth->win = win; printf("Initialise the sonic6 link to bristol: %p\n", synth->win); synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float)); synth->mem.count = DEVICE_COUNT; synth->mem.active = ACTIVE_DEVS; synth->dispatch = (dispatcher *) brightonmalloc(DEVICE_COUNT * sizeof(dispatcher)); dispatch = synth->dispatch; /* * We really want to have three connection mechanisms. These should be * 1. Unix named sockets. * 2. UDP sockets. * 3. MIDI pipe. */ if (!global.libtest) if ((synth->sid = initConnection(&global, synth)) < 0) return(-1); for (i = 0; i < DEVICE_COUNT; i++) { synth->dispatch[i].controller = 126; synth->dispatch[i].operator = 101; synth->dispatch[i].routine = sonic6MidiSendMsg; } /* LFO */ synth->dispatch[0].controller = 0; synth->dispatch[0].operator = 1; synth->dispatch[0].routine = (synthRoutine) sonic6LFOFreq; synth->dispatch[2].controller = 7; synth->dispatch[2].operator = 0; synth->dispatch[2].routine = (synthRoutine) sonic6LFOFreq; synth->dispatch[4].controller = 8; synth->dispatch[4].operator = 0; synth->dispatch[4].routine = (synthRoutine) sonic6LFOFreq; synth->dispatch[1].controller = 126; synth->dispatch[1].operator = 15; /* This should be shimmed to ensure the correct value is sent */ synth->dispatch[3].controller = 126; synth->dispatch[3].operator = 16; synth->dispatch[5].controller = 126; synth->dispatch[5].operator = 17; /* This should be shimmed to ensure the correct value is sent */ synth->dispatch[6].controller = 126; synth->dispatch[6].operator = 18; synth->dispatch[7].controller = 126; synth->dispatch[7].operator = 14; /* LFO Multi */ synth->dispatch[52].controller = 126; synth->dispatch[52].operator = 19; synth->dispatch[53].controller = 126; synth->dispatch[53].operator = 20; /* VCO A */ synth->dispatch[8].controller = 0; synth->dispatch[8].operator = 2; synth->dispatch[9].controller = 0; synth->dispatch[9].operator = 0; synth->dispatch[10].controller = 0; synth->dispatch[10].operator = 1; synth->dispatch[10].routine = (synthRoutine) sonic6Transpose; synth->dispatch[11].controller = 0; synth->dispatch[11].operator = 1; synth->dispatch[11].routine = (synthRoutine) sonic6Waveform; /* Two spares here */ synth->dispatch[14].controller = 126; synth->dispatch[14].operator = 21; synth->dispatch[15].controller = 126; synth->dispatch[15].operator = 22; /* Osc-A mode LFO/KBD/HIGH */ synth->dispatch[16].controller = 126; synth->dispatch[16].operator = 32; /* VCO B */ synth->dispatch[17].controller = 1; synth->dispatch[17].operator = 2; synth->dispatch[18].controller = 1; synth->dispatch[18].operator = 0; synth->dispatch[19].controller = 1; synth->dispatch[19].operator = 1; synth->dispatch[19].routine = (synthRoutine) sonic6Transpose; synth->dispatch[20].controller = 1; synth->dispatch[20].operator = 1; synth->dispatch[20].routine = (synthRoutine) sonic6Waveform; /* Two spares here */ synth->dispatch[23].controller = 126; synth->dispatch[23].operator = 23; synth->dispatch[24].controller = 126; synth->dispatch[24].operator = 24; synth->dispatch[25].controller = 126; synth->dispatch[25].operator = 25; /* Generate A/B */ synth->dispatch[26].controller = 126; synth->dispatch[26].operator = 13; /* RM */ synth->dispatch[27].controller = 126; synth->dispatch[27].operator = 26; synth->dispatch[28].controller = 126; synth->dispatch[28].operator = 27; /* Noise */ synth->dispatch[29].controller = 6; synth->dispatch[29].operator = 1; /* Mixer */ synth->dispatch[30].controller = 126; synth->dispatch[30].operator = 28; synth->dispatch[31].controller = 126; synth->dispatch[31].operator = 29; synth->dispatch[32].controller = 126; synth->dispatch[32].operator = 30; synth->dispatch[33].controller = 126; synth->dispatch[33].operator = 31; /* Bypass */ synth->dispatch[34].controller = 126; synth->dispatch[34].operator = 35; /* ADSR */ synth->dispatch[35].controller = 3; synth->dispatch[35].operator = 0; synth->dispatch[36].controller = 3; synth->dispatch[36].operator = 1; synth->dispatch[37].controller = 3; synth->dispatch[37].operator = 2; synth->dispatch[38].controller = 3; synth->dispatch[38].operator = 3; synth->dispatch[39].controller = 126; synth->dispatch[39].operator = 101; synth->dispatch[36].routine = synth->dispatch[37].routine = synth->dispatch[38].routine = synth->dispatch[39].routine = (synthRoutine) sonic6Envelope; synth->dispatch[40].controller = 3; synth->dispatch[40].operator = 5; /* Filter */ synth->dispatch[41].controller = 4; synth->dispatch[41].operator = 0; synth->dispatch[42].controller = 4; synth->dispatch[42].operator = 1; /* Direct Outputs */ synth->dispatch[43].controller = 126; synth->dispatch[43].operator = 10; synth->dispatch[44].controller = 126; synth->dispatch[44].operator = 11; synth->dispatch[45].controller = 126; synth->dispatch[45].operator = 12; /* Triggers */ synth->dispatch[46].controller = 3; synth->dispatch[46].operator = 6; synth->dispatch[47].controller = 126; synth->dispatch[47].operator = 36; synth->dispatch[48].controller = 126; synth->dispatch[48].operator = 37; /* filter */ synth->dispatch[49].controller = 126; synth->dispatch[49].operator = 33; synth->dispatch[50].controller = 4; synth->dispatch[50].operator = 3; synth->dispatch[50].routine = (synthRoutine) sonic6Filter; synth->dispatch[51].controller = 126; synth->dispatch[51].operator = 34; /* Reverb */ synth->dispatch[55].controller = 101; synth->dispatch[55].operator = 0; synth->dispatch[56].controller = 101; synth->dispatch[56].operator = 1; synth->dispatch[57].controller = 101; synth->dispatch[57].operator = 2; synth->dispatch[58].controller = 101; synth->dispatch[58].operator = 3; /* Global Tuning */ synth->dispatch[60].controller = 126; synth->dispatch[60].operator = 2; /* Memory and MIDI */ dispatch[MEM_START + 0].operator = 1; dispatch[MEM_START + 1].operator = 2; dispatch[MEM_START + 2].operator = 3; dispatch[MEM_START + 3].operator = 4; dispatch[MEM_START + 4].operator = 5; dispatch[MEM_START + 5].operator = 6; dispatch[MEM_START + 6].operator = 7; dispatch[MEM_START + 7].operator = 8; dispatch[MEM_START + 8].controller = 1; dispatch[MEM_START + 9].controller = 2; dispatch[MEM_START + 10].controller = 3; dispatch[MEM_START + 11].controller = 4; dispatch[MEM_START + 12].controller = 5; dispatch[MEM_START + 13].controller = 6; dispatch[MEM_START + 0].routine = dispatch[MEM_START + 1].routine = dispatch[MEM_START + 2].routine = dispatch[MEM_START + 3].routine = dispatch[MEM_START + 4].routine = dispatch[MEM_START + 5].routine = dispatch[MEM_START + 6].routine = dispatch[MEM_START + 7].routine = dispatch[MEM_START + 8].routine = dispatch[MEM_START + 9].routine = dispatch[MEM_START + 10].routine = dispatch[MEM_START + 11].routine = dispatch[MEM_START + 12].routine = dispatch[MEM_START + 13].routine = (synthRoutine) sonic6Memory; dispatch[DEVICE_COUNT - 3].routine = dispatch[DEVICE_COUNT - 2].routine = (synthRoutine) sonic6Midi; dispatch[DEVICE_COUNT - 3].controller = 1; dispatch[DEVICE_COUNT - 2].controller = 2; dispatch[MEM_START].other1 = -1; /* VCO inits */ bristolMidiSendMsg(global.controlfd, synth->sid, 0, 0, 8192); bristolMidiSendMsg(global.controlfd, synth->sid, 0, 1, 2); bristolMidiSendMsg(global.controlfd, synth->sid, 0, 2, 8192); bristolMidiSendMsg(global.controlfd, synth->sid, 0, 3, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 0, 5, 16383); /* VCO inits */ bristolMidiSendMsg(global.controlfd, synth->sid, 1, 0, 8192); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 1, 2); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 2, 8192); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 3, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 4, 16383); /* LFO Sync to key_on */ bristolMidiSendMsg(global.controlfd, synth->sid, 7, 1, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 8, 1, 16383); /* ADSR gain */ bristolMidiSendMsg(global.controlfd, synth->sid, 3, 3, 16383); /* Noise - gain and pink filter */ bristolMidiSendMsg(global.controlfd, synth->sid, 6, 0, 10024); bristolMidiSendMsg(global.controlfd, synth->sid, 6, 2, 4096); /* Ring Mod */ bristolMidiSendMsg(global.controlfd, synth->sid, 2, 0, 8192); bristolMidiSendMsg(global.controlfd, synth->sid, 2, 1, 8192); bristolMidiSendMsg(global.controlfd, synth->sid, 2, 2, 8192); /* filter mod and key tracking stuff */ bristolMidiSendMsg(global.controlfd, synth->sid, 4, 2, 8192); bristolMidiSendMsg(global.controlfd, synth->sid, 4, 3, 4096); bristolMidiSendMsg(global.controlfd, synth->sid, 4, 4, 4); bristolMidiSendMsg(global.controlfd, synth->sid, 4, 5, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 4, 6, 0); /* Tune */ bristolMidiSendMsg(global.controlfd, synth->sid, 126, 2, 8192); return(0); } /* * This will be called to make any routine specific parameters available. */ int sonic6Configure(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); brightonEvent event; if (synth == 0) { printf("problems going operational\n"); return(-1); } if (synth->flags & OPERATIONAL) return(0); printf("going operational\n"); synth->flags |= OPERATIONAL; synth->keypanel = 1; synth->keypanel2 = -1; synth->transpose = 36; if (synth->location == 0) { synth->bank = 1; synth->location = 1; } loadMemory(synth, "sonic6", 0, initmem, synth->mem.active, FIRST_DEV, BRISTOL_FORCE); event.type = BRIGHTON_FLOAT; /* Tune */ event.value = 0.5; brightonParamChange(synth->win, 0, 60, &event); /* Volume */ event.value = 0.5; brightonParamChange(synth->win, 2, 1, &event); /* Glide */ event.value = 0.1; brightonParamChange(synth->win, 2, 0, &event); /* Modwheel */ event.value = 0.1; brightonParamChange(synth->win, 2, 3, &event); /* * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only * occurs on first paint, so we suppress the first paint, and then request * an expose here. */ event.type = BRIGHTON_EXPOSE; event.intvalue = 1; brightonParamChange(synth->win, KEY_PANEL, -1, &event); configureGlobals(synth); brightonPut(win, "bitmaps/blueprints/sonic6shade.xpm", 0, 0, win->width, win->height); return(0); } bristol-0.60.11/brighton/brightonMixerMemory.h0000644000175000017500000000472211746476475016307 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #ifndef BRIGHTONMIXERMEMORY_H #define BRIGHTONMIXERMEMORY_H #include "brightonMini.h" typedef float cOpaque[18]; typedef struct cClear { float gain; float preSend; float dynSens; float dynAtt; float dynDec; float dynSus; float dynRel; float treble; float tFreq; float mid; float bass; float bFreq; float postSend; float fxVol; float fxSpd; float fxDpt; float pan; float vol; } cClear; typedef union CParams { cOpaque opaque; cClear clear; } cparams; typedef struct ChanMem { char scratch[20]; int inputSelect; int preSend[4]; int dynamics; int filter; int postSend[4]; int fxAlgo; cparams p; int mute; int solo; int boost; int outputSelect[16]; int stereoBus; float data[30]; } chanMem; typedef float bOpaque[FXP_COUNT]; typedef struct BClear { float igain; float speed; float depth; float m; float pan; float gain; int algorithm; float outputSelect[16]; float pad[FXP_COUNT - 7 - 16]; } bClear; typedef union BParams { bClear clear; bOpaque opaque; } bparams; typedef struct BusMem { char name[32]; // For eventual FX attachments. bparams b; } busMem; typedef float vbOpaque[3]; typedef struct VBClear { float vol; float left; float right; } vbClear; typedef union VBus { vbClear clear; vbOpaque opaque; } vBus; typedef struct MixerMemV1 { char name[20]; int version; int chancount; busMem bus[16]; vBus vbus[8]; chanMem chan[MAX_CHAN_COUNT]; } mixerMem; extern int saveMixerMemory(guiSynth *synth, char *name); extern int loadMixerMemory(guiSynth *synth, char *name, int param); extern void *initMixerMemory(int count); extern int setMixerMemory(mixerMem *, int, int, float *, char *); extern char* getMixerMemory(mixerMem *m, int op, int param); #endif bristol-0.60.11/brighton/brightonStratus.c0000644000175000017500000015361311746476475015476 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* * Filter type selector DONE * * Synth Pan DONE * * Env touch sense - env to filter should not have touch? Maybe it should to * add harmonics with touch hence an option. The option goes to the envelope * and to the emulator since they have to both recognise when to use touch? * DONE TEST * * Fixed Legato waveforms and waveform selection (alternate osc1/osc2). DONE * * Fixed Osc2 trill - Osc-1 trill is a function of joystick plus mod routing, * Osc-2 trill is a funtion of this button? DONE * * Fixed glides DONE * * Fixed pedal DONE * * Corrected tuning DONE * * Added options information: DONE * * P1 Master volume * * P2 Organ pan * P3 Organ waveform distorts * P4 Organ spacialisation * P5 Organ mod level * J1 Organ key grooming * P6 Organ tuning * * P7 Synth pan * P8 Synth tuning * P9 Synth osc1 harmonics * P10 Synth osc2 harmonics * J2 Synth velocity sensitivity * J3 Synth filter type * P11 Synth tracking * * P12 String pan * P13 String harmonics * P14 String spacialisation * P15 String mod level * P16 String waveform - dropped? * * Continuous controllers and joystick DONE * * Consider the VCO LFO options. Could perhaps be improved however they are * flexible and without more data on the original this will remain. DONE * * Fix LFO mono/multi for nosync/sync of lfo to key DONE TEST * * Fix envelope touch sense, emulation touch sense DONE * * Doublecheck options DONE * * Fix sync. This could be postponed but can try and look into whether the * noise comes from the syncing waveform or the synced waveform. * * Added filter keyboard tracking. Reworked tuning needs testing. This could * also be postponed however it is not far off. */ #include #include "brighton.h" #include "brightonMini.h" static int initmem = 0; int stratusInit(); int stratusConfigure(); int stratusCallback(brightonWindow *, int, int, float); /*static int keyCallback(void *, int, int, float); */ int stratusModCallback(brightonWindow *, int, int, float); int stratusMidiCallback(brightonWindow *, int, int, float); static void panelSwitch(guiSynth *, int, int, int, int, int); static void stratusLoadMemory(guiSynth *, int, int, int, int, int); static int dc; extern guimain global; static guimain manual; #include "brightonKeys.h" #include "brightoninternals.h" #define DEVICE_COUNT 87 #define STRATUS_DEVS 47 #define ACTIVE_DEVS 70 #define MEM_START (ACTIVE_DEVS) #define RADIOSET_1 MEM_START #define RADIOSET_2 (MEM_START + 1) #define RADIOSET_3 (MEM_START + 2) #define DISPLAY_DEV (DEVICE_COUNT - 1) #define KEY_PANEL 1 #define OPTS_PANEL 3 #define OPTS_OFFSET 47 #define MODS_OFFSET 66 /* * This structure is for device definition. The structure is defined in * include/brighton.h, further definitions in brighton/brightonDevtable.h and * include/brightoninternals.h * * typedef int (*brightonCallback)(int, float); * typedef struct BrightonLocations { * int device; 0=rotary, 1=scale, etc. * float relx, rely; relative position with regards to 1000 by 1000 window * float relw, relh; relative height. * int from, to; * brightonCallback callback; specific to this dev * char *image; bitmap. If zero take a device default. * int flags; * } brightonLocations; * * This example is for a stratusBristol type synth interface. */ #define S1 35 #define S2 110 #define S2b 15 #define S2c 80 #define S3 70 #define S4 600 #define BO 10 #define B2 6 #define R1 190 #define R2 560 #define R2a 260 #define R2b 380 #define R2c 500 #define R2d 620 #define D1 51 #define D2 43 #define D3 30 #define C1 26 #define C2 (C1 + D1) #define C3 (C2 + D1) #define C4 (C3 + D1) #define C5 (C4 + D1) #define C6 (C5 + D1) #define C7 (C6 + D1) #define C8 (C7 + D1) #define C9 (C8 + D1) #define C10 (C9 + D1) #define C11 (C10 + D1) #define C12 (C11 + D1) #define C13 (C12 + D1 + 23) #define C14 (C13 + D1) #define C15 (C14 + D1) #define C16 (C15 + D1) #define C17 (C16 + D1 - 23) #define C18 (C17 + D1) #define C19 (C18 + D1) #define C20 (C19 + D1) static brightonLocations stratusLocations[DEVICE_COUNT] = { /* Organ */ {"Organ-2'", 1, C1-10, 110, 90, 40, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, BRIGHTON_VERTICAL|BRIGHTON_NOSHADOW|BRIGHTON_REVERSE}, {"Organ-4'", 1, C1-10, 180, 90, 40, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, BRIGHTON_VERTICAL|BRIGHTON_NOSHADOW|BRIGHTON_REVERSE}, {"Organ-8'", 1, C1-10, 250, 90, 40, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, BRIGHTON_VERTICAL|BRIGHTON_NOSHADOW|BRIGHTON_REVERSE}, {"Organ-16'", 1, C1-10, 320, 90, 40, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, BRIGHTON_VERTICAL|BRIGHTON_NOSHADOW|BRIGHTON_REVERSE}, /* Filter - 4 */ {"VCF-Env", 0, C3, R1, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_NOTCH}, {"VCF-Cutoff", 0, C4, R1, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"VCF-Res", 0, C5, R1, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"VCF-Pedal", 0, C6, R1, S1, S2, 0, 1.01, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_STEPPED}, /* - 8 */ {"Glide-Amount", 0, C7, R1, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"Glide-Speed", 0, C8, R1, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"Glide-Multi", 0, C9, R1, S1, S2, 0, 1.01, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_STEPPED}, {"Glide-Dir", 0, C10, R1, S1, S2, 0, 3, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_STEPPED}, /* - 12 */ {"Osc1-Tuning", 0, C11, R1, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_NOTCH}, {"Osc1-Sync", 2, C11 + (D2*1) + 3, R1, S2b+4, S2-10, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"Osc1-Octave", 2, C11 + (D2*2), R1, S2b+4, S2-10, 0, 12, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* - 15 */ {"Osc1-Trill", 2, C11 + (D2*1) + 3, R2, S2b+4, S2-10, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"Osc2-Octave", 2, C11 + (D2*2), R2, S2b+4, S2-10, 0, 12, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"Osc2-Tuning", 0, C11 + (D2*0), R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_NOTCH}, /* - 18 */ {"LFO-Routing", 0, C13+10, R1, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_STEPPED|BRIGHTON_NOTCH}, {"LFO-Multi", 0, C14 + D1/2 + 3, R1, S1, S2, 0, 1.01, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_STEPPED}, {"LFO-Shape", 0, C16-5, R1, S1, S2, 0, 3, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_STEPPED}, /* - 21 */ {"Mix-Synth", 0, C1-5, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"Mix-Organ", 0, C2-5, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"Mix-X", 0, C3-5, 0, 0, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, /* - 24 String section */ {"X1", 0, C4, 0, 0, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"X2", 0, C5, 0, 0, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"X3", 0, C6, 0, 0, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"X4", 0, C7, 0, 0, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, /* - 28 */ {"Osc-Waveform", 0, C7+10, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_STEPPED}, {"Osc-WaveAlt", 0, C8 + D1/2 + 3, R2, S1, S2, 0, 1.01, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_STEPPED}, {"Osc-WaveLegato", 0, C10-5, R2, S1, S2, 0, 1.01, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_STEPPED}, /* - 31 */ {"LFO-Rate", 0, C13, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"LFO-Attack", 0, C14, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"LFO-Delay", 0, C15, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"LFO-Depth", 0, C16, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, /* Dummies 12 - 39 */ {"", 0, 0, 0, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, /* These are shadows for the opts parameters - 47 */ {"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, /* 57 */ {"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 2, 0, R2, S1, S2, 0, 1.01, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 2, 0, R2, S1, S2, 0, 4, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, /* These are shadows for the envelope parameters from the mod panel - 66 */ {"Attack", 0, C3, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"Decay", 0, C4, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"Sustain", 0, C5, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"Release", 0, C6, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, /* {"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, */ /* Memory - 40 */ {"", 2, C17+(D3*1), R2a, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C17+(D3*2), R2a, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C17+(D3*3), R2a, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C17+(D3*4), R2a, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C17+(D3*1), R2b, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C17+(D3*2), R2b, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C17+(D3*3), R2b, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C17+(D3*4), R2b, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON}, /* Load and Save */ {"", 2, C17+(D3*1), R2c, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, C17+(D3*1), R2d, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoffo.xpm", "bitmaps/buttons/pressono.xpm", BRIGHTON_CHECKBUTTON}, /* Bank Sel */ {"", 2, C17+(D3*2), R2c, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, /* Mem search buttons Down then Up */ {"", 2, C17+(D3*3), R2d, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, C17+(D3*3), R2c, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, /* Search Free */ {"", 2, C17+(D3*2), R2d, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, /* Midi, perhaps eventually file import/export buttons */ {"", 2, C17+(D3*4), R2d, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, C17+(D3*4), R2c, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 3, C17 + 30, R2a - 120, 106, 60, 0, 1, 0, 0, "bitmaps/images/alphadisplay3.xpm", 0} }; /* * Need more tuning, there is a global for both layers, then one each for the * three components (not synth) */ static brightonLocations stratusOpts[19] = { /* First one is index 47 */ {"", 0, C1, 100, 100, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm",// Master vol "bitmaps/knobs/alpharotary.xpm", BRIGHTON_NOTCH}, {"", 0, C1, 380, 100, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm", // organ pan "bitmaps/knobs/alpharotary.xpm", BRIGHTON_NOTCH}, {"", 0, C2 -4, 380, 100, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm", // o wave "bitmaps/knobs/alpharotary.xpm", BRIGHTON_NOTCH}, {"", 0, C3 + 10, 380, 100, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm", // o space "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, C4 - 10, 490, 100, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm", // o mod "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, 312, 30, 100, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm", // SynHarm "bitmaps/knobs/alpharotary.xpm", 0}, /* 53 */ {"", 2, C1 - 15, 500, 20, 110, 0, 1, 0, // clicky "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_NOSHADOW}, {"", 0, C1 - 18, 650, 100, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm", // O tune "bitmaps/knobs/alpharotary.xpm", BRIGHTON_NOTCH}, {"", 0, C8 - 8, 380, 100, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm", // syn pan "bitmaps/knobs/alpharotary.xpm", BRIGHTON_NOTCH}, {"", 0, C8 - 8, 670, 100, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm", // syn tune "bitmaps/knobs/alpharotary.xpm", BRIGHTON_NOTCH}, {"", 0, 312, 620, 100, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm", // not used "bitmaps/knobs/alpharotary.xpm", 0}, /* 58 */ {"", 2, C9 - 3, 380, 20, 110, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_NOSHADOW}, // Env touch {"", 2, C10, 380, 20, 110, 0, 4, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_NOSHADOW}, // filter type {"", 0, C11 - 22, 480, 100, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, C15, R1, 100, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, C16, R1, 100, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, C17, R1, 100, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, C18, R1, 100, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, C19, R1, S1, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, }; #define STRATUS_MODCOUNT 7 static brightonLocations stratusMods[STRATUS_MODCOUNT] = { {"", 1, 440, 180, 80, 700, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 1, 580, 180, 80, 700, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 1, 720, 180, 80, 700, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 1, 860, 180, 80, 700, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, /* View Opts button */ {"", 2, 420, 800, 150, 170, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* Joystick - we need to keep the dummy since it dispatches X/Y events */ {"", 5, 200, 160, 600, 500, 0, 1, 0, "bitmaps/images/sphere.xpm", 0, BRIGHTON_WIDE}, {"", 0, 0, 0, 10, 10, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, }; /* * This is a set of globals for the main window rendering. Again taken from * include/brighton.h */ brightonApp stratusApp = { "stratus", 0, /* no blueprint on wood background. */ "bitmaps/textures/metal6.xpm", BRIGHTON_STRETCH, /*flags */ stratusInit, stratusConfigure, /* 3 callbacks, unused? */ stratusMidiCallback, destroySynth, {5, 100, 1, 2, 5, 520, 0, 0}, 840, 385, 0, 0, 7, /* Panel count */ { { "Stratus", "bitmaps/blueprints/stratus.xpm", "bitmaps/textures/metal6.xpm", BRIGHTON_STRETCH|BRIGHTON_REVERSE, /* flags */ 0, 0, stratusCallback, 22, 100, 956, 550, DEVICE_COUNT, stratusLocations }, { "Keyboard", 0, "bitmaps/newkeys/kbg.xpm", /* flags */ 0x020|BRIGHTON_STRETCH, 0, 0, keyCallback, 140, 690, 845, 290, KEY_COUNT, keys }, { "Mods", "bitmaps/blueprints/stratusmods.xpm", "bitmaps/blueprints/stratusmods.xpm", BRIGHTON_STRETCH, 0, 0, stratusModCallback, 30, 710, 100, 250, STRATUS_MODCOUNT, stratusMods }, { "Options", "bitmaps/blueprints/stratusopts.xpm", "bitmaps/images/pcb.xpm", BRIGHTON_WITHDRAWN, 0, 0, stratusModCallback, 32, 110, 940, 530, 19, stratusOpts }, { "Logo", "bitmaps/blueprints/stratuslogo.xpm", 0, BRIGHTON_STRETCH, /*flags */ 0, 0, 0, 22, 0, 956, 100, 0, 0 }, { "Edge", 0, "bitmaps/textures/wood.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 0, 0, 22, 1000, 0, 0 }, { "Edge", 0, "bitmaps/textures/wood.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /*flags */ 0, 0, 0, 978, 0, 22, 1000, 0, 0 }, } }; int stratusMidiCallback(brightonWindow *win, int controller, int value, float n) { guiSynth *synth = findSynth(global.synths, win); printf("midi callback: %x, %i\n", controller, value); switch(controller) { case MIDI_PROGRAM: printf("midi program: %x, %i\n", controller, value); synth->location = value; loadMemory(synth, synth->resources->name, 0, synth->bank + synth->location, synth->mem.active, 0, 0); // stratusLoadMemory(synth, global.controlfd, synth->midichannel, // 0, 0, 0); break; case MIDI_BANK_SELECT: printf("midi banksel: %x, %i\n", controller, value); synth->bank = value; break; } return(0); } static void stratusLoadMemory(guiSynth *synth, int fd, int chan, int c, int o, int v) { int i; brightonEvent event; /* * This is now a shim to map the opts and mods, we have to send the events * twice since these controls are in the basic set and the shadow set since * the different emulations have the envelope parameters in differents * panels. */ event.type = BRISTOL_FLOAT; event.value = synth->mem.param[MODS_OFFSET]; brightonParamChange(synth->win, 0, MODS_OFFSET + 0, &event); brightonParamChange(synth->win, 2, 0, &event); event.value = synth->mem.param[MODS_OFFSET + 1]; brightonParamChange(synth->win, 0, MODS_OFFSET + 1, &event); brightonParamChange(synth->win, 2, 1, &event); event.value = synth->mem.param[MODS_OFFSET + 2]; brightonParamChange(synth->win, 0, MODS_OFFSET + 2, &event); brightonParamChange(synth->win, 2, 2, &event); event.value = synth->mem.param[MODS_OFFSET + 3]; brightonParamChange(synth->win, 0, MODS_OFFSET + 3, &event); brightonParamChange(synth->win, 2, 3, &event); for (i = 0; i < 19; i++) { event.type = BRISTOL_FLOAT; event.value = synth->mem.param[OPTS_OFFSET + i]; brightonParamChange(synth->win, 3, i, &event); } } int stratusModCallback(brightonWindow *win, int panel, int dev, float value) { guiSynth *synth = findSynth(global.synths, win); int sendvalue, index; if (synth == NULL) return(0); /* printf("stratusModCallback(%i, %i, %f) %x\n", panel, dev, value, (size_t) synth); */ /* * If this is controller 0-3 it is the Envelope and we need to bury the * values in our memory and dispatch the request. * Then we have the panel switch and two more parameters which are combined * callbacks for the Joystick X and Y. */ if (panel == 2) { switch (dev) { case 0: case 1: case 2: case 3: /* Envelope parameters, we need to send these */ synth->mem.param[MODS_OFFSET + dev] = value; if (!global.libtest) bristolMidiSendMsg(global.controlfd, synth->sid, 2, dev, (int) (value * C_RANGE_MIN_1)); break; case 4: /* Panelswitch */ panelSwitch(synth, 0, 0, 0, 0, value); break; case 5: /* * Joystick Y motion, below 0.5 = VCA, above = VCF. We just * send controller-1 and let the engine decipher it. */ if (!global.libtest) bristolMidiSendControlMsg(global.controlfd, synth->midichannel, 1, ((int) (value * C_RANGE_MIN_1)) >> 7); break; case 6: /* Joystick X motion - pitchbend */ if (!global.libtest) bristolMidiSendMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_PITCH, 0, (int) (value * C_RANGE_MIN_1)); break; } return(0); } if (stratusApp.resources[panel].devlocn[dev].to == 1.0) sendvalue = value * C_RANGE_MIN_1; else sendvalue = value; index = OPTS_OFFSET + dev; if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0)) return(0); synth->mem.param[index] = value; if ((!global.libtest) || (index >= ACTIVE_DEVS)) { if (synth->dispatch[index].other1 < 0) { synth->dispatch[index].routine(synth, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); synth->dispatch[index].routine(synth, global.controlfd, synth->sid2, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); } else synth->dispatch[index].routine(synth, global.controlfd, synth->dispatch[index].other1, /* The SID is buried here */ synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); } else printf("dispatch2[%p,%i](%i, %i, %i, %i, %i)\n", synth, index, global.controlfd, synth->dispatch[index].other1, /* The SID is buried here */ synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); return(0); } static void stratusMono(guiSynth *synth, int fd, int chan, int c, int o, int v) { bristolMidiSendMsg(global.controlfd, synth->sid, c, o, 1 - v); } static void stratusMultiLFO(guiSynth *synth, int fd, int chan, int c, int o, int v) { /* * We don't need a shim for the MULTI option but I want one to add * changes for LFO sync */ bristolMidiSendMsg(global.controlfd, synth->sid, 126, 16, v); bristolMidiSendMsg(global.controlfd, synth->sid, 5, 1, v); } /* Mono Alternate osc A/B */ static void stratusAlternate(guiSynth *synth, int fd, int chan, int c, int o, int v) { bristolMidiSendMsg(global.controlfd, synth->sid, c, o, 1 - v); } static void trilogyWaveform(guiSynth *synth, int fd, int chan, int c, int o, int v) { /* printf("trilogy wave %i/%i %i\n", c, o, v); * 16' to 8' */ if (o == 0) { bristolMidiSendMsg(global.controlfd, synth->sid2, 2, 0, C_RANGE_MIN_1 - v); bristolMidiSendMsg(global.controlfd, synth->sid2, 2, 1, v); } else bristolMidiSendMsg(global.controlfd, synth->sid2, 2, 12, v); } /* */ static void stratusWaveform(guiSynth *synth, int fd, int chan, int c, int o, int v) { /* * Mix Ramp to Square on both oscillators if (synth->mem.param[13] == 0) */ { bristolMidiSendMsg(global.controlfd, synth->sid, 0, 5, C_RANGE_MIN_1-v); bristolMidiSendMsg(global.controlfd, synth->sid, 0, 6, v); } bristolMidiSendMsg(global.controlfd, synth->sid, 1, 5, C_RANGE_MIN_1 - v); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 6, v); } static int stratusMidiSendMsg(void *synth, int fd, int chan, int c, int o, int v) { bristolMidiSendMsg(fd, chan, c, o, v); return(0); } static void stratusMemory(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; int bank = synth->bank; int location = synth->location; event.value = 1.0; event.type = BRISTOL_FLOAT; if (synth->flags & MEM_LOADING) return; if ((synth->flags & OPERATIONAL) == 0) return; if (synth->dispatch[MEM_START].other2) { synth->dispatch[MEM_START].other2 = 0; return; } switch (c) { default: case 0: /* * We want to make these into memory buttons. To do so we need to * know what the last active button was, and deactivate its * display, then send any message which represents the most * recently configured value. Since this is a memory button we do * not have much issue with the message, but we are concerned with * the display. */ if (synth->dispatch[MEM_START].other1 != -1) { synth->dispatch[MEM_START].other2 = 1; if (synth->dispatch[MEM_START].other1 != o) event.value = 0; else event.value = 1; brightonParamChange(synth->win, synth->panel, synth->dispatch[MEM_START].other1 + MEM_START - 1, &event); } synth->dispatch[MEM_START].other1 = o; if (synth->flags & BANK_SELECT) { if ((synth->bank * 10 + o) >= 100) { synth->location = o; synth->flags &= ~BANK_SELECT; if (loadMemory(synth, synth->resources->name, 0, synth->bank * 10 + synth->location, synth->mem.active, 0, BRISTOL_STAT) < 0) displayText(synth, "FREE", synth->bank * 10 + synth->location, DISPLAY_DEV); else displayText(synth, "PROG", synth->bank * 10 + synth->location, DISPLAY_DEV); } else { synth->bank = synth->bank * 10 + o; displayText(synth, "BANK", synth->bank * 10 + synth->location, DISPLAY_DEV); } } else { if (synth->bank < 1) synth->bank = 1; synth->location = o; if (loadMemory(synth, synth->resources->name, 0, synth->bank * 10 + synth->location, synth->mem.active, 0, BRISTOL_STAT) < 0) displayText(synth, "FREE", synth->bank * 10 + synth->location, DISPLAY_DEV); else displayText(synth, "PROG", synth->bank * 10 + synth->location, DISPLAY_DEV); } break; case 1: if (synth->bank < 1) synth->bank = 1; if (synth->location == 0) synth->location = 1; if (loadMemory(synth, synth->resources->name, 0, synth->bank * 10 + synth->location, synth->mem.active, 0, BRISTOL_FORCE) < 0) displayText(synth, "FREE", synth->bank * 10 + synth->location, DISPLAY_DEV); else displayText(synth, "PROG", synth->bank * 10 + synth->location, DISPLAY_DEV); if (brightonDoubleClick(dc)) stratusLoadMemory(synth, global.controlfd, synth->midichannel, 0, 0, 0); synth->flags &= ~BANK_SELECT; break; case 2: if (synth->bank < 1) synth->bank = 1; if (synth->location == 0) synth->location = 1; if (brightonDoubleClick(dc)) { saveMemory(synth, synth->resources->name, 0, synth->bank * 10 + synth->location, 0); displayText(synth, "PROG", synth->bank * 10 + synth->location, DISPLAY_DEV); } synth->flags &= ~BANK_SELECT; break; case 3: if (synth->flags & BANK_SELECT) { synth->flags &= ~BANK_SELECT; if (loadMemory(synth, synth->resources->name, 0, synth->bank * 10 + synth->location, synth->mem.active, 0, BRISTOL_STAT) < 0) displayText(synth, "FREE", synth->bank * 10 + synth->location, DISPLAY_DEV); else displayText(synth, "PROG", synth->bank * 10 + synth->location, DISPLAY_DEV); } else { synth->bank = 0; displayText(synth, "BANK", synth->bank, DISPLAY_DEV); synth->flags |= BANK_SELECT; } break; case 4: if (--location < 1) { location = 8; if (--bank < 1) bank = 88; } while (loadMemory(synth, synth->resources->name, 0, bank * 10 + location, synth->mem.active, 0, BRISTOL_STAT) < 0) { if (--location < 1) { location = 8; if (--bank < 1) bank = 88; } if ((bank * 10 + location) == (synth->bank * 10 + synth->location)) break; } displayText(synth, "PROG", bank * 10 + location, DISPLAY_DEV); synth->bank = bank; synth->location = location; loadMemory(synth, synth->resources->name, 0, bank * 10 + location, synth->mem.active, 0, BRISTOL_FORCE); // stratusLoadMemory(synth, global.controlfd, synth->midichannel, // 0, 0, 0); brightonParamChange(synth->win, 0, MEM_START - 1 + synth->location, &event); break; case 5: if (++location > 8) { location = 1; if (++bank > 88) bank = 1; } while (loadMemory(synth, synth->resources->name, 0, bank * 10 + location, synth->mem.active, 0, BRISTOL_STAT) < 0) { if (++location > 8) { location = 1; if (++bank > 88) bank = 1; } if ((bank * 10 + location) == (synth->bank * 10 + synth->location)) break; } displayText(synth, "PROG", bank * 10 + location, DISPLAY_DEV); synth->bank = bank; synth->location = location; loadMemory(synth, synth->resources->name, 0, bank * 10 + location, synth->mem.active, 0, BRISTOL_FORCE); // stratusLoadMemory(synth, global.controlfd, synth->midichannel, // 0, 0, 0); brightonParamChange(synth->win, 0, MEM_START - 1 + synth->location, &event); break; case 6: /* Find the next free mem */ if (++location > 8) { location = 1; if (++bank > 88) bank = 1; } while (loadMemory(synth, synth->resources->name, 0, bank * 10 + location, synth->mem.active, 0, BRISTOL_STAT) >= 0) { if (++location > 8) { location = 1; if (++bank > 88) bank = 1; } if ((bank * 10 + location) == (synth->bank * 10 + synth->location)) break; } if (loadMemory(synth, synth->resources->name, 0, bank * 10 + location, synth->mem.active, 0, BRISTOL_STAT) >= 0) displayText(synth, "PROG", bank * 10 + location, DISPLAY_DEV); else displayText(synth, "FREE", bank * 10 + location, DISPLAY_DEV); synth->bank = bank; synth->location = location; brightonParamChange(synth->win, 0, MEM_START - 1 + synth->location, &event); break; } /* printf(" stratusMemory(B: %i L %i: %i)\n", */ /* synth->bank, synth->location, o); */ } static void stratusFilter(guiSynth *synth, int fd, int chan, int c, int o, int v) { /* * We need a shim since changing the filter type means we have to push * the parameters again. */ bristolMidiSendMsg(global.controlfd, synth->sid, 3, 4, v); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 0, (int) (synth->mem.param[5] * C_RANGE_MIN_1)); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 1, (int) (synth->mem.param[6] * C_RANGE_MIN_1)); } static void stratusEnvelope(guiSynth *synth, int fd, int chan, int c, int o, int v) { /* * Send touch to envelope and reverse to emulator to decide who controls * response. */ bristolMidiSendMsg(global.controlfd, synth->sid, 2, 5, v); bristolMidiSendMsg(global.controlfd, synth->sid, 126, 27, v); } static void trilogyStringHarmonics(guiSynth *synth, int fd, int chan, int c, int o, int v) { bristolMidiSendMsg(global.controlfd, synth->sid2, 2, 0, C_RANGE_MIN_1 - v); bristolMidiSendMsg(global.controlfd, synth->sid2, 2, 2, v>>1); bristolMidiSendMsg(global.controlfd, synth->sid2, 2, 3, v); } static void stratusMod(guiSynth *synth, int fd, int chan, int c, int o, int v) { bristolMidiSendMsg(global.controlfd, synth->sid2, c, 5, v); bristolMidiSendMsg(global.controlfd, synth->sid2, c, 6, v); } static void stratusOscHarmonics(guiSynth *synth, int fd, int chan, int c, int o, int v) { bristolMidiSendMsg(global.controlfd, synth->sid, c, 0, C_RANGE_MIN_1 - v); bristolMidiSendMsg(global.controlfd, synth->sid, c, 2, v>>1); bristolMidiSendMsg(global.controlfd, synth->sid, c, 3, v); } static void stratusOrganEnv(guiSynth *synth, int fd, int chan, int c, int o, int v) { /* Clicky or not */ if (v == 0) { bristolMidiSendMsg(global.controlfd, synth->sid2, 1, 0, 40); bristolMidiSendMsg(global.controlfd, synth->sid2, 1, 1, 4096); bristolMidiSendMsg(global.controlfd, synth->sid2, 1, 2, 16383); bristolMidiSendMsg(global.controlfd, synth->sid2, 1, 3, 10); } else { bristolMidiSendMsg(global.controlfd, synth->sid2, 1, 0, 20); bristolMidiSendMsg(global.controlfd, synth->sid2, 1, 1, 2000); bristolMidiSendMsg(global.controlfd, synth->sid2, 1, 2, 2000); bristolMidiSendMsg(global.controlfd, synth->sid2, 1, 3, 10); } } static int stratusMidi(guiSynth *synth, int fd, int chan, int c, int o, int v) { int newchan; if ((synth->flags & OPERATIONAL) == 0) return(0); if (c == 1) { if ((newchan = synth->midichannel - 1) < 0) { synth->midichannel = 0; displayText(synth, "CHAN", synth->midichannel + 1, DISPLAY_DEV); return(0); } } else { if ((newchan = synth->midichannel + 1) >= 16) { synth->midichannel = 15; displayText(synth, "CHAN", synth->midichannel + 1, DISPLAY_DEV); return(0); } } if (global.libtest == 0) { bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_MIDICHANNEL|newchan); } synth->midichannel = newchan; /* printf("P: going to display: %x, %x\n", synth, synth->win); */ displayText(synth, "CHAN", synth->midichannel + 1, DISPLAY_DEV); return(0); } /* * For the sake of ease of use, links have been placed here to be called * by any of the devices created. They would be better in some other file, * perhaps with this as a dispatch. * * Param refers to the device index in the locations table given below. */ int stratusCallback(brightonWindow *win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); int sendvalue; if (synth == 0) return(0); if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0)) return(0); if (stratusApp.resources[0].devlocn[index].to == 1.0) sendvalue = value * C_RANGE_MIN_1; else sendvalue = value; /* We need to keep a hole for the shadowed opts */ if ((index < ACTIVE_DEVS - 4) && (index >= STRATUS_DEVS)) return(0); synth->mem.param[index] = value; if ((!global.libtest) || (index >= ACTIVE_DEVS)) { if (synth->dispatch[index].other1 < 0) { synth->dispatch[index].routine(synth, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); synth->dispatch[index].routine(synth, global.controlfd, synth->sid2, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); } else synth->dispatch[index].routine(synth, global.controlfd, synth->dispatch[index].other1, /* The SID is buried here */ synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); } else printf("dispatch[%p,%i](%i, %i, %i, %i, %i)\n", synth, index, global.controlfd, synth->dispatch[index].other1, /* The SID is buried here */ synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); return(0); } static int shade_id; void panelSwitch(guiSynth *synth, int fd, int chan, int cont, int op, int value) { brightonEvent event; /* * If the sendvalue is zero, then withdraw the opts window, draw the * slider window, and vice versa. */ if (value == 0) { event.type = BRIGHTON_EXPOSE; event.intvalue = 0; brightonParamChange(synth->win, 3, -1, &event); event.intvalue = 1; brightonParamChange(synth->win, 0, -1, &event); if (strstr(synth->resources->name, "stratus") != 0) shade_id = brightonPut(synth->win, "bitmaps/blueprints/stratusshade.xpm", 0, 0, synth->win->width, synth->win->height); else if (strstr(synth->resources->name, "trilogy") != 0) shade_id = brightonPut(synth->win, "bitmaps/blueprints/trilogyshade.xpm", 0, 0, synth->win->width, synth->win->height); } else { event.type = BRIGHTON_EXPOSE; event.intvalue = 0; brightonParamChange(synth->win, 0, -1, &event); event.intvalue = 1; brightonParamChange(synth->win, 3, -1, &event); brightonRemove(synth->win, shade_id); } } /* * We are going to start two synths here, the organ and string sections will * be one emulator with as many voices as the engine can handle since they are * going to be lightweight and were divider circuits anyway. The synth section * is then separate with a limited number of voices. */ int stratusInit(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); dispatcher *dispatch; int i; if (synth == 0) { synth = findSynth(global.synths, 0); if (synth == 0) { printf("cannot init\n"); return(0); } } if ((initmem = synth->location) == 0) initmem = 11; synth->win = win; printf("Initialise the strilogy link to bristol: %p\n", synth->win); synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float)); synth->mem.count = DEVICE_COUNT; synth->mem.active = ACTIVE_DEVS; if (synth->voices == BRISTOL_VOICECOUNT) synth->voices = 6; synth->dispatch = (dispatcher *) brightonmalloc(DEVICE_COUNT * sizeof(dispatcher)); dispatch = synth->dispatch; synth->synthtype = BRISTOL_TRILOGY; synth->second = brightonmalloc(sizeof(guiSynth)); bcopy(synth, ((guiSynth *) synth->second), sizeof(guiSynth)); ((guiSynth *) synth->second)->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float)); ((guiSynth *) synth->second)->mem.count = DEVICE_COUNT; ((guiSynth *) synth->second)->mem.active = ACTIVE_DEVS; ((guiSynth *) synth->second)->dispatch = synth->dispatch; /* * We really want to have three connection mechanisms. These should be * 1. Unix named sockets. * 2. UDP sockets. * 3. MIDI pipe. */ if (!global.libtest) { int voices = synth->voices; printf("Initialise the strilogy synth circuits\n"); bcopy(&global, &manual, sizeof(guimain)); if ((synth->sid = initConnection(&global, synth)) < 0) return(-1); /* * We have to tweak the voicecount as we use the same synth definition * to request the second layer */ manual.flags |= BRISTOL_CONN_FORCE|BRIGHTON_NOENGINE; manual.host = global.host; manual.port = global.port; printf("Initialise the strilogy organ divider circuits\n"); synth->synthtype = BRISTOL_TRILOGY_ODC; synth->voices = BRISTOL_VOICECOUNT; if ((synth->sid2 = initConnection(&manual, synth)) < 0) return(-1); global.manualfd = manual.controlfd; global.manual = &manual; manual.manual = &global; /* * Having played with the synth type to get the correct emulator we now * have to put it back to the actual model so that the GUI will load * the correct profiles. */ if (strcmp("stratus", synth->resources->name) == 0) synth->synthtype = BRISTOL_STRATUS; else synth->synthtype = BRISTOL_TRILOGY; synth->voices = voices; } for (i = 0; i < DEVICE_COUNT; i++) { synth->dispatch[i].routine = stratusMidiSendMsg; dispatch[i].controller = 126; dispatch[i].operator = 101; dispatch[i].other1 = synth->sid; } dispatch[0].controller = 0; dispatch[0].operator = 3; dispatch[0].other1 = synth->sid2; dispatch[1].controller = 0; dispatch[1].operator = 2; dispatch[1].other1 = synth->sid2; dispatch[2].controller = 0; dispatch[2].operator = 1; dispatch[2].other1 = synth->sid2; dispatch[3].controller = 0; dispatch[3].operator = 0; dispatch[3].other1 = synth->sid2; /* Filter env, c, e */ dispatch[4].controller = 126; dispatch[4].operator = 10; dispatch[5].controller = 3; dispatch[5].operator = 0; dispatch[6].controller = 3; dispatch[6].operator = 1; dispatch[7].controller = 126; /* Pedal/Manual filter */ dispatch[7].operator = 26; dispatch[8].controller = 126; dispatch[8].operator = 22; dispatch[9].controller = 126; dispatch[9].operator = 23; dispatch[10].controller = 126; dispatch[10].operator = 24; dispatch[11].controller = 126; dispatch[11].operator = 25; /* VCO 1 - tune, sync-2, octave */ dispatch[12].controller = 0; dispatch[12].operator = 9; dispatch[13].controller = 126; dispatch[13].operator = 11; /* Sync */ dispatch[14].controller = 0; dispatch[14].operator = 8; /* VCO 2 - tune, sync-2, octave */ dispatch[15].controller = 126; /* This mixes LFO into osc-2 */ dispatch[15].operator = 12; dispatch[16].controller = 1; dispatch[16].operator = 8; dispatch[17].controller = 1; dispatch[17].operator = 9; /* LFO Routing, multi, shape */ dispatch[18].controller = 126; dispatch[18].operator = 15; dispatch[19].controller = 126; dispatch[19].operator = 16; dispatch[19].routine = (synthRoutine) stratusMultiLFO; dispatch[20].controller = 126; dispatch[20].operator = 17; /* Gains */ dispatch[21].controller = 126; dispatch[21].operator = 9; dispatch[22].controller = 126; dispatch[22].operator = 5; dispatch[22].other1 = synth->sid2; dispatch[23].controller = 126; dispatch[23].operator = 8; dispatch[23].other1 = synth->sid2; /* Trilogy string section */ dispatch[24].controller = 2; dispatch[24].operator = 0; dispatch[24].other1 = synth->sid2; dispatch[24].routine = (synthRoutine) trilogyWaveform; dispatch[25].controller = 2; dispatch[25].operator = 1; dispatch[25].other1 = synth->sid2; dispatch[25].routine = (synthRoutine) trilogyWaveform; /* Env */ dispatch[26].controller = 3; dispatch[26].operator = 0; dispatch[26].other1 = synth->sid2; dispatch[27].controller = 3; dispatch[27].operator = 3; dispatch[27].other1 = synth->sid2; /* Waveform */ dispatch[28].routine = (synthRoutine) stratusWaveform; dispatch[29].controller = 126; dispatch[29].operator = 13; dispatch[29].routine = (synthRoutine) stratusAlternate; dispatch[30].controller = 126; dispatch[30].operator = 14; dispatch[30].routine = (synthRoutine) stratusMono; /* * LFO May need to be shimmed - if the LFO were not the same index in the * two different synths then this would not have worked. */ dispatch[31].controller = 5; dispatch[31].operator = 0; dispatch[31].other1 = -1; dispatch[32].controller = 126; dispatch[32].operator = 18; dispatch[32].other1 = -1; dispatch[33].controller = 126; dispatch[33].operator = 19; dispatch[33].other1 = -1; dispatch[34].controller = 126; dispatch[34].operator = 20; dispatch[34].other1 = -1; /* Organ options */ dispatch[47].controller = 126; dispatch[47].operator = 1; dispatch[47].other1 = -1; dispatch[48].controller = 126; /* Organ panning */ dispatch[48].operator = 3; dispatch[48].other1 = synth->sid2; dispatch[49].controller = 0; /* Waveform */ dispatch[49].operator = 4; dispatch[49].other1 = synth->sid2; dispatch[50].controller = 126; /* Space */ dispatch[50].operator = 4; dispatch[50].other1 = synth->sid2; dispatch[51].controller = 0; /* Modulation */ dispatch[51].operator = 6; dispatch[51].other1 = synth->sid2; dispatch[51].routine = (synthRoutine) stratusMod; /* Synth harmonics */ dispatch[52].controller = 0; dispatch[52].routine = (synthRoutine) stratusOscHarmonics; /* Organ env */ dispatch[53].routine = (synthRoutine) stratusOrganEnv; dispatch[54].controller = 126; /* ODC Tuning */ dispatch[54].operator = 2; dispatch[54].other1 = synth->sid2; dispatch[55].controller = 126; /* Synth Pan */ dispatch[55].operator = 21; dispatch[56].controller = 126; /* Synth Tuning? */ dispatch[56].operator = 2; dispatch[57].controller = 1; dispatch[57].routine = (synthRoutine) stratusOscHarmonics; dispatch[58].controller = 2; /* Env touch */ dispatch[58].operator = 5; dispatch[58].routine = (synthRoutine) stratusEnvelope; dispatch[59].controller = 3; /* Filter Type */ dispatch[59].operator = 4; dispatch[59].routine = (synthRoutine) stratusFilter; dispatch[60].controller = 3; /* Filter Tracking */ dispatch[60].operator = 3; /* String options */ dispatch[61].controller = 126; /* String panning */ dispatch[61].operator = 6; dispatch[61].other1 = synth->sid2; dispatch[62].routine = (synthRoutine) trilogyStringHarmonics; dispatch[63].controller = 126; /* String spacialisation */ dispatch[63].operator = 7; dispatch[63].other1 = synth->sid2; dispatch[64].controller = 2; /* String mod */ dispatch[64].operator = 6; dispatch[64].other1 = synth->sid2; dispatch[64].routine = (synthRoutine) stratusMod; dispatch[65].controller = 2; /* String Waveform */ dispatch[65].operator = 4; dispatch[65].other1 = synth->sid2; /* Synth env */ dispatch[66].controller = 2; dispatch[66].operator = 0; dispatch[67].controller = 2; dispatch[67].operator = 1; dispatch[68].controller = 2; dispatch[68].operator = 2; dispatch[69].controller = 2; dispatch[69].operator = 3; /* Memory and MIDI */ dispatch[MEM_START + 0].operator = 1; dispatch[MEM_START + 1].operator = 2; dispatch[MEM_START + 2].operator = 3; dispatch[MEM_START + 3].operator = 4; dispatch[MEM_START + 4].operator = 5; dispatch[MEM_START + 5].operator = 6; dispatch[MEM_START + 6].operator = 7; dispatch[MEM_START + 7].operator = 8; dispatch[MEM_START + 8].controller = 1; dispatch[MEM_START + 9].controller = 2; dispatch[MEM_START + 10].controller = 3; dispatch[MEM_START + 11].controller = 4; dispatch[MEM_START + 12].controller = 5; dispatch[MEM_START + 13].controller = 6; dispatch[MEM_START + 0].routine = dispatch[MEM_START + 1].routine = dispatch[MEM_START + 2].routine = dispatch[MEM_START + 3].routine = dispatch[MEM_START + 4].routine = dispatch[MEM_START + 5].routine = dispatch[MEM_START + 6].routine = dispatch[MEM_START + 7].routine = dispatch[MEM_START + 8].routine = dispatch[MEM_START + 9].routine = dispatch[MEM_START + 10].routine = dispatch[MEM_START + 11].routine = dispatch[MEM_START + 12].routine = dispatch[MEM_START + 13].routine = (synthRoutine) stratusMemory; dispatch[DEVICE_COUNT - 3].routine = dispatch[DEVICE_COUNT - 2].routine = (synthRoutine) stratusMidi; dispatch[DEVICE_COUNT - 3].controller = 1; dispatch[DEVICE_COUNT - 2].controller = 2; dispatch[MEM_START].other1 = -1; /* Organ oscillator */ bristolMidiSendMsg(global.controlfd, synth->sid2, 0, 0, 16383); bristolMidiSendMsg(global.controlfd, synth->sid2, 0, 1, 16383); bristolMidiSendMsg(global.controlfd, synth->sid2, 0, 2, 16383); bristolMidiSendMsg(global.controlfd, synth->sid2, 0, 3, 16383); bristolMidiSendMsg(global.controlfd, synth->sid2, 0, 4, 0); bristolMidiSendMsg(global.controlfd, synth->sid2, 0, 5, 0); /* Pulse signal level and width */ bristolMidiSendMsg(global.controlfd, synth->sid2, 0, 7, 0); bristolMidiSendMsg(global.controlfd, synth->sid2, 0, 8, 0); bristolMidiSendMsg(global.controlfd, synth->sid2, 0, 9, 8192); bristolMidiSendMsg(global.controlfd, synth->sid2, 0, 11, 16383); /* ODC grooming envelope */ bristolMidiSendMsg(global.controlfd, synth->sid2, 1, 0, 0); bristolMidiSendMsg(global.controlfd, synth->sid2, 1, 1, 100); bristolMidiSendMsg(global.controlfd, synth->sid2, 1, 2, 6000); bristolMidiSendMsg(global.controlfd, synth->sid2, 1, 3, 500); bristolMidiSendMsg(global.controlfd, synth->sid2, 1, 4, 16383); /* Velocity tracking envelope. Default is off */ bristolMidiSendMsg(global.controlfd, synth->sid2, 1, 5, 0); /* String oscillator */ bristolMidiSendMsg(global.controlfd, synth->sid2, 2, 0, 16383); bristolMidiSendMsg(global.controlfd, synth->sid2, 2, 1, 16383); bristolMidiSendMsg(global.controlfd, synth->sid2, 2, 2, 16383); bristolMidiSendMsg(global.controlfd, synth->sid2, 2, 3, 16383); /* Load it up on a sawtooth although this is now a parameter */ bristolMidiSendMsg(global.controlfd, synth->sid2, 2, 4, 16383); bristolMidiSendMsg(global.controlfd, synth->sid2, 2, 5, 0); /* Pulse signal level and width */ bristolMidiSendMsg(global.controlfd, synth->sid2, 2, 7, 1); bristolMidiSendMsg(global.controlfd, synth->sid2, 2, 8, 12); bristolMidiSendMsg(global.controlfd, synth->sid2, 2, 9, 8192); bristolMidiSendMsg(global.controlfd, synth->sid2, 2, 11, 16383); /* String grooming ASR envelope */ bristolMidiSendMsg(global.controlfd, synth->sid2, 3, 1, 8192); bristolMidiSendMsg(global.controlfd, synth->sid2, 3, 2, 16383); bristolMidiSendMsg(global.controlfd, synth->sid2, 3, 4, 16383); bristolMidiSendMsg(global.controlfd, synth->sid2, 3, 5, 1); /* Filter mod, tracking and type */ bristolMidiSendMsg(global.controlfd, synth->sid, 3, 2, 8192); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 3, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 4, 4); /* Synth envelope */ bristolMidiSendMsg(global.controlfd, synth->sid, 2, 4, 16383); /* * Envelope is not touch sensitive, this is moved into the gain stage * since the same filter is used for the filter and amp */ bristolMidiSendMsg(global.controlfd, synth->sid, 2, 5, 0); /* Osc harmonics - should add control */ bristolMidiSendMsg(global.controlfd, synth->sid, 0, 1, 8192); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 1, 8192); return(0); } /* * This will be called to make any routine specific parameters available. */ int stratusConfigure(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); brightonEvent event; if (synth == 0) { printf("problems going operational\n"); return(-1); } if (synth->flags & OPERATIONAL) return(0); synth->flags |= OPERATIONAL; synth->keypanel = 1; synth->keypanel2 = -1; synth->transpose = 24; synth->bank = initmem / 10; synth->location = initmem % 10; loadMemory(synth, synth->resources->name, 0, initmem, synth->mem.active, 0, BRISTOL_FORCE); stratusLoadMemory(synth, global.controlfd, synth->midichannel, 0, initmem, 0); event.value = 1.0; brightonParamChange(synth->win, synth->panel, MEM_START + synth->location - 1, &event); if (strstr(synth->resources->name, "stratus") != NULL) shade_id = brightonPut(win, "bitmaps/blueprints/stratusshade.xpm", 0, 0, win->width, win->height); else if (strstr(synth->resources->name, "trilogy") != NULL) shade_id = brightonPut(win, "bitmaps/blueprints/trilogyshade.xpm", 0, 0, win->width, win->height); /* * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only * occurs on first paint, so we suppress the first paint, and then request * an expose here. */ event.type = BRIGHTON_EXPOSE; event.intvalue = 1; brightonParamChange(synth->win, KEY_PANEL, -1, &event); // brightonParamChange(synth->win, 0, -1, &event); configureGlobals(synth); dc = brightonGetDCTimer(win->dcTimeout); return(0); } bristol-0.60.11/brighton/Makefile.am0000755000175000017500000000272712073330071014135 00000000000000AUTOMAKE_OPTIONS = foreign AM_CFLAGS = -pthread -Wall -g -I$(srcdir)/../include/brighton -I$(srcdir)/../include/bristol -DBRISTOL_HAS_ALSA=@BRISTOL_HAS_ALSA@ @BRIGHTON_HAS_X11@ -DBRISTOL_VOICECOUNT=@_BRISTOL_VOICES@ bin_PROGRAMS = brighton brighton_LDFLAGS = -Bdynamic -L../libbrighton/ -L../libbristolmidi/.libs @BRIGHTON_LIBXLIBS@ -L/usr/X11R6/lib -L../libbvg brighton_LDADD = -lbrighton -lbvg @BRIGHTON_LIBB11@ @BRIGHTON_LIBX11@ @BRIGHTON_LIBXEXT@ -lbristolmidi @ALSA_LIBS@ -lm -lpthread brighton_SOURCES = brightonArp2600.c brightonAxxe.c brighton.c brightonControllers.c brightonDX.c brightonExplorer.c brightonHammondB3.c brightonHammond.c brightonJuno.c brightonMemoryMoog.c brightonMini.c brightonMixer.c brightonMixerMemory.c brightonMixerMenu.c brightonMS20.c brightonOBXa.c brightonOBX.c brightonOdyssey.c brightonPoly6.c brightonPoly.c brightonProphet10.c brightonProphet52.c brightonProphet.c brightonRhodesBass.c brightonRhodes.c brightonRoutines.c brightonSAks.c brightonVox.c brightonKeyboards.h brightonKeys.h brightonMini.h brightonMixer.h brightonMixerMemory.h brightonhelp.h brightonSolina.c brightonRoadRunner.c brightonGranular.c brightonRealistic.c brightonVoxM2.c brightonJupiter.c brightonBitOne.c brightonMaster.c brightonCS80.c brightonProOne.c brightonVoyager.c brightonSonic6.c brightonTrilogy.c brightonStratus.c brightonPoly800.c brightonBME700.c brightonBassMaker.c brightonSID.c brightonSID2.c brightonSID2.h brightonreadme.h brightonCLI.c brightonVImages.h bristol-0.60.11/brighton/brightonCS80.c0000644000175000017500000021276211746476475014507 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* * Layer params - 12 are reserved: * * Sqr gain level * Rmp gain level * Osc Brilliance' * Osc Brilliance'' * Filter brilliance * Pan * Env1 gain * Nudge * Switch/level env2 to LPF? Gives two env for filters. Env panned cutover? * Glide rates - from starting point, not between notes? * * Global params: * * Detune * LFO Key Sync * Midi Channel selection * Noise Multi * LFO Multi * Nudge * Nudge Depth */ #include #include "brighton.h" #include "bristolmidi.h" #include "brightonMini.h" #include "brightoninternals.h" #include "bristolarpeggiation.h" static int cs80Init(); static int cs80Configure(); static int cs80Callback(brightonWindow *, int, int, float); static int cs80panelswitch(brightonWindow *, int, int, float); static int midiCallback(brightonWindow *, int, int, float); extern guimain global; static int debuglevel = 0; #include "brightonKeys.h" /* * These are a pair of double click timers and mw is a memory weighting to * scale the 64 available memories into banks of banks */ static int dc1, mw = 0; static int width; /* * We need a scratchpad so that we can load single layers out of existing * memories. */ static float *scratch = NULL; #define DEVICE_COUNT 180 /* * Need to split up active into the two layers, mods and opts. */ #define ACTIVE_DEVS 145 #define MEM_MGT (ACTIVE_DEVS + 2) #define LAYER_DEVS 120 #define PATCH_BUTTONS MEM_MGT #define BANK_BUTTONS (MEM_MGT + 9) #define LOAD_BUTTON (MEM_MGT + 8) #define KEY_PANEL 2 #define MODS_PANEL 2 #define RADIO_UB 147 #define RADIO_LB 163 #define RADIO_UP 151 #define RADIO_LP 167 #define PANEL_SELECT (ACTIVE_DEVS + 4) /* * This structure is for device definition. The structure is defined in * include/brighton.h, further definitions in brighton/brightonDevtable.h and * include/brightoninternals.h * * typedef int (*brightonCallback)(int, float); * typedef struct BrightonLocations { * int device; 0=rotary, 1=scale, etc. * float relx, rely; relative position with regards to 1000 by 1000 window * float relw, relh; relative height. * int from, to; * brightonCallback callback; specific to this dev * char *image; bitmap. If zero take a device default. * int flags; * } brightonLocations; * * This example is for a cs80Bristol type synth interface. */ #define W1 17 #define W2 16 #define W3 15 #define L1 200 #define L2 50 #define L3 100 #define L4 120 #define R1 53 #define R1a 100 #define R2 346 #define R2a 396 #define R3 618 #define R3a (R3 + 45) #define R4 (R3 + L2) #define R5 (R4 + L2) #define D1 25 #define D2 (W2) #define D3 20 #define D4 24 #define C1 270 #define C2 (C1 + D1) #define C3 (C2 + D1) #define C4 (C3 + D1 + 5) #define C5 (C4 + D1) #define C6 (C5 + D1) #define C7 (C6 + D1 +D3) #define C8 (C7 + D1) #define C9 (C8 + D1) #define C10 (C9 + D1) #define C11 (C10 + D1) #define C12 (C11 + D1) #define C13 (C12 + D1) #define C14 (C13 + D1) #define C15 (C14 + D1) #define C16 (C15 + D1 + D3) #define C17 (C16 + D1) #define C18 (C17 + D1) #define C19 (C18 + D1) #define C20 (C19 + D1) #define C21 (C20 + D1) #define C22 (C21 + D1) #define C23 (C22 + D1 + D3) #define C24 (C23 + D1) #define C25 (C24 + D1) #define C26 (C25 + D1) #define CB1 14 #define CB2 (CB1 + D4 + 8) #define CB3 (CB2 + D4 + 7) #define CB4 (CB3 + D4) #define CB5 (CB4 + D4) #define CB6 (CB5 + D4) #define CB7 (CB6 + D4) #define CB8 (CB7 + D4 + 4) #define CB9 (CB8 + D4 + 16) #define CB10 (CB9 + D4) #define CB11 (CB10 + D4) #define CB12 (CB11 + D4) #define CB13 (CB12 + D4) #define CB14 (CB13 + D4) #define CB15 665 #define CB16 (CB15 + D4) #define CB17 (CB16 + D4) #define CB18 (CB17 + D4 + 10) #define CB19 (CB18 + D4) #define CB20 (CB19 + D4) #define CB21 (CB20 + D4 + 1) #define CB22 (CB21 + D4 + 8) #define CB23 (CB22 + D4 + 1) #define CB24 (CB23 + D4) #define CB25 (CB24 + D4) #define CB26 (CB25 + D4 + 10) #define BC1 405 #define BC2 (BC1 + D2) #define BC3 (BC2 + D2) #define BC4 (BC3 + D2) #define BC5 (BC4 + D2) #define BC6 (BC5 + D2) #define BC7 (BC6 + D2) #define BC8 (BC7 + D2) #define BC9 (BC8 + D2) #define BC10 (BC9 + D2) #define BC11 (BC10 + D2) #define BC12 (BC11 + D2) #define BC13 (BC12 + D2) #define BC14 (BC13 + D2) #define BC15 (BC14 + D2) #define BC16 (BC15 + D2) /* * two rows of 25 identical controls for the layered synths, then a load for * global controls and presets. */ static brightonLocations locations[DEVICE_COUNT] = { /* First 26 controls for upper layer - 0 */ {"", 1, C1, R1, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderwhite2.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, C2, R1, W1, L1, 0, 1, 0, "bitmaps/knobs/slidergreen.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, C3, R1, W1, L1, 0, 1, 0, "bitmaps/knobs/slidergreen.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 2, C4, R1a, W3, L3, 0, 1, 0, "bitmaps/buttons/rockerblack.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_VERTICAL}, {"", 2, C5, R1a, W3, L3, 0, 1, 0, "bitmaps/buttons/rockerblack.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_VERTICAL}, {"", 1, C6, R1, W1, L1, 0, 1, 0, "bitmaps/knobs/slidergrey.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, C7, R1, W1, L1, 0, 1, 0, "bitmaps/knobs/slidergreen.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, C8, R1, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderred2.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, C9, R1, W1, L1, 0, 1, 0, "bitmaps/knobs/slidergreen.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, C10, R1, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderred2.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, C11, R1, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack6.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, C12, R1, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack6.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, C13, R1, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack6.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, C14, R1, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack6.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, C15, R1, W1, L1, 0, 1, 0, "bitmaps/knobs/slideryellow.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, C16, R1, W1, L1, 0, 1, 0, "bitmaps/knobs/slidergrey.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, C17, R1, W1, L1, 0, 1, 0, "bitmaps/knobs/slidergrey.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, C18, R1, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack6.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, C19, R1, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack6.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, C20, R1, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack6.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, C21, R1, W1, L1, 0, 1, 0, "bitmaps/knobs/slideryellow.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, C22, R1, W1, L1, 0, 1, 0, "bitmaps/knobs/slidergrey.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, C23, R1, W1, L1, 0, 1, 0, "bitmaps/knobs/slidergreen.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, C24, R1, W1, L1, 0, 1, 0, "bitmaps/knobs/slidergrey.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, C25, R1, W1, L1, 0, 1, 0, "bitmaps/knobs/slidergreen.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, C26, R1, W1, L1, 0, 1, 0, "bitmaps/knobs/slidergrey.xpm", 0, BRIGHTON_HALFSHADOW}, /* Second 25 controls for lower layer - 26 */ {"", 1, C1, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderwhite2.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, C2, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/slidergreen.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, C3, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/slidergreen.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 2, C4, R2a, W3, L3, 0, 1, 0, "bitmaps/buttons/rockerblack.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_VERTICAL}, {"", 2, C5, R2a, W3, L3, 0, 1, 0, "bitmaps/buttons/rockerblack.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_VERTICAL}, {"", 1, C6, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/slidergrey.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, C7, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/slidergreen.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, C8, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderred2.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, C9, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/slidergreen.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, C10, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderred2.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, C11, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack6.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, C12, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack6.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, C13, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack6.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, C14, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack6.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, C15, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/slideryellow.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, C16, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/slidergrey.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, C17, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/slidergrey.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, C18, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack6.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, C19, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack6.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, C20, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack6.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, C21, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/slideryellow.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, C22, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/slidergrey.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, C23, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/slidergreen.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, C24, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/slidergrey.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, C25, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/slidergreen.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, C26, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/slidergrey.xpm", 0, BRIGHTON_HALFSHADOW}, /* * Global controls 1 - 52 * The two knobs will eventually be moved outside of the memory area for * global tune and volume control. We will also install about 16 dummies * to cover for the control panel and a rake more for diverse parameters */ {"", 10, CB2, R3a, W1, L4, 0, 1, 0, "bitmaps/knobs/sliderwhite7_3.xpm", "bitmaps/knobs/sliderwhite7_2.xpm", BRIGHTON_HALFSHADOW|BRIGHTON_NOTCH}, {"", 10, CB3, R3a, W1, L4, 0, 1, 0, "bitmaps/knobs/sliderblack7_1.xpm", "bitmaps/knobs/sliderblack7_2.xpm", BRIGHTON_HALFSHADOW}, {"", 10, CB4, R3a, W1, L4, 0, 1, 0, "bitmaps/knobs/sliderblack7_1.xpm", "bitmaps/knobs/sliderblack7_2.xpm", BRIGHTON_HALFSHADOW}, {"", 10, CB5, R3a, W1, L4, 0, 1, 0, "bitmaps/knobs/slidergrey7_1.xpm", "bitmaps/knobs/slidergrey7_2.xpm", BRIGHTON_HALFSHADOW}, {"", 10, CB6, R3a, W1, L4, 0, 1, 0, "bitmaps/knobs/sliderwhite7_3.xpm", "bitmaps/knobs/sliderwhite7_2.xpm", BRIGHTON_HALFSHADOW}, {"", 10, CB7, R3a, W1, L4, 0, 1, 0, "bitmaps/knobs/slidergrey7_1.xpm", "bitmaps/knobs/slidergrey7_2.xpm", BRIGHTON_HALFSHADOW}, {"", 1, CB8, R3, W1, L1, 0, 5, 0, "bitmaps/knobs/sliderblack6.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 10, CB9, R3a, W1, L4, 0, 1, 0, "bitmaps/knobs/sliderwhite7_3.xpm", "bitmaps/knobs/sliderwhite7_2.xpm", BRIGHTON_HALFSHADOW}, {"", 10, CB10, R3a, W1, L4, 0, 1, 0, "bitmaps/knobs/sliderwhite7_3.xpm", "bitmaps/knobs/sliderwhite7_2.xpm", BRIGHTON_HALFSHADOW}, {"", 10, CB11, R3a, W1, L4, 0, 1, 0, "bitmaps/knobs/slidergreen7_1.xpm", "bitmaps/knobs/slidergreen7_2.xpm", BRIGHTON_HALFSHADOW}, {"", 10, CB12, R3a, W1, L4, 0, 1, 0, "bitmaps/knobs/slidergrey7_1.xpm", "bitmaps/knobs/slidergrey7_2.xpm", BRIGHTON_HALFSHADOW}, {"", 1, CB13 , R3, W1, L1, 0, 5, 0, "bitmaps/knobs/sliderwhite2.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, CB14 + 8, R3, W1, L1, 0, 5, 0, "bitmaps/knobs/sliderwhite2.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, /* * Global controls 2 - 69 */ {"", 10, CB15, R3a, W1, L4, 0, 1, 0, "bitmaps/knobs/sliderblack7_1.xpm", "bitmaps/knobs/sliderblack7_2.xpm", BRIGHTON_HALFSHADOW}, {"", 10, CB16, R3a, W1, L4, 0, 1, 0, "bitmaps/knobs/slidergreen7_1.xpm", "bitmaps/knobs/slidergreen7_2.xpm", BRIGHTON_HALFSHADOW}, {"", 10, CB17, R3a, W1, L4, 0, 1, 0, "bitmaps/knobs/sliderred7_1.xpm", "bitmaps/knobs/sliderred7_2.xpm", BRIGHTON_HALFSHADOW}, {"", 10, CB18, R3a, W1, L4, 0, 1, 0, "bitmaps/knobs/sliderwhite7_3.xpm", "bitmaps/knobs/sliderwhite7_2.xpm", BRIGHTON_HALFSHADOW}, {"", 10, CB19, R3a, W1, L4, 0, 1, 0, "bitmaps/knobs/sliderwhite7_3.xpm", "bitmaps/knobs/sliderwhite7_2.xpm", BRIGHTON_HALFSHADOW}, {"", 10, CB20, R3a, W1, L4, 0, 1, 0, "bitmaps/knobs/sliderwhite7_3.xpm", "bitmaps/knobs/sliderwhite7_2.xpm", BRIGHTON_HALFSHADOW}, {"", 10, CB21, R3a, W1, L4, 0, 1, 0, "bitmaps/knobs/slidergreen7_1.xpm", "bitmaps/knobs/slidergreen7_2.xpm", BRIGHTON_HALFSHADOW}, {"", 10, CB22, R3a, W1, L4, 0, 1, 0, "bitmaps/knobs/slidergreen7_1.xpm", "bitmaps/knobs/slidergreen7_2.xpm", BRIGHTON_HALFSHADOW}, {"", 10, CB23, R3a, W1, L4, 0, 1, 0, "bitmaps/knobs/slidergreen7_1.xpm", "bitmaps/knobs/slidergreen7_2.xpm", BRIGHTON_HALFSHADOW}, {"", 10, CB24, R3a, W1, L4, 0, 1, 0, "bitmaps/knobs/slidergrey7_1.xpm", "bitmaps/knobs/slidergrey7_2.xpm", BRIGHTON_HALFSHADOW}, {"", 10, CB25, R3a, W1, L4, 0, 1, 0, "bitmaps/knobs/slidergrey7_1.xpm", "bitmaps/knobs/slidergrey7_2.xpm", BRIGHTON_HALFSHADOW}, /* * Dummies 65 from index 80 * * First 53 for the opts panel, 36 used, final 12 for the opts. */ {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, /* Free 13 May turn into global options so channels can have 20 each */ {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, /* Mods panel, 12 from 133 */ {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, /* Vol and Tune - 145 */ {"", 0, CB1, R4 + 15, W1 + 8, L1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, BRIGHTON_HALFSHADOW|BRIGHTON_NOTCH}, {"", 0, CB26, R4 + 15, W1 + 8, L1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, BRIGHTON_HALFSHADOW}, /* Memory Buttons */ {"", 2, BC1, R4, W2, L2, 0, 1, 0, "bitmaps/buttons/touchnlo.xpm", "bitmaps/buttons/touchnlO.xpm", 0}, {"", 2, BC2, R4, W2, L2, 0, 1, 0, "bitmaps/buttons/touchnlo.xpm", "bitmaps/buttons/touchnlO.xpm", 0}, {"", 2, BC3, R4, W2, L2, 0, 1, 0, "bitmaps/buttons/touchnlo.xpm", "bitmaps/buttons/touchnlO.xpm", 0}, {"", 2, BC4, R4, W2, L2, 0, 1, 0, "bitmaps/buttons/touchnlo.xpm", "bitmaps/buttons/touchnlO.xpm", 0}, {"", 2, BC5, R4, W2, L2, 0, 1, 0, "bitmaps/buttons/touchnlr.xpm", "bitmaps/buttons/touchnlR.xpm", 0}, {"", 2, BC6, R4, W2, L2, 0, 1, 0, "bitmaps/buttons/touchnlr.xpm", "bitmaps/buttons/touchnlR.xpm", 0}, {"", 2, BC7, R4, W2, L2, 0, 1, 0, "bitmaps/buttons/touchnlo.xpm", "bitmaps/buttons/touchnlO.xpm", 0}, {"", 2, BC8, R4, W2, L2, 0, 1, 0, "bitmaps/buttons/touchnlo.xpm", "bitmaps/buttons/touchnlO.xpm", 0}, {"", 2, BC9, R4, W2, L2, 0, 1, 0, "bitmaps/buttons/touchnlo.xpm", "bitmaps/buttons/touchnlO.xpm", 0}, {"", 2, BC10, R4, W2, L2, 0, 1, 0, "bitmaps/buttons/touchnlg.xpm", "bitmaps/buttons/touchnlG.xpm", 0}, {"", 2, BC11, R4, W2, L2, 0, 1, 0, "bitmaps/buttons/touchnlg.xpm", "bitmaps/buttons/touchnlG.xpm", 0}, {"", 2, BC12, R4, W2, L2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlW.xpm", 0}, {"", 2, BC13, R4, W2, L2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlW.xpm", 0}, {"", 2, BC14, R4, W2, L2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlW.xpm", 0}, {"", 2, BC15, R4, W2, L2, 0, 1, 0, "bitmaps/buttons/touchnlo.xpm", "bitmaps/buttons/touchnlO.xpm", BRIGHTON_CHECKBUTTON}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 2, BC1, R5, W2, L2, 0, 1, 0, "bitmaps/buttons/touchnlo.xpm", "bitmaps/buttons/touchnlO.xpm", 0}, {"", 2, BC2, R5, W2, L2, 0, 1, 0, "bitmaps/buttons/touchnlo.xpm", "bitmaps/buttons/touchnlO.xpm", 0}, {"", 2, BC3, R5, W2, L2, 0, 1, 0, "bitmaps/buttons/touchnlo.xpm", "bitmaps/buttons/touchnlO.xpm", 0}, {"", 2, BC4, R5, W2, L2, 0, 1, 0, "bitmaps/buttons/touchnlo.xpm", "bitmaps/buttons/touchnlO.xpm", 0}, {"", 2, BC5, R5, W2, L2, 0, 1, 0, "bitmaps/buttons/touchnlr.xpm", "bitmaps/buttons/touchnlR.xpm", 0}, {"", 2, BC6, R5, W2, L2, 0, 1, 0, "bitmaps/buttons/touchnlr.xpm", "bitmaps/buttons/touchnlR.xpm", 0}, {"", 2, BC7, R5, W2, L2, 0, 1, 0, "bitmaps/buttons/touchnlo.xpm", "bitmaps/buttons/touchnlO.xpm", 0}, {"", 2, BC8, R5, W2, L2, 0, 1, 0, "bitmaps/buttons/touchnlo.xpm", "bitmaps/buttons/touchnlO.xpm", 0}, {"", 2, BC9, R5, W2, L2, 0, 1, 0, "bitmaps/buttons/touchnlo.xpm", "bitmaps/buttons/touchnlO.xpm", 0}, {"", 2, BC10, R5, W2, L2, 0, 1, 0, "bitmaps/buttons/touchnlg.xpm", "bitmaps/buttons/touchnlG.xpm", 0}, {"", 2, BC11, R5, W2, L2, 0, 1, 0, "bitmaps/buttons/touchnlg.xpm", "bitmaps/buttons/touchnlG.xpm", 0}, {"", 2, BC12, R5, W2, L2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlW.xpm", 0}, {"", 2, BC13, R5, W2, L2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlW.xpm", 0}, {"", 2, BC14, R5, W2, L2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlW.xpm", 0}, {"", 2, BC15, R5, W2, L2, 0, 1, 0, "bitmaps/buttons/touchnlr.xpm", "bitmaps/buttons/touchnlR.xpm", BRIGHTON_CHECKBUTTON}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, /* Touch strip - hide the controller */ {"", 1, 135, 920, 560, 41, 0, 1, 0, "bitmaps/buttons/blue.xpm", 0, BRIGHTON_VERTICAL|BRIGHTON_NOSHADOW|BRIGHTON_CENTER|BRIGHTON_REVERSE}, }; /* * Mod panel */ static brightonLocations csmods[15] = { {"", 2, 50, 100, 70, 300, 0, 1, 0, "bitmaps/buttons/dualpushgrey.xpm", 0, BRIGHTON_VERTICAL}, {"", 1, 305, 50, 80, 400, 0, 1, 0, "bitmaps/knobs/slideryellow.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, 430, 50, 80, 400, 0, 1, 0, "bitmaps/knobs/sliderwhite2.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 0, 630, 100, 115, 200, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 0, 820, 100, 115, 200, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 2, 50, 550, 70, 300, 0, 1, 0, "bitmaps/buttons/rockerblack.xpm", 0, BRIGHTON_VERTICAL}, {"", 2, 175, 550, 70, 300, 0, 1, 0, "bitmaps/buttons/rockerblack.xpm", 0, BRIGHTON_VERTICAL}, {"", 2, 300, 550, 70, 300, 0, 1, 0, "bitmaps/buttons/rockerblack.xpm", 0, BRIGHTON_VERTICAL}, {"", 2, 425, 550, 70, 300, 0, 1, 0, "bitmaps/buttons/rockerblack.xpm", 0, BRIGHTON_VERTICAL}, {"", 2, 640, 410, 90, 420, 0, 1, 0, "bitmaps/buttons/rockersmoothBB.xpm", "bitmaps/buttons/rockersmoothBBd.xpm", 0}, {"", 2, 740, 410, 90, 420, 0, 1, 0, "bitmaps/buttons/rockersmoothBB.xpm", "bitmaps/buttons/rockersmoothBBd.xpm", 0}, {"", 2, 840, 410, 90, 420, 0, 1, 0, "bitmaps/buttons/rockersmoothBB.xpm", "bitmaps/buttons/rockersmoothBBd.xpm", 0}, }; static brightonLocations csmods2[1] = { {"", 2, 250, 450, 600, 300, 0, 1, 0, "bitmaps/buttons/rockersmoothBWR.xpm", "bitmaps/buttons/rockersmoothBWRd.xpm", 0}, }; #define OPTS_COUNT 48 #define MODS_COUNT 12 #define OW1 50 #define OL1 250 #define OR1 110 #define OR2 390 #define OR3 (OR2 + OR2 - OR1) #define OD1 73 #define OC1 104 #define OC2 (OC1 + OD1) #define OC3 (OC2 + OD1) #define OC4 (OC3 + OD1) #define OC5 (OC4 + OD1) #define OC6 (OC5 + OD1) #define OC7 (OC6 + OD1) #define OC8 (OC7 + OD1) #define OC9 (OC8 + OD1) #define OC10 (OC9 + OD1) #define OC11 (OC10 + OD1) #define OC12 (OC11 + OD1) static brightonLocations csopts[OPTS_COUNT] = { {"", 1, OC1, OR1, OW1, OL1, 0, 1, 0, "bitmaps/knobs/slidergrey.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, OC2, OR1, OW1, OL1, 0, 1, 0, "bitmaps/knobs/slidergrey.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, OC3, OR1, OW1, OL1, 0, 1, 0, "bitmaps/knobs/slidergreen.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, OC4, OR1, OW1, OL1, 0, 1, 0, "bitmaps/knobs/slidergreen.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, OC5, OR1, OW1, OL1, 0, 1, 0, "bitmaps/knobs/sliderred2.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, OC6, OR1, OW1, OL1, 0, 1, 0, "bitmaps/knobs/sliderblack6.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, OC7, OR1, OW1, OL1, 0, 1, 0, "bitmaps/knobs/slidergreen.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, OC8, OR1, OW1, OL1, 0, 1, 0, "bitmaps/knobs/sliderblack6.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, OC9, OR1, OW1, OL1, 0, 1, 0, "bitmaps/knobs/sliderblack6.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, OC10, OR1, OW1, OL1, 0, 1, 0, "bitmaps/knobs/slidergrey.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, OC11, OR1, OW1, OL1, 0, 1, 0, "bitmaps/knobs/slideryellow.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, OC12, OR1, OW1, OL1, 0, 1, 0, "bitmaps/knobs/sliderblack6.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 1, OC1, OR2, OW1, OL1, 0, 1, 0, "bitmaps/knobs/slidergrey.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, OC2, OR2, OW1, OL1, 0, 1, 0, "bitmaps/knobs/slidergrey.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, OC3, OR2, OW1, OL1, 0, 1, 0, "bitmaps/knobs/slidergreen.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, OC4, OR2, OW1, OL1, 0, 1, 0, "bitmaps/knobs/slidergreen.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, OC5, OR2, OW1, OL1, 0, 1, 0, "bitmaps/knobs/sliderred2.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, OC6, OR2, OW1, OL1, 0, 1, 0, "bitmaps/knobs/sliderblack6.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, OC7, OR2, OW1, OL1, 0, 1, 0, "bitmaps/knobs/slidergreen.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, OC8, OR2, OW1, OL1, 0, 1, 0, "bitmaps/knobs/sliderblack6.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, OC9, OR2, OW1, OL1, 0, 1, 0, "bitmaps/knobs/sliderblack6.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, OC10, OR2, OW1, OL1, 0, 1, 0, "bitmaps/knobs/slidergrey.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, OC11, OR2, OW1, OL1, 0, 1, 0, "bitmaps/knobs/slideryellow.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, OC12, OR2, OW1, OL1, 0, 1, 0, "bitmaps/knobs/sliderblack6.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 1, OC1, OR3, OW1, OL1, 0, 1, 0, "bitmaps/knobs/sliderwhite2.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, OC2, OR3, OW1, OL1, 0, 1, 0, "bitmaps/knobs/sliderblack6.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, OC3, OR3, OW1, OL1, 0, 1, 0, "bitmaps/knobs/sliderblack6.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, OC4, OR3, OW1, OL1, 0, 1, 0, "bitmaps/knobs/sliderblack6.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, OC5, OR3, OW1, OL1, 0, 1, 0, "bitmaps/knobs/slidergrey.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, OC6, OR3, OW1, OL1, 0, 1, 0, "bitmaps/knobs/slidergrey.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, OC7, OR3, OW1, OL1, 0, 1, 0, "bitmaps/knobs/sliderwhite2.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, OC8, OR3, OW1, OL1, 0, 1, 0, "bitmaps/knobs/sliderwhite2.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, OC9, OR3, OW1, OL1, 0, 1, 0, "bitmaps/knobs/slidergreen.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, OC10, OR3, OW1, OL1, 0, 1, 0, "bitmaps/knobs/slidergreen.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, OC11, OR3, OW1, OL1, 0, 1, 0, "bitmaps/knobs/slideryellow.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 1, OC12, OR3, OW1, OL1, 0, 1, 0, "bitmaps/knobs/sliderblack6.xpm", 0, BRIGHTON_HALFSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 900, 900, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, }; static int cs80DestroySynth(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); /* * Since we registered two synths, we now need to remove the upper * manual. */ bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_EXIT_ALGO); return(0); } /* * This is a set of globals for the main window rendering. Again taken from * include/brighton.h */ brightonApp cs80App = { "cs80", 0, "bitmaps/textures/wood4.xpm", BRIGHTON_VERTICAL, cs80Init, cs80Configure, /* 3 callbacks, unused? */ midiCallback, cs80DestroySynth, {8, 150, 8, 2, 5, 520, 0, 0}, 940, 435, 0, 0, 11, { { "Opts", "bitmaps/blueprints/cs80opts.xpm", /* flags */ "bitmaps/textures/cs80opts.xpm", /* flags */ BRIGHTON_WITHDRAWN|BRIGHTON_STRETCH, 0, 0, cs80Callback, 28, 58, 235, 382, OPTS_COUNT, csopts }, { "CS80", "bitmaps/blueprints/cs80.xpm", "bitmaps/textures/metal7.xpm", BRIGHTON_STRETCH|BRIGHTON_REVERSE, /* flags */ 0, 0, cs80Callback, 23, 47, 957, 677, DEVICE_COUNT, locations }, { "Keyboard", 0, "bitmaps/newkeys/nkbg.xpm", /* flags */ 0x020|BRIGHTON_STRETCH, 0, 0, keyCallback, 208, 724, 758, 248, KEY_COUNT, keysprofile2 }, { "Mods", "bitmaps/blueprints/cs80mods.xpm", "bitmaps/textures/metal5.xpm", /* flags */ BRIGHTON_VERTICAL, 0, 0, cs80Callback, 23, 724, 186, 248, MODS_COUNT, csmods }, { "Mods2", 0, "bitmaps/textures/metal5.xpm", /* flags */ BRIGHTON_VERTICAL, 0, 0, cs80panelswitch, 943, 724, 38, 248, 1, csmods2 }, { "Leather Edge", 0, "bitmaps/textures/leather.xpm", BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 0, 0, 10, 1000, 0, 0 }, { "Leather Cover", 0, "bitmaps/textures/leather.xpm", BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 10, 830, 13, 160, 0, 0 }, { "Leather Edge", 0, "bitmaps/textures/leather.xpm", BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 991, 0, 10, 1000, 0, 0 }, { "Leather Cover", 0, "bitmaps/textures/leather.xpm", BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 979, 830, 13, 160, 0, 0 }, { "Leather Top", 0, "bitmaps/textures/leather.xpm", BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 0, 0, 1000, 22, 0, 0 }, { "Leather bottom", 0, "bitmaps/textures/leather.xpm", BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 0, 970, 1000, 33, 0, 0 }, } }; static int cs80panelswitch(brightonWindow *win, int panel, int index, float value) { brightonEvent event; event.type = BRIGHTON_EXPOSE; printf("panel swithc %f\n", value); if (value > 0) { event.intvalue = 0; brightonParamChange(win, 0, -1, &event); event.intvalue = 1; brightonParamChange(win, 1, -1, &event); } else { event.intvalue = 1; brightonParamChange(win, 0, -1, &event); } if (width != win->width) brightonPut(win, "bitmaps/blueprints/cs80shade.xpm", 0, 0, win->width, win->height); width = win->width; return(0); } static int cs80Debug(guiSynth *synth, int level) { if (debuglevel >= level) return(1); return(0); } static int cs80MidiSendMsg(guiSynth *synth, int fd, int chan, int c, int o, int v) { bristolMidiSendMsg(fd, synth->sid2, c, o, v); return(0); } static void modPanelFix(brightonWindow *win, guiSynth *synth) { int i; brightonEvent event; event.type = BRIGHTON_FLOAT; for (i = 0; i < 14; i++) { event.value = synth->mem.param[LAYER_DEVS + i]; brightonParamChange(win, MODS_PANEL, i, &event); } } static int midiCallback(brightonWindow *win, int controller, int value, float n) { guiSynth *synth = findSynth(global.synths, win); if (cs80Debug(synth, 1)) printf("midi callback: %x, %i\n", controller, value); switch(controller) { case MIDI_PROGRAM: if (cs80Debug(synth, 2)) printf("midi program: %x, %i\n", controller, value); synth->location = value; loadMemory(synth, "cs80", 0, synth->bank + synth->location + mw, synth->mem.active, 0, 0); modPanelFix(win, synth); break; case MIDI_BANK_SELECT: if (cs80Debug(synth, 2)) printf("midi banksel: %x, %i\n", controller, value); synth->bank = value; break; } return(0); } static void cs80ButtonPanel(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; event.type = BRIGHTON_FLOAT; if (cs80Debug(synth, 1)) printf("cs80ButtonPanel(%i, %i, %i)\n", c, o, v); switch (c) { case 0: /* patch selector */ if (cs80Debug(synth, 2)) printf("memory\n"); /* * Force exclusion */ if (synth->dispatch[MEM_MGT + c].other2) { synth->dispatch[MEM_MGT + c].other2 = 0; return; } if (synth->dispatch[MEM_MGT + c].other1 != -1) { synth->dispatch[MEM_MGT + c].other2 = 1; if (synth->dispatch[MEM_MGT + c].other1 != MEM_MGT + o) event.value = 0; else event.value = 1; brightonParamChange(synth->win, synth->panel, synth->dispatch[MEM_MGT + c].other1, &event); } synth->dispatch[MEM_MGT + c].other1 = MEM_MGT + o; synth->location = o + 1; break; case 1: /* Bank selector */ if (cs80Debug(synth, 2)) printf("bank\n"); /* * Force exclusion */ if (synth->dispatch[MEM_MGT + c].other2) { synth->dispatch[MEM_MGT + c].other2 = 0; return; } if (synth->dispatch[MEM_MGT + c].other1 != -1) { synth->dispatch[MEM_MGT + c].other2 = 1; if (synth->dispatch[MEM_MGT + c].other1 != MEM_MGT + o + 9) event.value = 0; else event.value = 1; brightonParamChange(synth->win, synth->panel, synth->dispatch[MEM_MGT + c].other1, &event); } synth->dispatch[MEM_MGT + c].other1 = MEM_MGT + o + 9; synth->bank = (o + 1) * 10; break; } } #define CS_LOAD 0 #define CS_UB 1 #define CS_LB 2 #define CS_UP 3 #define CS_LP 4 #define CS_SAVE 5 #define UPPER_BANK 0 #define LOWER_BANK 1 #define NO_BANK -1 static int currentLayer = NO_BANK; /* * Loading everything means get the memory with NOCALLS then dispatch the new * values manually including the opts and mods panel. */ static void cs80MemoryShim(guiSynth *synth) { brightonEvent event; int i; event.type = BRIGHTON_FLOAT; /* The main panel */ for (i = 0; i < 80; i++) { event.value = synth->mem.param[i]; brightonParamChange(synth->win, 1, i, &event); } /* The opts panel */ for (i = 0; i < OPTS_COUNT; i++) { event.value = synth->mem.param[i + 80]; brightonParamChange(synth->win, 0, i, &event); } /* The mods panel */ for (i = 0; i < MODS_COUNT; i++) { event.value = synth->mem.param[i + 133]; brightonParamChange(synth->win, 3, i, &event); } } /* * Load everything */ static void cs80MemoryLoad(guiSynth *synth, int layer, int bank, int patch) { printf("load %i %i %i %i\n", mw, layer, bank, patch); loadMemory(synth, "cs80", 0, bank * 10 + patch + mw, synth->mem.active, 0, BRISTOL_FORCE|BRISTOL_NOCALLS); cs80MemoryShim(synth); } /* * Loading layer means get the memory with nocalls into scratch memory then * dispatch the single layer values manually. */ static void cs80MemoryLoadLayer(guiSynth *synth, int layer, int bank, int patch) { float *hold = synth->mem.param; int i, offset = 0; brightonEvent event; printf("load layer %i %i %i %i\n", mw, layer, bank, patch); event.type = BRIGHTON_FLOAT; synth->mem.param = scratch; loadMemory(synth, "cs80", 0, bank * 10 + patch + mw, synth->mem.active, 0, BRISTOL_FORCE|BRISTOL_NOCALLS); synth->mem.param = hold; /* * So, we now have scratch selected. depending on the selected layer we * need to scan through the channel settings and then the opts for that * channel */ if (layer == LOWER_BANK) { printf("load into channel-II\n"); offset = 26; } else printf("load into channel-I\n"); for (i = 0; i < 26; i++) { event.value = scratch[i + offset]; brightonParamChange(synth->win, 1, i + offset, &event); } /* * Then work on the channel opts */ if (layer == LOWER_BANK) { offset = 92; layer = 12; } else { offset = 80; layer = 0; } for (i = 0; i < 12; i++) { event.value = scratch[i + offset]; brightonParamChange(synth->win, 0, i + layer, &event); } } static void cs80MemorySave(guiSynth *synth, int layer, int bank, int patch) { saveMemory(synth, "cs80", 0, mw + bank * 10 + patch, 0); } static void cs80Memory(guiSynth *synth, int fd, int chan, int c, int o, int v) { int i, b = 0, p = 0, off = 147; brightonEvent event; event.type = BRIGHTON_FLOAT; if (synth->flags & MEM_LOADING) return; if ((synth->flags & OPERATIONAL) == 0) return; if (cs80Debug(synth, 1)) printf("cs80Memory(%i, %i, %i)\n", c, o, v); printf("cs80Memory(%i, %i, %i)\n", c, o, v); /* * Six ways here, we need to do button exclusions here, probably in the * routines called. * * CS_LOAD - single then load last selected layer. Double load all. * CS_SAVE - double then save all to last selected layer. * * CS_UB - select upper bank. * CS_LB - select lower bank. * CS_UP - select upper bank, double load it. * CS_LP - select lower bank, double load it. */ switch (c) { case CS_LOAD: printf("cs80Memory(load)\n"); if (currentLayer == LOWER_BANK) off = 163; for (i = 0; i < 4;i++) { if (synth->mem.param[i + off] != 0) { b = i; break; } } if (currentLayer == LOWER_BANK) off = 167; else off = 151; for (i = 0; i < 10;i++) { if (synth->mem.param[i + off] != 0) { p = i; break; } } if (brightonDoubleClick(dc1)) cs80MemoryLoad(synth, currentLayer, b, p); else cs80MemoryLoadLayer(synth, currentLayer, b, p); break; case CS_SAVE: if (currentLayer == NO_BANK) return; if (brightonDoubleClick(dc1)) { printf("cs80Memory(save)\n"); if (currentLayer == LOWER_BANK) off = 163; for (i = 0; i < 4;i++) { if (synth->mem.param[i + off] != 0) { b = i; break; } } if (currentLayer == LOWER_BANK) off = 167; else off = 151; for (i = 0; i < 10;i++) { if (synth->mem.param[i + off] != 0) { p = i; break; } } cs80MemorySave(synth, currentLayer, b, p); } break; case CS_UB: printf("cs80Memory(ub, %i, %i)\n", c, o); currentLayer = UPPER_BANK; /* * Force exclusion */ if (synth->dispatch[RADIO_UB].other2) { synth->dispatch[RADIO_UB].other2 = 0; return; } o += RADIO_UB; if (v == 0) { if (synth->dispatch[RADIO_UB].other1 == o) { event.value = 1; brightonParamChange(synth->win, 1, o, &event); } return; } if (synth->dispatch[RADIO_UB].other1 != -1) { synth->dispatch[RADIO_UB].other2 = 1; if (synth->dispatch[RADIO_UB].other1 != o) event.value = 0; else event.value = 1; brightonParamChange(synth->win, 1, synth->dispatch[RADIO_UB].other1, &event); } synth->dispatch[RADIO_UB].other1 = o; break; case CS_LB: currentLayer = LOWER_BANK; printf("cs80Memory(lb)\n"); /* * Force exclusion */ if (synth->dispatch[RADIO_LB].other2) { synth->dispatch[RADIO_LB].other2 = 0; return; } o += RADIO_LB; if (v == 0) { if (synth->dispatch[RADIO_LB].other1 == o) { event.value = 1; brightonParamChange(synth->win, 1, o, &event); } return; } if (synth->dispatch[RADIO_LB].other1 != -1) { synth->dispatch[RADIO_LB].other2 = 1; if (synth->dispatch[RADIO_LB].other1 != o) event.value = 0; else event.value = 1; brightonParamChange(synth->win, 1, synth->dispatch[RADIO_LB].other1, &event); } synth->dispatch[RADIO_LB].other1 = o; break; case CS_UP: currentLayer = UPPER_BANK; printf("cs80Memory(up)\n"); /* * Force exclusion */ if (synth->dispatch[RADIO_UP].other2) { synth->dispatch[RADIO_UP].other2 = 0; return; } o += RADIO_UP; if (v == 0) { if (synth->dispatch[RADIO_UP].other1 == o) { event.value = 1; brightonParamChange(synth->win, 1, o, &event); } return; } if (synth->dispatch[RADIO_UP].other1 != -1) { synth->dispatch[RADIO_UP].other2 = 1; if (synth->dispatch[RADIO_UP].other1 != o) event.value = 0; else event.value = 1; brightonParamChange(synth->win, 1, synth->dispatch[RADIO_UP].other1, &event); } synth->dispatch[RADIO_UP].other1 = o; break; case CS_LP: currentLayer = LOWER_BANK; printf("cs80Memory(lp)\n"); /* * Force exclusion */ if (synth->dispatch[RADIO_LP].other2) { synth->dispatch[RADIO_LP].other2 = 0; return; } o += RADIO_LP; if (v == 0) { if (synth->dispatch[RADIO_LP].other1 == o) { event.value = 1; brightonParamChange(synth->win, 1, o, &event); } return; } if (synth->dispatch[RADIO_LP].other1 != -1) { synth->dispatch[RADIO_LP].other2 = 1; if (synth->dispatch[RADIO_LP].other1 != o) event.value = 0; else event.value = 1; brightonParamChange(synth->win, 1, synth->dispatch[RADIO_LP].other1, &event); } synth->dispatch[RADIO_LP].other1 = o; break; default: currentLayer = NO_BANK; printf("cs80Memory(?)\n"); break; } } static void cs80Midi(guiSynth *synth, int fd, int chan, int c, int o, int v) { int newchan; if ((synth->flags & OPERATIONAL) == 0) return; if (c == 1) { if ((newchan = synth->midichannel - 1) < 0) newchan = synth->midichannel = 0; } else { /* * This is a little incorrect - if we are layered then we can go to * midi channel 15. */ if ((newchan = synth->midichannel + 1) >= 14) newchan = synth->midichannel = 14; } if (global.libtest == 0) { bristolMidiSendMsg(global.controlfd, synth->sid2, 127, 0, (BRISTOL_MIDICHANNEL|newchan) + 1); bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_MIDICHANNEL|newchan); } synth->midichannel = newchan; } /* * For the sake of ease of use, links have been placed here to be called * by any of the devices created. They would be better in some other file, * perhaps with this as a dispatch. * * Param refers to the device index in the locations table given below. */ static int cs80Callback(brightonWindow * win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); int sendvalue; if ((synth == 0) || (synth->flags & SUPPRESS)) return(0); if (cs80Debug(synth, 2)) printf("cs80Callback(%i, %i, %f)\n", panel, index, value); printf("cs80Callback(%i, %i, %f)\n", panel, index, value); if (panel == 0) { index += 80; sendvalue = value * C_RANGE_MIN_1; } else if (panel == 3) { index += 133; sendvalue = value * C_RANGE_MIN_1; } else { if (cs80App.resources[panel].devlocn[index].to == 1.0) sendvalue = value * C_RANGE_MIN_1; else sendvalue = value; } /* * If the index is less than LAYER_DEVS then write the value to the desired * layer only, otherwise write the value to both/top layers? */ synth->mem.param[index] = value; /* if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0)) return(0); */ synth->dispatch[index].routine(synth, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); return(0); } static void cs80WaveLevel(guiSynth *synth, int fd, int chan, int c, int o, int v) { if (v != 0) { if (c == 1) { /* CH-I */ if (o == 0) { if (synth->mem.param[3] == 0) v = 0; else v = synth->mem.param[80] * C_RANGE_MIN_1; } else { if (synth->mem.param[4] == 0) v = 0; else v = synth->mem.param[81] * C_RANGE_MIN_1; } } else { /* CH-II */ if (o == 0) { if (synth->mem.param[29] == 0) v = 0; else v = synth->mem.param[96] * C_RANGE_MIN_1; } else { if (synth->mem.param[30] == 0) v = 0; else v = synth->mem.param[97] * C_RANGE_MIN_1; } } } printf("%i %i %i\n", c, o, v); bristolMidiSendMsg(global.controlfd, synth->sid, c, o, v); } static void cs80Release(guiSynth *synth, int fd, int chan, int c, int o, int v) { switch (c) { case 4: v = synth->mem.param[134] * synth->mem.param[14] * C_RANGE_MIN_1; break; case 5: v = synth->mem.param[134] * synth->mem.param[20] * C_RANGE_MIN_1; break; case 10: v = synth->mem.param[134] * synth->mem.param[40] * C_RANGE_MIN_1; break; case 11: v = synth->mem.param[134] * synth->mem.param[46] * C_RANGE_MIN_1; break; case 126: bristolMidiSendMsg(global.controlfd, synth->sid, 4, 4, (int) (synth->mem.param[134] * synth->mem.param[14] * C_RANGE_MIN_1)); bristolMidiSendMsg(global.controlfd, synth->sid, 5, 3, (int) (synth->mem.param[134] * synth->mem.param[20] * C_RANGE_MIN_1)); bristolMidiSendMsg(global.controlfd, synth->sid, 10, 4, (int) (synth->mem.param[134] * synth->mem.param[40] * C_RANGE_MIN_1)); bristolMidiSendMsg(global.controlfd, synth->sid, 11, 3, (int) (synth->mem.param[134] * synth->mem.param[46] * C_RANGE_MIN_1)); return; } bristolMidiSendMsg(global.controlfd, synth->sid, c, o, v); } static void cs80Resonance(guiSynth *synth, int fd, int chan, int c, int o, int v) { switch (c) { case 2: v = synth->mem.param[71] * synth->mem.param[7] * C_RANGE_MIN_1; break; case 3: v = synth->mem.param[71] * synth->mem.param[9] * C_RANGE_MIN_1; break; case 8: v = synth->mem.param[71] * synth->mem.param[33] * C_RANGE_MIN_1; break; case 9: v = synth->mem.param[71] * synth->mem.param[35] * C_RANGE_MIN_1; break; case 126: bristolMidiSendMsg(global.controlfd, synth->sid, 2, 1, (int) (synth->mem.param[71] * synth->mem.param[7] * C_RANGE_MIN_1)); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 1, (int) (synth->mem.param[71] * synth->mem.param[9] * C_RANGE_MIN_1)); bristolMidiSendMsg(global.controlfd, synth->sid, 8, 1, (int) (synth->mem.param[71] * synth->mem.param[33] * C_RANGE_MIN_1)); bristolMidiSendMsg(global.controlfd, synth->sid, 9, 1, (int) (synth->mem.param[71] * synth->mem.param[35] * C_RANGE_MIN_1)); return; } bristolMidiSendMsg(global.controlfd, synth->sid, c, o, v); } static void cs80Pitchbend(guiSynth *synth, int fd, int chan, int c, int o, int v) { if (global.libtest) return; bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_EVENT_PITCH, 0, v); } static void cs80Detune(guiSynth *synth, int fd, int chan, int c, int o, int v) { int value = v / 50; if (o == 101) { if (!global.libtest) { bristolMidiSendNRP(global.controlfd, synth->sid, BRISTOL_NRP_DETUNE, value); } } else { /* * Channel 2 detune */ bristolMidiSendMsg(global.controlfd, synth->sid, 7, 6, v); } } /* * Any location initialisation required to run the callbacks. For bristol, this * will connect to the engine, and give it some base parameters. * May need to generate some application specific menus. * Will also then make specific requests to some of the devices to alter their * rendering. */ static int cs80Init(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); int i; if (synth == 0) { synth = findSynth(global.synths, 0); if (synth == 0) { printf("cannot init\n"); return(0); } } synth->win = win; printf("Initialise the cs80 link to bristol: %p\n", synth->win); scratch = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float)); synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float)); synth->mem.count = DEVICE_COUNT; synth->mem.active = ACTIVE_DEVS; synth->dispatch = (dispatcher *) brightonmalloc(DEVICE_COUNT * sizeof(dispatcher)); /* * We really want to have three connection mechanisms. These should be * 1. Unix named sockets. * 2. UDP sockets. * 3. MIDI pipe. */ if (!global.libtest) { if ((synth->sid = initConnection(&global, synth)) < 0) return(-1); } printf(" The SID are %i and %i\n", synth->sid, synth->sid2); for (i = 0; i < DEVICE_COUNT; i++) { /* Default all controllers to send a message that is ignored */ synth->dispatch[i].controller = 126; synth->dispatch[i].operator = 101; synth->dispatch[i].routine = (synthRoutine) cs80MidiSendMsg; } /* LFO */ synth->dispatch[0].controller = 0; synth->dispatch[0].operator = 0; synth->dispatch[1].controller = 126; synth->dispatch[1].operator = 24; synth->dispatch[2].controller = 1; synth->dispatch[2].operator = 5; /* Square on/off, ramp on/off - will need shim for level later */ synth->dispatch[3].controller = 1; synth->dispatch[3].operator = 0; synth->dispatch[3].routine = (synthRoutine) cs80WaveLevel; synth->dispatch[4].controller = 1; synth->dispatch[4].operator = 1; synth->dispatch[4].routine = (synthRoutine) cs80WaveLevel; synth->dispatch[5].controller = 126; synth->dispatch[5].operator = 26; /* Noise level */ synth->dispatch[6].controller = 2; synth->dispatch[6].operator = 0; synth->dispatch[7].controller = 2; synth->dispatch[7].operator = 1; synth->dispatch[7].routine = (synthRoutine) cs80Resonance; synth->dispatch[8].controller = 3; synth->dispatch[8].operator = 0; synth->dispatch[9].controller = 3; synth->dispatch[9].operator = 1; synth->dispatch[9].routine = (synthRoutine) cs80Resonance; synth->dispatch[10].controller = 4; synth->dispatch[10].operator = 0; synth->dispatch[11].controller = 4; synth->dispatch[11].operator = 1; synth->dispatch[12].controller = 4; synth->dispatch[12].operator = 2; synth->dispatch[13].controller = 4; synth->dispatch[13].operator = 3; synth->dispatch[14].controller = 4; synth->dispatch[14].operator = 4; synth->dispatch[14].routine = (synthRoutine) cs80Release; synth->dispatch[15].controller = 126; synth->dispatch[15].operator = 28; /* Sine level */ synth->dispatch[16].controller = 1; synth->dispatch[16].operator = 2; synth->dispatch[17].controller = 5; synth->dispatch[17].operator = 0; synth->dispatch[18].controller = 5; synth->dispatch[18].operator = 1; synth->dispatch[19].controller = 5; synth->dispatch[19].operator = 2; synth->dispatch[20].controller = 5; synth->dispatch[20].operator = 3; synth->dispatch[20].routine = (synthRoutine) cs80Release; synth->dispatch[21].controller = 5; synth->dispatch[21].operator = 4; /* Brill/Vol */ synth->dispatch[22].controller = 126; synth->dispatch[22].operator = 11; synth->dispatch[23].controller = 126; synth->dispatch[23].operator = 12; synth->dispatch[24].controller = 126; synth->dispatch[24].operator = 13; synth->dispatch[25].controller = 126; synth->dispatch[25].operator = 14; synth->dispatch[26].controller = 6; synth->dispatch[26].operator = 0; synth->dispatch[27].controller = 126; synth->dispatch[27].operator = 25; /* PW */ synth->dispatch[28].controller = 7; synth->dispatch[28].operator = 5; /* Sqr/Rmp on off will need shim for level */ synth->dispatch[29].controller = 7; synth->dispatch[29].operator = 0; synth->dispatch[29].routine = (synthRoutine) cs80WaveLevel; synth->dispatch[30].controller = 7; synth->dispatch[30].operator = 1; synth->dispatch[30].routine = (synthRoutine) cs80WaveLevel; synth->dispatch[31].controller = 126; synth->dispatch[31].operator = 27; /* Noise level */ synth->dispatch[32].controller = 8; synth->dispatch[32].operator = 0; synth->dispatch[33].controller = 8; synth->dispatch[33].operator = 1; synth->dispatch[33].routine = (synthRoutine) cs80Resonance; synth->dispatch[34].controller = 9; synth->dispatch[34].operator = 0; synth->dispatch[35].controller = 9; synth->dispatch[35].operator = 1; synth->dispatch[35].routine = (synthRoutine) cs80Resonance; synth->dispatch[36].controller = 10; synth->dispatch[36].operator = 0; synth->dispatch[37].controller = 10; synth->dispatch[37].operator = 1; synth->dispatch[38].controller = 10; synth->dispatch[38].operator = 2; synth->dispatch[39].controller = 10; synth->dispatch[39].operator = 3; synth->dispatch[40].controller = 10; synth->dispatch[40].operator = 4; synth->dispatch[40].routine = (synthRoutine) cs80Release; synth->dispatch[41].controller = 126; synth->dispatch[41].operator = 29; /* CH-II Sine */ synth->dispatch[42].controller = 7; synth->dispatch[42].operator = 2; synth->dispatch[43].controller = 11; synth->dispatch[43].operator = 0; synth->dispatch[44].controller = 11; synth->dispatch[44].operator = 1; synth->dispatch[45].controller = 11; synth->dispatch[45].operator = 2; synth->dispatch[46].controller = 11; synth->dispatch[46].operator = 3; synth->dispatch[46].routine = (synthRoutine) cs80Release; synth->dispatch[47].controller = 11; synth->dispatch[47].operator = 4; /* Brill/Vol */ synth->dispatch[48].controller = 126; synth->dispatch[48].operator = 15; synth->dispatch[49].controller = 126; synth->dispatch[49].operator = 16; synth->dispatch[50].controller = 126; synth->dispatch[50].operator = 17; synth->dispatch[51].controller = 126; synth->dispatch[51].operator = 18; /* Channel-2 detune */ synth->dispatch[52].controller = 126; synth->dispatch[52].operator = 100; synth->dispatch[52].routine = (synthRoutine) cs80Detune; synth->dispatch[53].controller = 126; synth->dispatch[53].operator = 101; synth->dispatch[54].controller = 126; synth->dispatch[54].operator = 101; synth->dispatch[55].controller = 126; synth->dispatch[55].operator = 101; synth->dispatch[56].controller = 126; synth->dispatch[56].operator = 101; synth->dispatch[57].controller = 126; synth->dispatch[57].operator = 101; /* LFO */ synth->dispatch[58].controller = 126; synth->dispatch[58].operator = 20; /* Rate. Add in Key sync as global option if desired */ synth->dispatch[59].controller = 15; synth->dispatch[59].operator = 0; synth->dispatch[60].controller = 126; synth->dispatch[60].operator = 21; synth->dispatch[61].controller = 126; synth->dispatch[61].operator = 22; synth->dispatch[62].controller = 126; synth->dispatch[62].operator = 23; /* Osc transpose */ synth->dispatch[63].controller = 1; synth->dispatch[63].operator = 7; synth->dispatch[64].controller = 7; synth->dispatch[64].operator = 7; synth->dispatch[65].controller = 126; synth->dispatch[65].operator = 101; synth->dispatch[66].controller = 126; synth->dispatch[66].operator = 101; synth->dispatch[67].controller = 126; synth->dispatch[67].operator = 101; synth->dispatch[68].controller = 126; synth->dispatch[68].operator = 101; /* Channel level */ synth->dispatch[69].controller = 126; synth->dispatch[69].operator = 5; /* Overall brilliance */ synth->dispatch[70].controller = 126; synth->dispatch[70].operator = 6; synth->dispatch[71].controller = 126; synth->dispatch[71].operator = 101; synth->dispatch[71].routine = (synthRoutine) cs80Resonance; synth->dispatch[72].controller = 126; synth->dispatch[72].operator = 101; synth->dispatch[73].controller = 126; synth->dispatch[73].operator = 101; synth->dispatch[74].controller = 126; synth->dispatch[74].operator = 101; synth->dispatch[75].controller = 126; synth->dispatch[75].operator = 101; /* Key spreading Brill/Level */ synth->dispatch[76].controller = 126; synth->dispatch[76].operator = 7; synth->dispatch[77].controller = 126; synth->dispatch[77].operator = 8; synth->dispatch[78].controller = 126; synth->dispatch[78].operator = 9; synth->dispatch[79].controller = 126; synth->dispatch[79].operator = 10; /* 16x CH-I controls starting with Square gain, Tri gain and two brill */ synth->dispatch[80].controller = 1; synth->dispatch[80].operator = 0; synth->dispatch[80].routine = (synthRoutine) cs80WaveLevel; synth->dispatch[81].controller = 1; synth->dispatch[81].operator = 1; synth->dispatch[81].routine = (synthRoutine) cs80WaveLevel; synth->dispatch[82].controller = 1; synth->dispatch[82].operator = 3; synth->dispatch[83].controller = 1; synth->dispatch[83].operator = 4; synth->dispatch[84].controller = 126; synth->dispatch[84].operator = 30; /* filter brill */ synth->dispatch[85].controller = 126; synth->dispatch[85].operator = 3; /* Pan */ synth->dispatch[86].controller = 126; synth->dispatch[86].operator = 101; synth->dispatch[87].controller = 126; synth->dispatch[87].operator = 101; synth->dispatch[88].controller = 126; synth->dispatch[88].operator = 101; synth->dispatch[89].controller = 126; synth->dispatch[89].operator = 101; synth->dispatch[90].controller = 126; synth->dispatch[90].operator = 101; synth->dispatch[91].controller = 126; synth->dispatch[91].operator = 101; synth->dispatch[92].controller = 126; synth->dispatch[92].operator = 101; synth->dispatch[93].controller = 126; synth->dispatch[93].operator = 101; synth->dispatch[94].controller = 126; synth->dispatch[94].operator = 101; synth->dispatch[95].controller = 126; synth->dispatch[95].operator = 101; /* 16x CH-II controls starting with Square gain, Tri gain and two brill */ synth->dispatch[96].controller = 7; synth->dispatch[96].operator = 0; synth->dispatch[96].routine = (synthRoutine) cs80WaveLevel; synth->dispatch[97].controller = 7; synth->dispatch[97].operator = 1; synth->dispatch[97].routine = (synthRoutine) cs80WaveLevel; synth->dispatch[98].controller = 7; synth->dispatch[98].operator = 3; synth->dispatch[99].controller = 7; synth->dispatch[99].operator = 4; synth->dispatch[100].controller = 126; synth->dispatch[100].operator = 31; /* Filter brill */ synth->dispatch[101].controller = 126; synth->dispatch[101].operator = 4; /* Pan */ synth->dispatch[102].controller = 126; synth->dispatch[102].operator = 101; synth->dispatch[103].controller = 126; synth->dispatch[103].operator = 101; synth->dispatch[104].controller = 126; synth->dispatch[104].operator = 101; synth->dispatch[105].controller = 126; synth->dispatch[105].operator = 101; synth->dispatch[106].controller = 126; synth->dispatch[106].operator = 101; synth->dispatch[107].controller = 126; synth->dispatch[107].operator = 101; synth->dispatch[108].controller = 126; synth->dispatch[108].operator = 101; synth->dispatch[109].controller = 126; synth->dispatch[109].operator = 101; synth->dispatch[110].controller = 126; synth->dispatch[110].operator = 101; synth->dispatch[111].controller = 126; synth->dispatch[111].operator = 101; /* 16x global controls */ synth->dispatch[112].controller = 126; synth->dispatch[112].operator = 101; synth->dispatch[112].routine = (synthRoutine) cs80Detune; synth->dispatch[113].controller = 126; synth->dispatch[113].operator = 101; synth->dispatch[114].controller = 126; synth->dispatch[114].operator = 101; synth->dispatch[115].controller = 126; synth->dispatch[115].operator = 101; synth->dispatch[116].controller = 126; synth->dispatch[116].operator = 101; synth->dispatch[117].controller = 126; synth->dispatch[117].operator = 101; synth->dispatch[118].controller = 126; synth->dispatch[118].operator = 101; synth->dispatch[119].controller = 126; synth->dispatch[119].operator = 101; synth->dispatch[120].controller = 126; synth->dispatch[120].operator = 101; synth->dispatch[121].controller = 126; synth->dispatch[121].operator = 101; synth->dispatch[122].controller = 126; synth->dispatch[122].operator = 101; synth->dispatch[123].controller = 126; synth->dispatch[123].operator = 101; synth->dispatch[124].controller = 126; synth->dispatch[124].operator = 101; synth->dispatch[125].controller = 126; synth->dispatch[125].operator = 101; synth->dispatch[126].controller = 126; synth->dispatch[126].operator = 101; synth->dispatch[127].controller = 126; synth->dispatch[127].operator = 101; /* A few dummies */ synth->dispatch[128].controller = 126; synth->dispatch[128].operator = 101; synth->dispatch[129].controller = 126; synth->dispatch[129].operator = 101; synth->dispatch[130].controller = 126; synth->dispatch[130].operator = 101; synth->dispatch[131].controller = 126; synth->dispatch[131].operator = 101; synth->dispatch[132].controller = 126; synth->dispatch[132].operator = 101; /* Mods panel */ synth->dispatch[133].controller = 126; synth->dispatch[133].operator = 101; synth->dispatch[134].controller = 126; synth->dispatch[134].operator = 101; synth->dispatch[134].routine = (synthRoutine) cs80Release; synth->dispatch[135].controller = 126; synth->dispatch[135].operator = 101; synth->dispatch[136].controller = 126; synth->dispatch[136].operator = 101; synth->dispatch[137].controller = 126; synth->dispatch[137].operator = 101; synth->dispatch[138].controller = 126; synth->dispatch[138].operator = 101; synth->dispatch[139].controller = 126; synth->dispatch[139].operator = 101; synth->dispatch[140].controller = 126; synth->dispatch[140].operator = 101; synth->dispatch[141].controller = 126; synth->dispatch[141].operator = 101; synth->dispatch[142].controller = 126; synth->dispatch[142].operator = 101; synth->dispatch[143].controller = 126; synth->dispatch[143].operator = 101; synth->dispatch[144].controller = 126; synth->dispatch[144].operator = 101; /* Global tune and gain */ synth->dispatch[145].controller = 126; synth->dispatch[145].operator = 1; synth->dispatch[146].controller = 126; synth->dispatch[146].operator = 2; synth->dispatch[147].controller = CS_UB; synth->dispatch[147].operator = 0; synth->dispatch[147].routine = (synthRoutine) cs80Memory; synth->dispatch[148].controller = CS_UB; synth->dispatch[148].operator = 1; synth->dispatch[148].routine = (synthRoutine) cs80Memory; synth->dispatch[149].controller = CS_UB; synth->dispatch[149].operator = 2; synth->dispatch[149].routine = (synthRoutine) cs80Memory; synth->dispatch[150].controller = CS_UB; synth->dispatch[150].operator = 3; synth->dispatch[150].routine = (synthRoutine) cs80Memory; synth->dispatch[151].controller = CS_UP; synth->dispatch[151].operator = 0; synth->dispatch[151].routine = (synthRoutine) cs80Memory; synth->dispatch[152].controller = CS_UP; synth->dispatch[152].operator = 1; synth->dispatch[152].routine = (synthRoutine) cs80Memory; synth->dispatch[153].controller = CS_UP; synth->dispatch[153].operator = 2; synth->dispatch[153].routine = (synthRoutine) cs80Memory; synth->dispatch[154].controller = CS_UP; synth->dispatch[154].operator = 3; synth->dispatch[154].routine = (synthRoutine) cs80Memory; synth->dispatch[155].controller = CS_UP; synth->dispatch[155].operator = 4; synth->dispatch[155].routine = (synthRoutine) cs80Memory; synth->dispatch[156].controller = CS_UP; synth->dispatch[156].operator = 5; synth->dispatch[156].routine = (synthRoutine) cs80Memory; synth->dispatch[157].controller = CS_UP; synth->dispatch[157].operator = 6; synth->dispatch[157].routine = (synthRoutine) cs80Memory; synth->dispatch[158].controller = CS_UP; synth->dispatch[158].operator = 7; synth->dispatch[158].routine = (synthRoutine) cs80Memory; synth->dispatch[159].controller = CS_UP; synth->dispatch[159].operator = 8; synth->dispatch[159].routine = (synthRoutine) cs80Memory; synth->dispatch[160].controller = CS_UP; synth->dispatch[160].operator = 9; synth->dispatch[160].routine = (synthRoutine) cs80Memory; synth->dispatch[161].controller = CS_LOAD; synth->dispatch[161].operator = 0; synth->dispatch[161].routine = (synthRoutine) cs80Memory; synth->dispatch[163].controller = CS_LB; synth->dispatch[163].operator = 0; synth->dispatch[163].routine = (synthRoutine) cs80Memory; synth->dispatch[164].controller = CS_LB; synth->dispatch[164].operator = 1; synth->dispatch[164].routine = (synthRoutine) cs80Memory; synth->dispatch[165].controller = CS_LB; synth->dispatch[165].operator = 2; synth->dispatch[165].routine = (synthRoutine) cs80Memory; synth->dispatch[166].controller = CS_LB; synth->dispatch[166].operator = 3; synth->dispatch[166].routine = (synthRoutine) cs80Memory; synth->dispatch[167].controller = CS_LP; synth->dispatch[167].operator = 0; synth->dispatch[167].routine = (synthRoutine) cs80Memory; synth->dispatch[168].controller = CS_LP; synth->dispatch[168].operator = 1; synth->dispatch[168].routine = (synthRoutine) cs80Memory; synth->dispatch[169].controller = CS_LP; synth->dispatch[169].operator = 2; synth->dispatch[169].routine = (synthRoutine) cs80Memory; synth->dispatch[170].controller = CS_LP; synth->dispatch[170].operator = 3; synth->dispatch[170].routine = (synthRoutine) cs80Memory; synth->dispatch[171].controller = CS_LP; synth->dispatch[171].operator = 4; synth->dispatch[171].routine = (synthRoutine) cs80Memory; synth->dispatch[172].controller = CS_LP; synth->dispatch[172].operator = 5; synth->dispatch[172].routine = (synthRoutine) cs80Memory; synth->dispatch[173].controller = CS_LP; synth->dispatch[173].operator = 6; synth->dispatch[173].routine = (synthRoutine) cs80Memory; synth->dispatch[174].controller = CS_LP; synth->dispatch[174].operator = 7; synth->dispatch[174].routine = (synthRoutine) cs80Memory; synth->dispatch[175].controller = CS_LP; synth->dispatch[175].operator = 8; synth->dispatch[175].routine = (synthRoutine) cs80Memory; synth->dispatch[176].controller = CS_LP; synth->dispatch[176].operator = 9; synth->dispatch[176].routine = (synthRoutine) cs80Memory; synth->dispatch[177].controller = CS_SAVE; synth->dispatch[177].operator = 0; synth->dispatch[177].routine = (synthRoutine) cs80Memory; synth->dispatch[178].controller = 126; synth->dispatch[178].operator = 101; synth->dispatch[179].routine = (synthRoutine) cs80Pitchbend; /* Tune CH-1 */ bristolMidiSendMsg(global.controlfd, synth->sid, 1, 6, CONTROLLER_RANGE/2); bristolMidiSendMsg(global.controlfd, synth->sid, 7, 6, CONTROLLER_RANGE/2); /* PWM LFO Key Sync */ bristolMidiSendMsg(global.controlfd, synth->sid, 0, 1, 1); bristolMidiSendMsg(global.controlfd, synth->sid, 6, 1, 1); /* No touch on Filter env, HP filt, mods */ bristolMidiSendMsg(global.controlfd, synth->sid, 4, 5, 0); bristolMidiSendMsg(global.controlfd, synth->sid, 10, 5, 0); bristolMidiSendMsg(global.controlfd, synth->sid, 2, 6, 2); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 6, 0); bristolMidiSendMsg(global.controlfd, synth->sid, 8, 6, 2); bristolMidiSendMsg(global.controlfd, synth->sid, 9, 6, 0); bristolMidiSendMsg(global.controlfd, synth->sid, 2, 2, C_RANGE_MIN_1); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 2, C_RANGE_MIN_1); bristolMidiSendMsg(global.controlfd, synth->sid, 8, 2, C_RANGE_MIN_1); bristolMidiSendMsg(global.controlfd, synth->sid, 9, 2, C_RANGE_MIN_1); /* Noise gain */ bristolMidiSendMsg(global.controlfd, synth->sid, 15, 0, 8192); return(0); } /* * This will be called to make any routine specific parameters available. */ static int cs80Configure(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); brightonEvent event; if (synth == 0) { printf("problems going operational\n"); return(-1); } if (synth->flags & OPERATIONAL) return(0); printf("going operational\n"); synth->keypanel = KEY_PANEL; if (synth->location == 0) { synth->bank = 10; synth->location = 1; } else if (synth->location > 0) { if ((mw = synth->location / 10) == 0) synth->bank = 10; else { synth->bank = mw % 10; mw -= synth->bank; mw *= 10; synth->bank *= 10; } if ((synth->location = (synth->location % 10)) == 0) synth->location = 1; } if (cs80Debug(synth, 2)) printf("weight %i, bank %i, mem %i\n", mw, synth->bank,synth->location); configureGlobals(synth); synth->keypanel2 = -1; synth->transpose = 24; synth->flags |= OPERATIONAL; dc1 = brightonGetDCTimer(win->dcTimeout); /* * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only * occurs on first paint, so we suppress the first paint, and then request * an expose here. */ event.type = BRIGHTON_EXPOSE; event.intvalue = 1; brightonParamChange(synth->win, KEY_PANEL, -1, &event); brightonParamChange(synth->win, KEY_PANEL + 2, -1, &event); /* Push some radio buttons to set their starting point */ event.value = 1.0; synth->dispatch[RADIO_UB].other1 = RADIO_UB; synth->dispatch[RADIO_LB].other1 = RADIO_LB; synth->dispatch[RADIO_UP].other1 = RADIO_UP; synth->dispatch[RADIO_LP].other1 = RADIO_LP; brightonParamChange(synth->win, 1, RADIO_UB, &event); brightonParamChange(synth->win, 1, RADIO_LB, &event); brightonParamChange(synth->win, 1, RADIO_UP, &event); brightonParamChange(synth->win, 1, RADIO_LP, &event); brightonPut(win, "bitmaps/blueprints/cs80shade.xpm", 0, 0, win->width, win->height); width = win->width; /* Then set some defaults for volume, balance and tuning */ event.type = BRIGHTON_FLOAT; event.value = 0.9; brightonParamChange(synth->win, 1, 146, &event); event.value = 0.5; brightonParamChange(synth->win, 1, 145, &event); event.value = 1.0; /* On/Off switch for Opts panel */ brightonParamChange(synth->win, 4, 0, &event); /* Then set the load button twice to get a memory loaded */ cs80MemoryLoad(synth, 0, 0, 0); if (cs80Debug(synth, 3)) printf("dct = %i\n", win->dcTimeout); return(0); } bristol-0.60.11/brighton/brightonSolina.c0000644000175000017500000006175611746476475015264 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include #include "brighton.h" #include "brightonMini.h" #include "brightoninternals.h" static int solinaInit(); static int solinaConfigure(); static int solinaCallback(brightonWindow *, int, int, float); static int midiCallback(brightonWindow *, int, int, float); extern guimain global; static int dc, shade_id; #include "brightonKeys.h" #define OPTS_PANEL 0 #define MOD_PANEL 1 #define KEY_PANEL 2 #define FX_PANEL 4 #define MEM_PANEL 5 #define OPTS_COUNT 16 #define FX_COUNT 1 #define MOD_COUNT 16 #define MEM_COUNT 14 #define OPTS_START 0 #define FX_START OPTS_COUNT #define MOD_START (FX_START + FX_COUNT) #define MEM_START (MOD_COUNT + MOD_START) #define ACTIVE_DEVS (MOD_COUNT + FX_COUNT + OPTS_COUNT) #define DEVICE_COUNT (ACTIVE_DEVS + MEM_COUNT) /* * This structure is for device definition. The structure is defined in * include/brighton.h, further definitions in brighton/brightonDevtable.h and * include/brightoninternals.h * * typedef int (*brightonCallback)(int, float); * typedef struct BrightonLocations { * int device; 0=rotary, 1=scale, etc. * float relx, rely; relative position with regards to 1000 by 1000 window * float relw, relh; relative height. * int from, to; * brightonCallback callback; specific to this dev * char *image; bitmap. If zero take a device default. * int flags; * } brightonLocations; * * This example is for a solinaBristol type synth interface. */ #define R1 400 #define W1 75 #define W2 20 #define L1 300 #define L2 250 #define C0 310 #define C1 355 #define C2 380 #define C3 410 #define C4 500 #define C5 590 #define C6 680 #define C7 760 #define C8 785 #define C9 810 #define C10 835 static brightonLocations panelControls[OPTS_COUNT] = { {"BassString", 2, C1, R1, W2, L2, 0, 1, 0, "bitmaps/buttons/solinaOff.xpm", "bitmaps/buttons/solinaOn.xpm", 0}, {"BassHorn", 2, C2, R1, W2, L2, 0, 1, 0, "bitmaps/buttons/solinaOff.xpm", "bitmaps/buttons/solinaOn.xpm", 0}, {"BassGain", 1, C3, R1, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderred.xpm", 0, BRIGHTON_VERTICAL|BRIGHTON_REVERSE}, {"Tuning", 1, C4, R1, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderred.xpm", 0, BRIGHTON_VERTICAL|BRIGHTON_NOTCH|BRIGHTON_REVERSE}, {"Crescendo", 1, C5, R1, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderred.xpm", 0, BRIGHTON_VERTICAL|BRIGHTON_REVERSE}, {"Sustain", 1, C6, R1, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderred.xpm", 0, BRIGHTON_VERTICAL|BRIGHTON_REVERSE}, {"String-16", 2, C7, R1, W2, L2, 0, 1, 0, "bitmaps/buttons/solinaOff.xpm", "bitmaps/buttons/solinaOn.xpm", 0}, {"Horn-16", 2, C9, R1, W2, L2, 0, 1, 0, "bitmaps/buttons/solinaOff.xpm", "bitmaps/buttons/solinaOn.xpm", 0}, {"String-8", 2, C8, R1, W2, L2, 0, 1, 0, "bitmaps/buttons/solinaOff.xpm", "bitmaps/buttons/solinaOn.xpm", 0}, {"Horn-8", 2, C10, R1, W2, L2, 0, 1, 0, "bitmaps/buttons/solinaOff.xpm", "bitmaps/buttons/solinaOn.xpm", 0}, {"MasterVolume", 0, C0, R1 - 100, 400, 400, 0, 1, 0, 0, 0, 0}, {"", 0, C0, R1 - 100, 400, 400, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 0, C0, R1 - 100, 400, 400, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 0, C0, R1 - 100, 400, 400, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 0, C0, R1 - 100, 400, 400, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 0, C0, R1 - 100, 400, 400, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, }; #define S1 200 #define oW1 20 #define oL1 700 #define oC1 39 #define oC2 103 #define oC3 152 #define oC4 203 #define oC5 280 #define oC6 330 #define oC7 742 #define oC8 790 #define oC9 842 #define oC10 891 #define oC11 942 #define oC12 600 #define oC13 650 #define oC14 700 #define oC15 510 #define oC16 560 #define oR1 100 #define oR2 300 #define oR3 500 #define oR4 700 static brightonLocations options[MOD_COUNT] = { {"Chorus-D1", 1, oC7, oR1, oW1, oL1, 0, 1, 0, "bitmaps/knobs/sliderred.xpm", 0, 0}, {"Chorus-D1", 1, oC8, oR1, oW1, oL1, 0, 1, 0, "bitmaps/knobs/sliderred.xpm", 0, 0}, {"Chorus-Speed", 1, oC9, oR1, oW1, oL1, 0, 1, 0, "bitmaps/knobs/sliderred.xpm", 0, 0}, {"On Wet/Dry", 1, oC10, oR1, oW1, oL1, 0, 1, 0, "bitmaps/knobs/sliderred.xpm", 0, 0}, {"Off Wet/Dry", 1, oC11, oR1, oW1, oL1, 0, 1, 0, "bitmaps/knobs/sliderred.xpm", 0, 0}, {"Osc Detune", 1, oC2, oR1, oW1, oL1, 0, 1, 0, "bitmaps/knobs/sliderred.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_NOTCH}, {"PulseWidth", 1, oC3, oR1, oW1, oL1, 0, 1, 0, "bitmaps/knobs/sliderred.xpm", 0, 0}, /* The remaining envelope parameters */ {"Decay", 1, oC5, oR1, oW1, oL1, 0, 1, 0, "bitmaps/knobs/sliderred.xpm", 0, 0}, {"Sustain", 1, oC6, oR1, oW1, oL1, 0, 1, 0, "bitmaps/knobs/sliderred.xpm", 0, 0}, /* These should be PWM and LFO, and LFO to OSC? */ {"PulseWidthMod", 1, oC4, oR1, oW1, oL1, 0, 1, 0, "bitmaps/knobs/sliderred.xpm", 0, 0}, {"LFO Rate", 1, oC1, oR1, oW1, oL1, 0, 1, 0, "bitmaps/knobs/sliderred.xpm", 0, 0}, /* Reverb */ {"Reverb Feedback", 1, oC12, oR1, oW1, oL1, 0, 1, 0, "bitmaps/knobs/sliderred.xpm", 0, 0}, {"Reverb Crossover", 1, oC13, oR1, oW1, oL1, 0, 1, 0, "bitmaps/knobs/sliderred.xpm", 0, 0}, {"Reverb Depth", 1, oC14, oR1, oW1, oL1, 0, 1, 0, "bitmaps/knobs/sliderred.xpm", 0, 0}, /* Vibrato and tremelo */ {"Vibraro", 1, oC15, oR1, oW1, oL1, 0, 1, 0, "bitmaps/knobs/sliderred.xpm", 0, 0}, {"Tremelo", 1, oC16, oR1, oW1, oL1, 0, 1, 0, "bitmaps/knobs/sliderred.xpm", 0, 0}, }; #define mR1 200 #define mR2 450 #define mR3 700 #define mC1 100 #define mC2 283 #define mC3 466 #define mC4 649 #define mC5 835 #define mC11 100 #define mC12 255 #define mC13 410 #define mC14 565 #define mC15 720 #define mC16 874 #define S3 100 #define S4 80 #define S5 120 #define S6 150 static brightonLocations mem[MEM_COUNT] = { /* memories */ {"", 2, mC1, mR1, S3, S5, 0, 1, 0, "bitmaps/buttons/solinaOff.xpm", "bitmaps/buttons/solinaOn.xpm", 0}, {"", 2, mC2, mR1, S3, S5, 0, 1, 0, "bitmaps/buttons/solinaOff.xpm", "bitmaps/buttons/solinaOn.xpm", 0}, {"", 2, mC3, mR1, S3, S5, 0, 1, 0, "bitmaps/buttons/solinaOff.xpm", "bitmaps/buttons/solinaOn.xpm", 0}, {"", 2, mC4, mR1, S3, S5, 0, 1, 0, "bitmaps/buttons/solinaOff.xpm", "bitmaps/buttons/solinaOn.xpm", 0}, {"", 2, mC5, mR1, S3, S5, 0, 1, 0, "bitmaps/buttons/solinaOff.xpm", "bitmaps/buttons/solinaOn.xpm", 0}, {"", 2, mC1, mR2, S3, S5, 0, 1, 0, "bitmaps/buttons/solinaOff.xpm", "bitmaps/buttons/solinaOn.xpm", 0}, {"", 2, mC2, mR2, S3, S5, 0, 1, 0, "bitmaps/buttons/solinaOff.xpm", "bitmaps/buttons/solinaOn.xpm", 0}, {"", 2, mC3, mR2, S3, S5, 0, 1, 0, "bitmaps/buttons/solinaOff.xpm", "bitmaps/buttons/solinaOn.xpm", 0}, {"", 2, mC4, mR2, S3, S5, 0, 1, 0, "bitmaps/buttons/solinaOff.xpm", "bitmaps/buttons/solinaOn.xpm", 0}, {"", 2, mC5, mR2, S3, S5, 0, 1, 0, "bitmaps/buttons/solinaOff.xpm", "bitmaps/buttons/solinaOn.xpm", 0}, /* mem U/D, midi U/D, Load + Save */ {"", 2, mC1, mR3, S4, S6, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, mC2, mR3, S4, S6, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, mC5, mR3, S4, S6, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, mC3, mR3, S4, S6, 0, 1, 0, "bitmaps/buttons/pressoffo.xpm", "bitmaps/buttons/pressono.xpm", BRIGHTON_CHECKBUTTON}, }; static brightonLocations fx[FX_COUNT] = { {"FX on/off", 2, 300, 400, 400, 150, 0, 1, 0, "bitmaps/buttons/solinaOff.xpm", "bitmaps/buttons/solinaOn.xpm", 0}, }; /* * Should try and make this one as generic as possible, and try to use it as * a general memory routine. has Midi u/d, mem u/d, load/save and a display. */ static int memCallback(brightonWindow* win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); /* printf("memCallback(%i, %i, %f) %i, %s\n", panel, index, value, */ /* synth->mem.active, synth->resources->name); */ if (synth->flags & SUPPRESS) return(0); /* * The first ten buttons are exclusive highlighting, we use the first mem * pointer to handle this. */ if (synth->dispatch[MEM_START].other2) { synth->dispatch[MEM_START].other2 = 0; return(0); } if (index == 13) { if (brightonDoubleClick(dc)) { synth->location = synth->dispatch[MEM_START].other1; saveMemory(synth, "solina", 0, synth->bank + synth->location, 0); } return(0); } if (index < 10) { int i; brightonEvent event; event.command = BRIGHTON_PARAMCHANGE; event.type = BRIGHTON_FLOAT; event.value = 0; /* * This is a numeric. We need to force exclusion. */ if (synth->dispatch[MEM_START].other1 != -1) { synth->dispatch[MEM_START].other2 = 1; if (synth->dispatch[MEM_START].other1 != index) event.value = 0; else event.value = 1; brightonParamChange(synth->win, panel, synth->dispatch[MEM_START].other1, &event); } synth->location = index; loadMemory(synth, "solina", 0, synth->bank + synth->location, synth->mem.active, 0, BRISTOL_NOCALLS|BRISTOL_FORCE); /* * We have loaded the memory but cannot call the devices as they have * various panels. */ for (i = 0; i < OPTS_COUNT; i++) { event.value = synth->mem.param[i]; brightonParamChange(synth->win, OPTS_PANEL, i, &event); } event.value = synth->mem.param[i]; brightonParamChange(synth->win, FX_PANEL, 0, &event); for (; i < ACTIVE_DEVS; i++) { event.value = synth->mem.param[i]; brightonParamChange(synth->win, MOD_PANEL, i - MOD_START, &event); } synth->dispatch[MEM_START].other1 = index; } else { int newchan; /* * This is a control button. */ switch(index) { case 10: /* * Midi Down */ if ((newchan = synth->midichannel - 1) < 0) { synth->midichannel = 0; return(0); } if (global.libtest) { printf("midi chan %i\n", newchan); synth->midichannel = newchan; return(0); } bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_MIDICHANNEL|newchan); synth->midichannel = newchan; break; case 11: /* * Midi Up */ if ((newchan = synth->midichannel + 1) > 15) { synth->midichannel = 15; return(0); } if (global.libtest) { printf("midi chan %i\n", newchan); synth->midichannel = newchan; return(0); } bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_MIDICHANNEL|newchan); synth->midichannel = newchan; break; } } return(0); } /* * This is a set of globals for the main window rendering. Again taken from * include/brighton.h */ brightonApp solinaApp = { "solina", 0, /* no blueprint on wood background. */ "bitmaps/textures/metal5.xpm", BRIGHTON_STRETCH, solinaInit, solinaConfigure, /* 3 callbacks */ midiCallback, destroySynth, {-1, 0, 2, 2, 5, 520, 0, 0}, 600, 200, 0, 0, 8, /* panel count */ { { "Mods", "bitmaps/blueprints/solinapanel.xpm", "bitmaps/textures/metal6.xpm", /* flags */ BRIGHTON_STRETCH|BRIGHTON_VERTICAL|BRIGHTON_REVERSE, 0, 0, solinaCallback, 15, 390, 970, 180, OPTS_COUNT, panelControls }, { "Opts", "bitmaps/blueprints/solinamods.xpm", "bitmaps/textures/metal5.xpm", /* flags */ 0x020, 0, 0, solinaCallback, 17, 9, 967, 381, MOD_COUNT, options }, { "Keyboard", 0, "bitmaps/keys/kbg.xpm", /* flags */ 0x020|BRIGHTON_STRETCH, 0, 0, keyCallback, 187, 580, 740, 400, KEY_COUNT_4OCTAVE, keys4octave }, { "Solina", 0, "bitmaps/textures/wood6.xpm", 0, /* flags */ 0, 0, 0, 17, 9, 967, 381, 0, 0 }, { "Effects switch", 0, "bitmaps/textures/metal5.xpm", 0, 0, 0, solinaCallback, 930, 570, 53, 400, FX_COUNT, fx }, { "Memory Panel", 0, "bitmaps/textures/metal5.xpm", 0, 0, 0, solinaCallback, 17, 570, 168, 400, MEM_COUNT, mem }, { "Wood Side", 0, "bitmaps/textures/wood.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 0, 0, 15, 1000, 0, 0 }, { "Wood Side", 0, "bitmaps/textures/wood.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 985, 0, 15, 1000, 0, 0 }, } }; /*static dispatcher dispatch[DEVICE_COUNT]; */ static int midiCallback(brightonWindow *win, int controller, int value, float n) { guiSynth *synth = findSynth(global.synths, win); printf("midi callback: %x, %i\n", controller, value); switch(controller) { case MIDI_PROGRAM: printf("midi program: %x, %i\n", controller, value); synth->location = value; loadMemory(synth, synth->resources->name, 0, synth->bank + synth->location, synth->mem.active, 0, 0); break; case MIDI_BANK_SELECT: printf("midi banksel: %x, %i\n", controller, value); synth->bank = value; break; } return(0); } static void panelSwitch(guiSynth *id, int fd, int chan, int cont, int op, int value) { brightonEvent event; /* * If the sendvalue is zero, then withdraw the opts window, draw the * slider window, and vice versa. */ if (value == 0) { event.type = BRIGHTON_EXPOSE; event.intvalue = 0; brightonParamChange(id->win, 1, -1, &event); event.intvalue = 1; brightonParamChange(id->win, 3, -1, &event); shade_id = brightonPut(id->win, "bitmaps/blueprints/solinashade.xpm", 0, 0, id->win->width, id->win->height); } else { event.type = BRIGHTON_EXPOSE; event.intvalue = 0; brightonParamChange(id->win, 3, -1, &event); event.intvalue = 1; brightonParamChange(id->win, 1, -1, &event); brightonRemove(id->win, shade_id); } } static int solinaMidiNull(void *synth, int fd, int chan, int c, int o, int v) { /* printf("%i, %i, %i\n", c, o, v); */ return(0); } static int solinaMidiDetune(guiSynth *synth, int fd, int chan, int c, int o, int v) { if ((v = 8192 - v) >= 8192) v = 8191; if (v <= -8191) v = -8191; bristolMidiSendMsg(global.controlfd, synth->sid, 0, 2, 8192); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 2, 8192 + v); bristolMidiSendMsg(global.controlfd, synth->sid, 2, 2, 8192 - v); return(0); } static int solinaMidiPW(guiSynth *synth, int fd, int chan, int c, int o, int v) { bristolMidiSendMsg(global.controlfd, synth->sid, 0, 0, v / 2); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 0, v * 3 / 4); bristolMidiSendMsg(global.controlfd, synth->sid, 2, 0, v); return(0); } static int solinaMidiFX(guiSynth *synth, int fd, int chan, int c, int o, int v) { /* * See if the effect is turned on. If so change the wet dry, otherwise * set wet/dry to 0 */ if (synth->mem.param[FX_START] == 0.0) { bristolMidiSendMsg(fd, chan, 98, 3, (int) (synth->mem.param[MOD_START + 4] * C_RANGE_MIN_1)); bristolMidiSendMsg(fd, chan, 99, 3, (int) (synth->mem.param[MOD_START + 4] * C_RANGE_MIN_1)); } else { bristolMidiSendMsg(fd, chan, 98, 3, (int) (synth->mem.param[MOD_START + 3] * C_RANGE_MIN_1)); bristolMidiSendMsg(fd, chan, 99, 3, (int) (synth->mem.param[MOD_START + 3] * C_RANGE_MIN_1)); } return(0); } static int solinaMidiSendMsg(void *synth, int fd, int chan, int c, int o, int v) { /* printf("%i, %i, %i\n", c, o, v); */ bristolMidiSendMsg(fd, chan, c, o, v); return(0); } /* * For the sake of ease of use, links have been placed here to be called * by any of the devices created. They would be better in some other file, * perhaps with this as a dispatch. * * Param refers to the device index in the locations table given below. */ static int solinaCallback(brightonWindow *win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); int sendvalue; if (synth == 0) return(0); if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0)) return(0); if (solinaApp.resources[panel].devlocn[index].to == 1) sendvalue = value * C_RANGE_MIN_1; else sendvalue = value; switch (panel) { case OPTS_PANEL: break; case FX_PANEL: index+=FX_START; break; case MOD_PANEL: index+=MOD_START; break; case MEM_PANEL: if (index == 12) panelSwitch(synth, 0, 0, 0, 0, value); else memCallback(win, panel, index, value); return(0); } synth->mem.param[index] = value; if ((!global.libtest) || (index >= ACTIVE_DEVS)) synth->dispatch[index].routine(synth, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #ifdef DEBUG else printf("dispatch[%p,%i](%i, %i, %i, %i, %i)\n", synth, index, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #endif return(0); } /* * Any location initialisation required to run the callbacks. For bristol, this * will connect to the engine, and give it some base parameters. * May need to generate some application specific menus. * Will also then make specific requests to some of the devices to alter their * rendering. */ static int solinaInit(brightonWindow* win) { guiSynth *synth = findSynth(global.synths, win); dispatcher *dispatch; int i; if (synth == 0) { synth = findSynth(global.synths, 0); if (synth == 0) { printf("cannot init\n"); return(0); } } synth->win = win; printf("Initialise the solina link to bristol: %p\n", synth->win); synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float)); synth->mem.count = DEVICE_COUNT; synth->mem.active = ACTIVE_DEVS; synth->dispatch = (dispatcher *) brightonmalloc(DEVICE_COUNT * sizeof(dispatcher)); dispatch = synth->dispatch; /* * We really want to have three connection mechanisms. These should be * 1. Unix named sockets. * 2. UDP sockets. * 3. MIDI pipe. */ if (!global.libtest) if ((synth->sid = initConnection(&global, synth)) < 0) return(-1); for (i = 0; i < DEVICE_COUNT; i++) synth->dispatch[i].routine = solinaMidiNull; /* Bass oscillator */ synth->dispatch[OPTS_START + 0].controller = 126; /* harmonic mix */ synth->dispatch[OPTS_START + 0].operator = 14; synth->dispatch[OPTS_START + 1].controller = 126; synth->dispatch[OPTS_START + 1].operator = 15; synth->dispatch[OPTS_START + 2].controller = 2; synth->dispatch[OPTS_START + 2].operator = 3; synth->dispatch[OPTS_START + 3].controller = 126; /* Global tune */ synth->dispatch[OPTS_START + 3].operator = 1; synth->dispatch[OPTS_START + 4].controller = 3; /* Env - 2 parameters */ synth->dispatch[OPTS_START + 4].operator = 0; synth->dispatch[OPTS_START + 5].controller = 3; synth->dispatch[OPTS_START + 5].operator = 3; synth->dispatch[OPTS_START + 6].controller = 126; /* Harmonics - 4 params */ synth->dispatch[OPTS_START + 6].operator = 10; synth->dispatch[OPTS_START + 7].controller = 126; synth->dispatch[OPTS_START + 7].operator = 11; synth->dispatch[OPTS_START + 8].controller = 126; synth->dispatch[OPTS_START + 8].operator = 12; synth->dispatch[OPTS_START + 9].controller = 126; synth->dispatch[OPTS_START + 9].operator = 13; synth->dispatch[OPTS_START + 10].controller = 3; /* Volume */ synth->dispatch[OPTS_START + 10].operator = 4; /* Volume */ synth->dispatch[OPTS_START + 0].routine = synth->dispatch[OPTS_START + 1].routine = synth->dispatch[OPTS_START + 2].routine = synth->dispatch[OPTS_START + 3].routine = synth->dispatch[OPTS_START + 4].routine = synth->dispatch[OPTS_START + 5].routine = synth->dispatch[OPTS_START + 6].routine = synth->dispatch[OPTS_START + 7].routine = synth->dispatch[OPTS_START + 8].routine = synth->dispatch[OPTS_START + 9].routine = synth->dispatch[OPTS_START + 10].routine = solinaMidiSendMsg; synth->dispatch[FX_START + 0].controller = 98; /* Effects wet/dry */ synth->dispatch[FX_START + 0].operator = 3; synth->dispatch[MOD_START + 0].routine = synth->dispatch[MOD_START + 1].routine = synth->dispatch[MOD_START + 2].routine = synth->dispatch[MOD_START + 3].routine = synth->dispatch[MOD_START + 4].routine = synth->dispatch[MOD_START + 7].routine = synth->dispatch[MOD_START + 8].routine = synth->dispatch[MOD_START + 9].routine = synth->dispatch[MOD_START + 10].routine = synth->dispatch[MOD_START + 11].routine = synth->dispatch[MOD_START + 12].routine = synth->dispatch[MOD_START + 13].routine = synth->dispatch[MOD_START + 14].routine = synth->dispatch[MOD_START + 15].routine = solinaMidiSendMsg; synth->dispatch[MOD_START + 0].controller = 98; /* Effects */ synth->dispatch[MOD_START + 0].operator = 0; synth->dispatch[MOD_START + 1].controller = 98; /* Effects */ synth->dispatch[MOD_START + 1].operator = 1; synth->dispatch[MOD_START + 2].controller = 98; /* Effects */ synth->dispatch[MOD_START + 2].operator = 2; synth->dispatch[MOD_START + 3].controller = 98; /* Effects */ synth->dispatch[MOD_START + 3].operator = 3; synth->dispatch[MOD_START + 4].controller = 98; /* Effects */ synth->dispatch[MOD_START + 4].operator = 3; synth->dispatch[MOD_START + 11].controller = 99; /* Effects */ synth->dispatch[MOD_START + 11].operator = 0; synth->dispatch[MOD_START + 12].controller = 99; /* Effects */ synth->dispatch[MOD_START + 12].operator = 1; synth->dispatch[MOD_START + 13].controller = 99; /* Effects */ synth->dispatch[MOD_START + 13].operator = 2; synth->dispatch[MOD_START + 14].controller = 126; /* Vib */ synth->dispatch[MOD_START + 14].operator = 7; synth->dispatch[MOD_START + 15].controller = 126; /* Trem */ synth->dispatch[MOD_START + 15].operator = 8; synth->dispatch[MOD_START + 5].routine = (synthRoutine) solinaMidiDetune; synth->dispatch[MOD_START + 6].routine = (synthRoutine) solinaMidiPW; synth->dispatch[MOD_START + 3].routine = synth->dispatch[MOD_START + 4].routine = synth->dispatch[FX_START + 0].routine = (synthRoutine) solinaMidiFX; synth->dispatch[MOD_START + 7].controller = 3; /* Env - 2 parameters */ synth->dispatch[MOD_START + 7].operator = 1; synth->dispatch[MOD_START + 8].controller = 3; synth->dispatch[MOD_START + 8].operator = 2; synth->dispatch[MOD_START + 9].controller = 126; /* PWM and LFO */ synth->dispatch[MOD_START + 9].operator = 3; synth->dispatch[MOD_START + 10].controller = 5; synth->dispatch[MOD_START + 10].operator = 0; /* * These will be replaced by some opts controllers. We need to tie the * envelope parameters for decay, sustain. We need to fix a few parameters * of the oscillators too - transpose, tune and gain. */ bristolMidiSendMsg(global.controlfd, synth->sid, 3, 1, 10); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 2, 16382); /* Oscillators */ bristolMidiSendMsg(global.controlfd, synth->sid, 0, 3, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 3, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 1, 3); bristolMidiSendMsg(global.controlfd, synth->sid, 2, 1, 1); return(0); } /* * This will be called to make any routine specific parameters available. */ static int solinaConfigure(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); brightonEvent event; if (synth == 0) { printf("problems going operational\n"); return(-1); } if (synth->flags & OPERATIONAL) return(0); printf("going operational\n"); synth->flags |= OPERATIONAL; synth->keypanel = 2; synth->keypanel2 = -1; synth->transpose = 36; loadMemory(synth, "solina", 0, synth->location, synth->mem.active, 0, 0); /* * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only * occurs on first paint, so we suppress the first paint, and then request * an expose here. */ event.type = BRIGHTON_EXPOSE; event.intvalue = 1; brightonParamChange(synth->win, KEY_PANEL, -1, &event); configureGlobals(synth); shade_id = brightonPut(synth->win, "bitmaps/blueprints/solinashade.xpm", 0, 0, synth->win->width, synth->win->height); /* Fix the pulsewidths of the first two osc */ bristolMidiSendMsg(global.controlfd, synth->sid, 0, 0, 8192); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 0, 4096); /* detune all oscs just a small amount */ bristolMidiSendMsg(global.controlfd, synth->sid, 0, 2, 8192); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 2, 8292); bristolMidiSendMsg(global.controlfd, synth->sid, 2, 2, 8092); /* Disable velocity tracking */ bristolMidiSendMsg(global.controlfd, synth->sid, 3, 5, 0); /* Configure a split point */ bristolMidiSendMsg(global.controlfd, synth->sid, 126, 5, 47); bristolMidiSendMsg(global.controlfd, synth->sid, 126, 6, 35); event.command = BRIGHTON_PARAMCHANGE; event.type = BRIGHTON_FLOAT; event.value = 1; brightonParamChange(synth->win, MEM_PANEL, 0, &event); event.command = BRIGHTON_PARAMCHANGE; event.type = BRIGHTON_FLOAT; event.value = 0; brightonParamChange(synth->win, KEY_PANEL, 0, &event); dc = brightonGetDCTimer(win->dcTimeout); return(0); } bristol-0.60.11/brighton/brightonMaster.c0000644000175000017500000007140311746476475015260 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include #include "brighton.h" #include "brightonMini.h" #include "brightoninternals.h" static int masterInit(); static int masterConfigure(); static int masterCallback(brightonWindow * , int, int, float); static int masterMidiCallback(brightonWindow * , int, int, float); extern guimain global; #include "brightonKeys.h" #define BLUEPRINT "bitmaps/blueprints/master7.xpm" #define OP_COUNT 6 #define FIRST_DEV 0 #define PARAM_COUNT 20 #define ALGOS_COUNT 29 #define MEM_COUNT 17 #define ACTIVE_DEVS (PARAM_COUNT * OP_COUNT + ALGOS_COUNT + FIRST_DEV) #define DISPLAY_DEV (MEM_COUNT - 3) #define DISPLAY_PANEL 7 #define OP_START FIRST_DEV #define OP1_START FIRST_DEV #define OP2_START (OP1_START + PARAM_COUNT) #define OP3_START (OP2_START + PARAM_COUNT) #define OP4_START (OP3_START + PARAM_COUNT) #define OP5_START (OP4_START + PARAM_COUNT) #define OP6_START (OP5_START + PARAM_COUNT) #define ALGO_START (PARAM_COUNT * OP_COUNT + FIRST_DEV) #define MEM_START ACTIVE_DEVS #define OP_PANEL 0 #define ALGOS_PANEL OP_COUNT #define MEM_PANEL (ALGOS_PANEL + 1) #define KEY_PANEL 1 #define DEVICE_COUNT (ACTIVE_DEVS + MEM_COUNT) /* * This structure is for device definition. The structure is defined in * include/brighton.h, further definitions in brighton/brightonDevtable.h and * include/brightoninternals.h * * typedef int (*brightonCallback)(int, float); * typedef struct BrightonLocations { * int device; 0=rotary, 1=scale, etc. * float relx, rely; relative position with regards to 1000 by 1000 window * float relw, relh; relative height. * int from, to; * brightonCallback callback; specific to this dev * char *image; bitmap. If zero take a device default. * int flags; * } brightonLocations; * * This example is for a masterBristol type synth interface. */ #define R1 150 #define R2 665 #define S1 300 #define S2 40 #define S3 250 #define D2 50 #define S4 45 #define S5 250 #define AR1 150 #define AR2 425 #define AR3 700 #define AC0 50 #define AC1 (AC0 + D2) #define AC2 (AC1 + D2) #define AC3 (AC2 + D2) #define AC4 (AC3 + D2) #define AC5 (AC4 + D2) #define AC6 (AC5 + D2) #define AC7 (AC6 + D2) #define AC8 (AC7 + D2 + 253) #define AC9 (AC8 + D2 + 142) #define AC10 (AC9 + D2 + 10) static brightonLocations algopanel[ALGOS_COUNT] = { {"", 2, AC0, AR1, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, AC1, AR1, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, AC2, AR1, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, AC3, AR1, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, AC4, AR1, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, AC5, AR1, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, AC6, AR1, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, AC7, AR1, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, AC0, AR2, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, AC1, AR2, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, AC2, AR2, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, AC3, AR2, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, AC4, AR2, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, AC5, AR2, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, AC6, AR2, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, AC7, AR2, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, AC0, AR3, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, AC1, AR3, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, AC2, AR3, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, AC3, AR3, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, AC4, AR3, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, AC5, AR3, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, AC6, AR3, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, AC7, AR3, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, AC9, R1 + 40, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 4, AC7 + 90, AR1, 190, 800, 0, 1, 0, 0, 0, 0}, }; /* * This is a set of globals for the main window rendering. Again taken from * include/brighton.h */ brightonApp masterApp = { "master", 0, /* no blueprint on wood background. */ "bitmaps/textures/metal6.xpm", BRIGHTON_STRETCH, masterInit, masterConfigure, /* 3 callbacks, unused? */ masterMidiCallback, destroySynth, {8, 0, 2, 2, 5, 520, 0, 0}, 1000, 300, 0, 0, 8, { { "MASTER", "bitmaps/blueprints/masteralgo.xpm", "bitmaps/textures/metal5.xpm", 0, /* flags */ 0, 0, masterCallback, 25, 40, 310, 530, ALGOS_COUNT, algopanel }, { "Keyboard", 0, "bitmaps/newkeys/dkbg.xpm", /* flags */ 0x020|BRIGHTON_STRETCH, 0, 0, keyCallback, 110, 615, 870, 380, KEY_COUNT_6_OCTAVE, keys6octave }, { "MASTER", "bitmaps/blueprints/masteralgo.xpm", "bitmaps/textures/metal5.xpm", 0, /* flags */ 0, 0, masterCallback, 350, 40, 310, 530, ALGOS_COUNT, algopanel }, { "Mods", "bitmaps/blueprints/mods.xpm", "bitmaps/textures/metal5.xpm", // flags */ 0, 0, 0, modCallback, 15, 615, 95, 380, 2, mods }, /* Wood rim */ { "Wood", 0, "bitmaps/textures/wood2.xpm", 0, 0, 0, 0, 0, 0, 15, 1000, 0, 0 }, { "Wood", 0, "bitmaps/textures/wood2.xpm", 0, 0, 0, 0, 985, 0, 15, 1000, 0, 0 }, { "Wood", 0, "bitmaps/textures/wood.xpm", 0, 0, 0, 0, 1, 5, 13, 980, 0, 0 }, { "Wood", 0, "bitmaps/textures/wood.xpm", 0, 0, 0, 0, 986, 5, 13, 980, 0, 0 }, } }; /*static dispatcher dispatch[DEVICE_COUNT]; */ static int masterMidiSendMsg(void *synth, int fd, int chan, int c, int o, int v) { /*printf("%i, %i, %i\n", c, o, v); */ bristolMidiSendMsg(fd, chan, c, o, v); return(0); } int masterLoadMem(guiSynth *synth, char *algo, char *name, int location, int active, int skip, int flags) { brightonEvent event; int op; float mo, fmop[OP_COUNT][2]; /* * See if the memory actually exists. This is a bit of file system overhead * but prevents attempting to load non-existant memories */ op = loadMemory(synth, algo, name, location, active, skip, BRISTOL_STAT); if (flags == 2) return(op); if (op < 0) return(op); event.type = BRIGHTON_FLOAT; event.value = 0.0; /* * Zero out diverse gain functions to prevent a noisy transition. * What happens is that as the parameters change and the algorithm alters * we get a LOT of FM noise. We can dump this by zeroing the output * parameters. We have to be careful, since if the memory does not load, * for example it does not exist, then we have to reset the parameters * afterwards. * * Start with main out. */ mo = synth->mem.param[OP_COUNT * PARAM_COUNT + 26]; brightonParamChange(synth->win, ALGOS_PANEL, 26, &event); for (op = 0; op < 6; op++) { /* * Output gain */ fmop[op][0] = synth->mem.param[op * PARAM_COUNT]; brightonParamChange(synth->win, op, 0, &event); /* * Input gain */ fmop[op][1] = synth->mem.param[op * PARAM_COUNT + 3]; brightonParamChange(synth->win, op, 3, &event); } if (loadMemory(synth, algo, name, location, active, skip, flags) == 0) return(0); /* * Load failed, return the gain parameters to their previous values. */ event.value = mo; brightonParamChange(synth->win, ALGOS_PANEL, 26, &event); for (op = 0; op < 6; op++) { /* * Output gain */ event.value = fmop[op][0]; brightonParamChange(synth->win, op, 0, &event); /* * Input gain */ event.value = fmop[op][1]; brightonParamChange(synth->win, op, 3, &event); } return(-1); } static int masterMidiCallback(brightonWindow *win, int command, int value, float v) { guiSynth *synth = findSynth(global.synths, win); printf("midi callback: %x, %i\n", command, value); switch(command) { case MIDI_PROGRAM: printf("midi program: %x, %i\n", command, value); synth->location = value; masterLoadMem(synth, "master", 0, synth->location, synth->mem.active, FIRST_DEV, 0); break; case MIDI_BANK_SELECT: printf("midi banksel: %x, %i\n", command, value); synth->bank = value; break; } return(0); } static void masterMemory(guiSynth *synth, int fd, int chan, int c, int o, int v) { switch (c) { default: case 0: synth->location = synth->location * 10 + o; if (synth->location >= 1000) synth->location = o; if (masterLoadMem(synth, "master", 0, synth->location, synth->mem.active, FIRST_DEV, BRISTOL_STAT) < 0) displayPanelText(synth, "FRE", synth->location, DISPLAY_PANEL, DISPLAY_DEV); else displayPanelText(synth, "PRG", synth->location, DISPLAY_PANEL, DISPLAY_DEV); break; case 1: if (masterLoadMem(synth, "master", 0, synth->location, synth->mem.active, FIRST_DEV, 0) < 0) displayPanelText(synth, "FRE", synth->location, DISPLAY_PANEL, DISPLAY_DEV); else displayPanelText(synth, "PRG", synth->location, DISPLAY_PANEL, DISPLAY_DEV); break; case 2: saveMemory(synth, "master", 0, synth->location, FIRST_DEV); displayPanelText(synth, "PRG", synth->location, DISPLAY_PANEL, DISPLAY_DEV); break; case 3: while (masterLoadMem(synth, "master", 0, --synth->location, synth->mem.active, FIRST_DEV, 0) < 0) { if (synth->location < 0) synth->location = 999; } displayPanelText(synth, "PRG", synth->location, DISPLAY_PANEL, DISPLAY_DEV); break; case 4: while (masterLoadMem(synth, "master", 0, ++synth->location, synth->mem.active, FIRST_DEV, 0) < 0) { if (synth->location > 999) synth->location = -1; } displayPanelText(synth, "PRG", synth->location, DISPLAY_PANEL, DISPLAY_DEV); break; } } static int masterMidi(guiSynth *synth, int fd, int chan, int c, int o, int v) { int newchan; if ((synth->flags & OPERATIONAL) == 0) return(0); if (c == 1) { if ((newchan = synth->midichannel - 1) < 0) { synth->midichannel = 0; return(0); } } else { if ((newchan = synth->midichannel + 1) >= 16) { synth->midichannel = 15; return(0); } } if (global.libtest == 0) { bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_MIDICHANNEL|newchan); } synth->midichannel = newchan; displayPanelText(synth, "MIDI", synth->midichannel + 1, DISPLAY_PANEL, DISPLAY_DEV); return(0); } /* * For the sake of ease of use, links have been placed here to be called * by any of the devices created. They would be better in some other file, * perhaps with this as a dispatch. * * Param refers to the device index in the locations table given below. */ static int masterCallback(brightonWindow * win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); int sendvalue; if (synth == 0) return(0); if (masterApp.resources[panel].devlocn[index].to == 1) sendvalue = value * C_RANGE_MIN_1; else sendvalue = value; switch (panel) { case OP_PANEL: case OP_PANEL + 1: case OP_PANEL + 2: case OP_PANEL + 3: case OP_PANEL + 4: case OP_PANEL + 5: index += panel * PARAM_COUNT; break; case ALGOS_PANEL: index += ALGO_START; break; case MEM_PANEL: index += MEM_START; break; default: printf("unknown panel\n"); break; } if ((synth->flags & OPERATIONAL) == 0) return(0); /* printf("masterCallback(%i, %f): %x\n", index, value, synth); */ synth->mem.param[index] = value; synth->dispatch[index].routine(synth, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #ifdef DEBUG else printf("dispatch[%p,%i](%i, %i, %i, %i, %i)\n", synth, index, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #endif return(0); } static void masterAlgo(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; /* printf("masterAlgo(%x, %i, %i, %i, %i, %i): %i\n", */ /* synth, fd, chan, c, o, v, synth->mem.param[v - 1]); */ /* * These will be radio buttons */ if (synth->dispatch[ALGO_START].other2) { synth->dispatch[ALGO_START].other2 = 0; return; } if (v == 0) return; if (synth->dispatch[ALGO_START].other1 >= 0) { synth->dispatch[ALGO_START].other2 = 1; if (synth->dispatch[ALGO_START].other1 != o) event.value = 0; else event.value = 1; /*printf("other one is %i\n", synth->dispatch[ALGO_START].other1); */ brightonParamChange(synth->win, ALGOS_PANEL, synth->dispatch[ALGO_START].other1, &event); } if (v != 0) { char bitmap[128]; event.type = BRIGHTON_MEM; sprintf(bitmap, "bitmaps/images/algo%i.xpm", o); event.m = bitmap; /*printf("%i %i: RECONFIGURING BITMAP\n", v, synth->mem.param[ALGO_START + o]); */ brightonParamChange(synth->win, ALGOS_PANEL, ALGOS_COUNT - 1, &event); } bristolMidiSendMsg(global.controlfd, synth->sid, 126, 101, o); synth->dispatch[ALGO_START].other1 = o; } static void masterTune(guiSynth *synth) { brightonEvent event; printf("masterTune(%p, %i, %i)\n", synth->win, OP_PANEL, OP1_START); event.value = 0.5; brightonParamChange(synth->win, 0, 1, &event); brightonParamChange(synth->win, 1, 1, &event); brightonParamChange(synth->win, 2, 1, &event); brightonParamChange(synth->win, 3, 1, &event); brightonParamChange(synth->win, 4, 1, &event); brightonParamChange(synth->win, 5, 1, &event); } /* * Any location initialisation required to run the callbacks. For bristol, this * will connect to the engine, and give it some base parameters. * May need to generate some application specific menus. * Will also then make specific requests to some of the devices to alter their * rendering. */ static int masterInit(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); dispatcher *dispatch; int i; /* brightonEvent event; char bitmap[128]; event.type = BRIGHTON_MEM; event.m = OP2XPM; brightonParamChange(synth->win, ALGOS_PANEL, ALGOS_COUNT - 1, &event); */ if (synth == 0) { synth = findSynth(global.synths, 0); if (synth == 0) { printf("cannot init\n"); return(0); } } synth->win = win; printf("Initialise the master link to bristol: %p\n", synth->win); synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float)); synth->mem.count = DEVICE_COUNT; synth->mem.active = ACTIVE_DEVS; synth->dispatch = (dispatcher *) brightonmalloc(DEVICE_COUNT * sizeof(dispatcher)); dispatch = synth->dispatch; /* * We really want to have three connection mechanisms. These should be * 1. Unix named sockets. * 2. UDP sockets. * 3. MIDI pipe. */ if (!global.libtest) if ((synth->sid = initConnection(&global, synth)) < 0) return(-1); for (i = 0; i < DEVICE_COUNT; i++) synth->dispatch[i].routine = masterMidiSendMsg; /* algo panel */ dispatch[ALGO_START].operator = 0; dispatch[ALGO_START + 1].operator = 1; dispatch[ALGO_START + 2].operator = 2; dispatch[ALGO_START + 3].operator = 3; dispatch[ALGO_START + 4].operator = 4; dispatch[ALGO_START + 5].operator = 5; dispatch[ALGO_START + 6].operator = 6; dispatch[ALGO_START + 7].operator = 7; dispatch[ALGO_START + 8].operator = 8; dispatch[ALGO_START + 9].operator = 9; dispatch[ALGO_START + 10].operator = 10; dispatch[ALGO_START + 11].operator = 11; dispatch[ALGO_START + 12].operator = 12; dispatch[ALGO_START + 13].operator = 13; dispatch[ALGO_START + 14].operator = 14; dispatch[ALGO_START + 15].operator = 15; dispatch[ALGO_START + 16].operator = 16; dispatch[ALGO_START + 17].operator = 17; dispatch[ALGO_START + 18].operator = 18; dispatch[ALGO_START + 19].operator = 19; dispatch[ALGO_START + 20].operator = 20; dispatch[ALGO_START + 21].operator = 21; dispatch[ALGO_START + 22].operator = 22; dispatch[ALGO_START + 23].operator = 23; dispatch[ALGO_START].routine = dispatch[ALGO_START + 1].routine = dispatch[ALGO_START + 2].routine = dispatch[ALGO_START + 3].routine = dispatch[ALGO_START + 4].routine = dispatch[ALGO_START + 5].routine = dispatch[ALGO_START + 6].routine = dispatch[ALGO_START + 7].routine = dispatch[ALGO_START + 8].routine = dispatch[ALGO_START + 9].routine = dispatch[ALGO_START + 10].routine = dispatch[ALGO_START + 11].routine = dispatch[ALGO_START + 12].routine = dispatch[ALGO_START + 13].routine = dispatch[ALGO_START + 14].routine = dispatch[ALGO_START + 15].routine = dispatch[ALGO_START + 16].routine = dispatch[ALGO_START + 17].routine = dispatch[ALGO_START + 18].routine = dispatch[ALGO_START + 19].routine = dispatch[ALGO_START + 20].routine = dispatch[ALGO_START + 21].routine = dispatch[ALGO_START + 22].routine = dispatch[ALGO_START + 23].routine = (synthRoutine) masterAlgo; dispatch[ALGO_START + 24].controller = 126; dispatch[ALGO_START + 24].operator = 99; dispatch[ALGO_START + 25].controller = 126; dispatch[ALGO_START + 25].operator = 100; dispatch[ALGO_START + 27].routine = (synthRoutine) masterTune; /* Main volume */ dispatch[ALGO_START + 26].controller = 126; dispatch[ALGO_START + 26].operator = 102; /* operator = 1 */ dispatch[OP1_START].controller = 126; dispatch[OP1_START].operator = 0; dispatch[OP1_START + 1].controller = 0; dispatch[OP1_START + 1].operator = 1; dispatch[OP1_START + 2].controller = 0; dispatch[OP1_START + 2].operator = 0; /* envelope */ dispatch[OP1_START + 5].controller = 0; dispatch[OP1_START + 5].operator = 2; dispatch[OP1_START + 6].controller = 0; dispatch[OP1_START + 6].operator = 3; dispatch[OP1_START + 7].controller = 0; dispatch[OP1_START + 7].operator = 4; dispatch[OP1_START + 8].controller = 0; dispatch[OP1_START + 8].operator = 5; dispatch[OP1_START + 3].controller = 0; dispatch[OP1_START + 3].operator = 6; dispatch[OP1_START + 9].controller = 0; dispatch[OP1_START + 9].operator = 7; dispatch[OP1_START + 4].controller = 126; dispatch[OP1_START + 4].operator = 1; dispatch[OP1_START + 10].controller = 126; dispatch[OP1_START + 10].operator = 2; dispatch[OP1_START + 11].controller = 126; dispatch[OP1_START + 11].operator = 3; dispatch[OP1_START + 12].controller = 0; dispatch[OP1_START + 12].operator = 9; /* L1-A-L2 */ dispatch[OP1_START + 13].controller = 0; dispatch[OP1_START + 13].operator = 10; dispatch[OP1_START + 14].controller = 0; dispatch[OP1_START + 14].operator = 11; dispatch[OP1_START + 15].controller = 0; dispatch[OP1_START + 15].operator = 12; /* operator = 2 */ dispatch[OP2_START].controller = 126; dispatch[OP2_START].operator = 10; dispatch[OP2_START + 1].controller = 1; dispatch[OP2_START + 1].operator = 1; dispatch[OP2_START + 2].controller = 1; dispatch[OP2_START + 2].operator = 0; /* envelope */ dispatch[OP2_START + 5].controller = 1; dispatch[OP2_START + 5].operator = 2; dispatch[OP2_START + 6].controller = 1; dispatch[OP2_START + 6].operator = 3; dispatch[OP2_START + 7].controller = 1; dispatch[OP2_START + 7].operator = 4; dispatch[OP2_START + 8].controller = 1; dispatch[OP2_START + 8].operator = 5; dispatch[OP2_START + 3].controller = 1; dispatch[OP2_START + 3].operator = 6; dispatch[OP2_START + 9].controller = 1; dispatch[OP2_START + 9].operator = 7; dispatch[OP2_START + 4].controller = 126; dispatch[OP2_START + 4].operator = 11; dispatch[OP2_START + 10].controller = 126; dispatch[OP2_START + 10].operator = 12; dispatch[OP2_START + 11].controller = 126; dispatch[OP2_START + 11].operator = 13; dispatch[OP2_START + 12].controller = 1; dispatch[OP2_START + 12].operator = 9; /* L1-A-L2 */ dispatch[OP2_START + 13].controller = 1; dispatch[OP2_START + 13].operator = 10; dispatch[OP2_START + 14].controller = 1; dispatch[OP2_START + 14].operator = 11; dispatch[OP2_START + 15].controller = 1; dispatch[OP2_START + 15].operator = 12; /* operator = 3 */ dispatch[OP3_START].controller = 126; dispatch[OP3_START].operator = 20; dispatch[OP3_START + 1].controller = 2; dispatch[OP3_START + 1].operator = 1; dispatch[OP3_START + 2].controller = 2; dispatch[OP3_START + 2].operator = 0; /* envelope */ dispatch[OP3_START + 5].controller = 2; dispatch[OP3_START + 5].operator = 2; dispatch[OP3_START + 6].controller = 2; dispatch[OP3_START + 6].operator = 3; dispatch[OP3_START + 7].controller = 2; dispatch[OP3_START + 7].operator = 4; dispatch[OP3_START + 8].controller = 2; dispatch[OP3_START + 8].operator = 5; dispatch[OP3_START + 3].controller = 2; dispatch[OP3_START + 3].operator = 6; dispatch[OP3_START + 9].controller = 2; dispatch[OP3_START + 9].operator = 7; dispatch[OP3_START + 4].controller = 126; dispatch[OP3_START + 4].operator = 21; dispatch[OP3_START + 10].controller = 126; dispatch[OP3_START + 10].operator = 22; dispatch[OP3_START + 11].controller = 126; dispatch[OP3_START + 11].operator = 23; dispatch[OP3_START + 12].controller = 2; dispatch[OP3_START + 12].operator = 9; /* L1-A-L2 */ dispatch[OP3_START + 13].controller = 2; dispatch[OP3_START + 13].operator = 10; dispatch[OP3_START + 14].controller = 2; dispatch[OP3_START + 14].operator = 11; dispatch[OP3_START + 15].controller = 2; dispatch[OP3_START + 15].operator = 12; /* operator = 4 */ dispatch[OP4_START].controller = 126; dispatch[OP4_START].operator = 30; dispatch[OP4_START + 1].controller = 3; dispatch[OP4_START + 1].operator = 1; dispatch[OP4_START + 2].controller = 3; dispatch[OP4_START + 2].operator = 0; /* envelope */ dispatch[OP4_START + 5].controller = 3; dispatch[OP4_START + 5].operator = 2; dispatch[OP4_START + 6].controller = 3; dispatch[OP4_START + 6].operator = 3; dispatch[OP4_START + 7].controller = 3; dispatch[OP4_START + 7].operator = 4; dispatch[OP4_START + 8].controller = 3; dispatch[OP4_START + 8].operator = 5; dispatch[OP4_START + 3].controller = 3; dispatch[OP4_START + 3].operator = 6; dispatch[OP4_START + 9].controller = 3; dispatch[OP4_START + 9].operator = 7; dispatch[OP4_START + 4].controller = 126; dispatch[OP4_START + 4].operator = 31; dispatch[OP4_START + 10].controller = 126; dispatch[OP4_START + 10].operator = 32; dispatch[OP4_START + 11].controller = 126; dispatch[OP4_START + 11].operator = 33; dispatch[OP4_START + 12].controller = 3; dispatch[OP4_START + 12].operator = 9; /* L1-A-L2 */ dispatch[OP4_START + 13].controller = 3; dispatch[OP4_START + 13].operator = 10; dispatch[OP4_START + 14].controller = 3; dispatch[OP4_START + 14].operator = 11; dispatch[OP4_START + 15].controller = 3; dispatch[OP4_START + 15].operator = 12; /* operator = 5 */ dispatch[OP5_START].controller = 126; dispatch[OP5_START].operator = 40; dispatch[OP5_START + 1].controller = 4; dispatch[OP5_START + 1].operator = 1; dispatch[OP5_START + 2].controller = 4; dispatch[OP5_START + 2].operator = 0; /* envelope */ dispatch[OP5_START + 5].controller = 4; dispatch[OP5_START + 5].operator = 2; dispatch[OP5_START + 6].controller = 4; dispatch[OP5_START + 6].operator = 3; dispatch[OP5_START + 7].controller = 4; dispatch[OP5_START + 7].operator = 4; dispatch[OP5_START + 8].controller = 4; dispatch[OP5_START + 8].operator = 5; dispatch[OP5_START + 3].controller = 4; dispatch[OP5_START + 3].operator = 6; dispatch[OP5_START + 9].controller = 4; dispatch[OP5_START + 9].operator = 7; dispatch[OP5_START + 4].controller = 126; dispatch[OP5_START + 4].operator = 41; dispatch[OP5_START + 10].controller = 126; dispatch[OP5_START + 10].operator = 42; dispatch[OP5_START + 11].controller = 126; dispatch[OP5_START + 11].operator = 43; dispatch[OP5_START + 12].controller = 4; dispatch[OP5_START + 12].operator = 9; /* L1-A-L2 */ dispatch[OP5_START + 13].controller = 4; dispatch[OP5_START + 13].operator = 10; dispatch[OP5_START + 14].controller = 4; dispatch[OP5_START + 14].operator = 11; dispatch[OP5_START + 15].controller = 4; dispatch[OP5_START + 15].operator = 12; /* operator = 6 */ dispatch[OP6_START].controller = 126; dispatch[OP6_START].operator = 50; dispatch[OP6_START + 1].controller = 5; dispatch[OP6_START + 1].operator = 1; dispatch[OP6_START + 2].controller = 5; dispatch[OP6_START + 2].operator = 0; /* envelope */ dispatch[OP6_START + 5].controller = 5; dispatch[OP6_START + 5].operator = 2; dispatch[OP6_START + 6].controller = 5; dispatch[OP6_START + 6].operator = 3; dispatch[OP6_START + 7].controller = 5; dispatch[OP6_START + 7].operator = 4; dispatch[OP6_START + 8].controller = 5; dispatch[OP6_START + 8].operator = 5; dispatch[OP6_START + 3].controller = 5; dispatch[OP6_START + 3].operator = 6; dispatch[OP6_START + 9].controller = 5; dispatch[OP6_START + 9].operator = 7; dispatch[OP6_START + 4].controller = 126; dispatch[OP6_START + 4].operator = 51; dispatch[OP6_START + 10].controller = 126; dispatch[OP6_START + 10].operator = 52; dispatch[OP6_START + 11].controller = 126; dispatch[OP6_START + 11].operator = 53; dispatch[OP6_START + 12].controller = 5; dispatch[OP6_START + 12].operator = 9; /* L1-A-L2 */ dispatch[OP6_START + 13].controller = 5; dispatch[OP6_START + 13].operator = 10; dispatch[OP6_START + 14].controller = 5; dispatch[OP6_START + 14].operator = 11; dispatch[OP6_START + 15].controller = 5; dispatch[OP6_START + 15].operator = 12; /* memories */ dispatch[MEM_START].operator = 0; dispatch[MEM_START + 1].operator = 1; dispatch[MEM_START + 2].operator = 2; dispatch[MEM_START + 3].operator = 3; dispatch[MEM_START + 4].operator = 4; dispatch[MEM_START + 5].operator = 5; dispatch[MEM_START + 6].operator = 6; dispatch[MEM_START + 7].operator = 7; dispatch[MEM_START + 8].operator = 8; dispatch[MEM_START + 9].operator = 9; dispatch[MEM_START].routine = dispatch[MEM_START + 1].routine = dispatch[MEM_START + 2].routine = dispatch[MEM_START + 3].routine = dispatch[MEM_START + 4].routine = dispatch[MEM_START + 5].routine = dispatch[MEM_START + 6].routine = dispatch[MEM_START + 7].routine = dispatch[MEM_START + 8].routine = dispatch[MEM_START + 9].routine = dispatch[MEM_START + 10].routine = dispatch[MEM_START + 11].routine = dispatch[MEM_START + 15].routine = dispatch[MEM_START + 16].routine = (synthRoutine) masterMemory; dispatch[MEM_START + 10].controller = 1; dispatch[MEM_START + 11].controller = 2; dispatch[MEM_START + 15].controller = 3; dispatch[MEM_START + 16].controller = 4; /* Midi */ dispatch[MEM_START + 12].controller = 2; dispatch[MEM_START + 13].controller = 1; dispatch[MEM_START + 12].routine = dispatch[MEM_START + 13].routine = (synthRoutine) masterMidi; return(0); } /* * This will be called to make any routine specific parameters available. */ static int masterConfigure(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); brightonEvent event; if (synth == 0) { printf("problems going operational\n"); return(-1); } if (synth->flags & OPERATIONAL) return(0); printf("going operational %p %p\n", synth, synth->win); synth->flags |= OPERATIONAL; synth->keypanel = KEY_PANEL; synth->keypanel2 = -1; synth->transpose = 24; synth->dispatch[ALGO_START].other2 = 0; synth->dispatch[ALGO_START].other1 = -1; masterLoadMem(synth, "master", 0, synth->location, synth->mem.active, FIRST_DEV, 0); brightonPut(win, "bitmaps/blueprints/mastershade.xpm", 0, 0, win->width, win->height); /* * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only * occurs on first paint, so we suppress the first paint, and then request * an expose here. */ event.type = BRIGHTON_EXPOSE; event.intvalue = 1; brightonParamChange(synth->win, KEY_PANEL, -1, &event); configureGlobals(synth); return(0); } bristol-0.60.11/brighton/brightonProOne.c0000644000175000017500000010650411746476475015230 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include #include "brighton.h" #include "brightonMini.h" #include "brightoninternals.h" static int initmem; static int pro1Init(); static int pro1Configure(); static int pro1Callback(brightonWindow *, int, int, float); /*static int keyCallback(void *, int, int, float); */ static int proOneKeyCallback(brightonWindow *, int, int, float); /*static int modCallback(void *, int, int, float); */ static int midiCallback(brightonWindow *, int, int, float); extern guimain global; static int seqLearn = 0; #include "brightonKeys.h" #define DEVICE_COUNT 72 #define ACTIVE_DEVS 52 #define DISPLAY_DEV (DEVICE_COUNT - 1) #define MEM_START (ACTIVE_DEVS + 2) // 54 #define KEY_PANEL 1 #define R1 150 #define R1S (R1 + 20) #define R2 (R1 + 245) #define R2S (R2 + 20) #define R3 (R2 + 245) #define R3S (R3 + 20) #define R4 (R3 + 275) #define RA (R1 - 38) #define RB (RA + 144) #define RC (RB + 142) #define RD (RC + 145) #define RE (RD + 144) #define CD1 63 #define C1 31 #define C2 (C1 + 60) #define C3 (C2 + 56) #define C4 (C1 + 155) #define C4a (C4 + 60) #define C4b (C4a + 31) #define C4c (C4b + 31) #define C5 (C4 + CD1 + 3) #define C6 (C5 + 58) #define C7 (C6 + 31) #define C7S (C7 + 31) #define C8 (C5 + 124) #define C8a (C8 + 29) #define C8b (C8a + 59) #define C8c (C8b + 32) #define C7a (C7 + 58) #define C9 (C8 + 59) #define C10 (C8 + 102) #define C11 (C10 + CD1) #define C11a (C11 + 15) #define C11b (C11a + 60) #define C11c (C11 + 3) #define C11d (C11 + 44) #define C11e (C11 + 83) #define C12 (C11 + CD1) #define C13 (C12 + 75) #define C14 (C13 + CD1) #define C15 (C14 + CD1) #define C16 (C15 + CD1) #define C17 (C16 + 70) #define S1 100 #define S2 12 #define S3 70 #define S4 11 #define S5 90 #define S6 15 #define S7 50 /* * This structure is for device definition. The structure is defined in * include/brighton.h, further definitions in brighton/brightonDevtable.h and * include/brightoninternals.h * * typedef int (*brightonCallback)(int, float); * typedef struct BrightonLocations { * int device; 0=rotary, 1=scale, etc. * float relx, rely; relative position with regards to 1000 by 1000 window * float relw, relh; relative height. * int from, to; * brightonCallback callback; specific to this dev * char *image; bitmap. If zero take a device default. * int flags; * } brightonLocations; * * This example is for a pro1Bristol type synth interface. */ static brightonLocations locations[DEVICE_COUNT] = { /* mod */ {"ModFiltEnv", 0, C1, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0, BRIGHTON_REDRAW}, {"ModFiltEnv", 2, C2, R1S, S2, S3, 0, 1.01, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, {"ModOscBMod", 0, C1, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0, BRIGHTON_REDRAW}, {"ModOscBRt", 2, C2, R2S, S2, S3, 0, 1.01, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, {"ModLfo", 0, C1, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0, BRIGHTON_REDRAW}, {"ModLfoRt", 2, C2, R3S, S2, S3, 0, 1.01, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, {"ModOSCAFr", 1, C3, RA, S4, S5, 0, 2, 0, "bitmaps/buttons/klunk3.xpm", 0, 0}, {"ModOSCAPWM", 1, C3, RB, S4, S5, 0, 2, 0, "bitmaps/buttons/klunk3.xpm", 0, 0}, {"ModOSCBFr", 1, C3, RC, S4, S5, 0, 2, 0, "bitmaps/buttons/klunk3.xpm", 0, 0}, {"ModOSCBPWM", 1, C3, RD, S4, S5, 0, 2, 0, "bitmaps/buttons/klunk3.xpm", 0, 0}, {"ModFilter", 1, C3, RE, S4, S5, 0, 2, 0, "bitmaps/buttons/klunk3.xpm", 0, 0}, /* Osc-A */ {"OscAFine", 0, C4, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0, BRIGHTON_REDRAW|BRIGHTON_NOTCH}, {"OscAOct", 0, C5, R1, S1, S1, 0, 3, 0, "bitmaps/knobs/knob9.xpm", 0, BRIGHTON_REDRAW|BRIGHTON_STEPPED}, {"OscASaw", 2, C6, R1S, S2, S3, 0, 1.01, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, {"OscAPuls", 2, C7, R1S, S2, S3, 0, 1.01, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, {"OscAPW", 0, C8, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0, BRIGHTON_REDRAW}, {"OscASync", 2, C9, R1S, S2, S3, 0, 1.01, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, /* Osc-B */ {"OscBFine", 0, C4, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0, BRIGHTON_REDRAW|BRIGHTON_NOTCH}, {"OscBOct", 0, C5, R2, S1, S1, 0, 3, 0, "bitmaps/knobs/knob9.xpm", 0, BRIGHTON_REDRAW|BRIGHTON_STEPPED}, {"OscBSaw", 2, C6, R2S, S2, S3, 0, 1.01, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, {"OscBTri", 2, C7, R2S, S2, S3, 0, 1.01, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, {"OscBPuls", 2, C7S, R2S, S2, S3, 0, 1.01, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, {"OscBPW", 0, C8a, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0, BRIGHTON_REDRAW}, {"OscBLFO", 2, C8b, R2S, S2, S3, 0, 1.01, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, {"OscBKEY", 2, C8c, R2S, S2, S3, 0, 1.01, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, /* LFO */ {"LFORATE", 0, C4, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0, BRIGHTON_REDRAW}, {"LFOSAW", 2, C4a, R3S, S2, S3, 0, 1.01, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, {"LFOTRI", 2, C4b, R3S, S2, S3, 0, 1.01, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, {"LFOPuls", 2, C4c, R3S, S2, S3, 0, 1.01, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, /* Seq */ {"SEQ 1/2", 2, C8 - 6, R3S, S2, S3, 0, 1.01, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, {"Rec/Play", 2, C8a + 5, R3S, S2, S3, 0, 1.01, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, /* Arpeg */ {"Up/Down", 1, C10 - 4, R3S - 5, S4, S5, 0, 2, 0, "bitmaps/buttons/klunk3.xpm", 0, 0}, /* Mode */ {"Metro", 2, C11c, R3S, S2, S3, 0, 1.01, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, {"Repeat", 2, C11d, R3S, S2, S3, 0, 1.01, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, {"Drone", 2, C11e, R3S, S2, S3, 0, 1.01, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, /* Mixer */ {"OSCAMix", 0, C10, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0, BRIGHTON_REDRAW}, {"OSCBMix", 0, C11, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0, BRIGHTON_REDRAW}, {"Noise Mix", 0, C12, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0, BRIGHTON_REDRAW}, /* Glide */ {"Glide", 0, C11a, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0, BRIGHTON_REDRAW}, {"Auto", 2, C11b, R2S, S2, S3, 0, 1.01, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, /* Filter */ {"Cutoff", 0, C13, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0, BRIGHTON_REDRAW}, {"Emphasis", 0, C14, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0, BRIGHTON_REDRAW}, {"EnvAmt", 0, C15, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0, BRIGHTON_REDRAW}, {"KeyAmt", 0, C16, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0, BRIGHTON_REDRAW}, /* ENV */ {"Filt Attack", 0, C13, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0, BRIGHTON_REDRAW}, {"Filt Decay", 0, C14, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0, BRIGHTON_REDRAW}, {"Filt Sustain", 0, C15, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0, BRIGHTON_REDRAW}, {"Filt Release", 0, C16, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0, BRIGHTON_REDRAW}, /* ENV */ {"Attack", 0, C13, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0, BRIGHTON_REDRAW|BRIGHTON_HALFSHADOW}, {"Decay", 0, C14, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0, BRIGHTON_REDRAW|BRIGHTON_HALFSHADOW}, {"Sustain", 0, C15, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0, BRIGHTON_REDRAW|BRIGHTON_HALFSHADOW}, {"Release", 0, C16, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0, BRIGHTON_REDRAW|BRIGHTON_HALFSHADOW}, /* Tune Vol */ {"VolumeTuning", 0, C17, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_REDRAW}, {"MasterVolume", 0, C17, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0, BRIGHTON_REDRAW|BRIGHTON_HALFSHADOW}, /* memories */ {"", 2, C10 + 10, R4, S6, S7, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C10 + 30, R4, S6, S7, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C10 + 50, R4, S6, S7, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C10 + 70, R4, S6, S7, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C10 + 90, R4, S6, S7, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C10 + 110, R4, S6, S7, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C10 + 130, R4, S6, S7, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C10 + 150, R4, S6, S7, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C4, R4, S6, S7, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, C4 + 30, R4, S6, S7, 0, 1, 0, "bitmaps/buttons/pressoffo.xpm", "bitmaps/buttons/pressono.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, C4 + 60, R4, S6, S7, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, /* Mem search buttons */ {"", 2, C10 + 180, R4, S6, S7, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, C10 + 210, R4, S6, S7, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, C10 + 240, R4, S6, S7, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 4, 798, 870, 125, 100, 0, 1, 0, "bitmaps/images/pro1.xpm", 0, 0}, /* Midi, perhaps eventually file import/export buttons */ {"", 2, C1, R4, S6, S7, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, C2 + 5, R4, S6, S7, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 3, C5 + 23, R4, 200, S7 - 10, 0, 1, 0, 0, "bitmaps/images/alphadisplay3.xpm", 0} }; /* * These are new mod controls for the Pro-1. May be used elsewhere */ static brightonLocations promods[2] = { {"", BRIGHTON_MODWHEEL, 300, 220, 150, 350, 0, 1, 0, "bitmaps/knobs/modwheel.xpm", 0, BRIGHTON_HSCALE|BRIGHTON_NOSHADOW|BRIGHTON_CENTER|BRIGHTON_NOTCH}, {"", BRIGHTON_MODWHEEL, 640, 220, 150, 350, 0, 1, 0, "bitmaps/knobs/modwheel.xpm", 0, BRIGHTON_HSCALE|BRIGHTON_NOSHADOW}, }; /* * This is a set of globals for the main window rendering. Again taken from * include/brighton.h */ brightonApp pro1App = { "pro1", 0, /* no blueprint on wood background. */ "bitmaps/textures/metal4.xpm",//"bitmaps/textures/metal7.xpm", BRIGHTON_STRETCH,//|BRIGHTON_REVERSE|BRIGHTON_VERTICAL, //flags pro1Init, pro1Configure, /* 3 callbacks, unused? */ midiCallback, destroySynth, {1, 100, 2, 2, 5, 520, 0, 0}, 895, 500, 0, 0, 5, { { "Pro1", "bitmaps/blueprints/pro1.xpm", 0, // "bitmaps/textures/metal5.xpm", 0, /*BRIGHTON_STRETCH, // flags */ 0, 0, pro1Callback, 25, 0, 950, 650, DEVICE_COUNT, locations }, { "Keyboard", 0, "bitmaps/newkeys/ekbg.xpm", /* flags */ 0x020|BRIGHTON_STRETCH, 0, 0, proOneKeyCallback, 140, 680, 845, 300, KEY_COUNT_3OCTAVE, keys3octave }, { "Mods", 0, //"bitmaps/blueprints/pro1mod.xpm", "bitmaps/buttons/blue.xpm", /* flags */ 0, 0, 0, modCallback, 25, 680, 110, 320, 2, promods }, { "Metal side", 0, "bitmaps/textures/wood4.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 0, 0, 25, 1000, 0, 0 }, { "Metal side", 0, "bitmaps/textures/wood4.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 976, 0, 25, 1000, 0, 0 }, } }; static void pro1SeqInsert(guiSynth *synth, int note, int layer) { arpeggiatorMemory *seq = (arpeggiatorMemory *) synth->seq1.param; if (seq->s_max == 0) seq->s_dif = note + synth->transpose; seq->sequence[(int) (seq->s_max)] = // (float) (note + synth->transpose - seq->s_dif); (float) (note + synth->transpose); // if (pro10Debug(synth, 0)) printf("Seq put %i into %i\n", (int) seq->sequence[(int) (seq->s_max)], (int) (seq->s_max)); if ((seq->s_max += 1) >= BRISTOL_SEQ_MAX) seq->s_max = BRISTOL_SEQ_MAX; } static int proOneKeyCallback(brightonWindow * win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); if (global.libtest) return(0); //printf("proOneKeyCallback(%i, %i, %f) %i\n", panel, index, value, seqLearn); if ((seqLearn) && (value != 0)) pro1SeqInsert(synth, index, panel); /* * Want to send a note event, on or off, for this index + transpose. */ if (value) bristolMidiSendMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_KEYON, 0, index + synth->transpose); else bristolMidiSendMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_KEYOFF, 0, index + synth->transpose); return(0); } static int midiCallback(brightonWindow *win, int controller, int value, float n) { guiSynth *synth = findSynth(global.synths, win); printf("midi callback: %x, %i\n", controller, value); switch(controller) { case MIDI_PROGRAM: printf("midi program: %x, %i\n", controller, value); synth->bank = value - (value % 8); synth->location = value % 8; loadMemory(synth, "pro1", 0, synth->bank * 10 + synth->location, synth->mem.active, 0, 0); break; case MIDI_BANK_SELECT: printf("midi banksel: %x, %i\n", controller, value); synth->bank = value; break; } return(0); } /*static dispatcher dispatch[DEVICE_COUNT]; */ static int pro1MidiSendMsg(void *synth, int fd, int chan, int c, int o, int v) { bristolMidiSendMsg(fd, chan, c, o, v); return(0); } static void pro1Sequence(guiSynth *synth, int fd, int chan, int c, int o, int v) { if (synth->seq1.param == NULL) { /* This does not actually reload a sequence..... FFS, see Pro10 code */ loadSequence(&synth->seq1, "pro1", 0, 0); fillSequencer(synth, (arpeggiatorMemory *) synth->seq1.param, 0); } switch (o) { case 0: /* On/Off */ if (v == 0) { seqLearn = 0; bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_ENABLE, 0); } else { seqLearn = 0; bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RESEQ, 0); bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_DIR, BRISTOL_ARPEG_UP); bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_TRIGGER, 1); bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RANGE, 0); bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_ENABLE, 1); } break; case 1: /* Record/Play */ if (v == 0) { seqLearn = 0; /* Turn off sequence learning */ bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RESEQ, 0); /* If we are configured to play then start else stop */ if (synth->mem.param[29] != 0) { bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_TRIGGER, 1); bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_DIR, BRISTOL_ARPEG_UP); bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RANGE, 0); bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_ENABLE, 1); } else bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_ENABLE, 0); } else { arpeggiatorMemory *seq = (arpeggiatorMemory *) synth->seq1.param; seqLearn = 1; seq->s_max = 0; bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_ENABLE, 0); bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RESEQ, 1); } break; } } static void pro1Arpeggiate(guiSynth *synth, int fd, int chan, int c, int o, int v) { /* * See if this is rate. Send the request to both the LFO and the arpeg */ if (c != 126) { bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_RATE, v); bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RATE, v); bristolMidiSendMsg(global.controlfd, synth->sid, 2, 0, v); return; } switch (v) { case 2: /* Arpeggiation up */ bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_DIR, BRISTOL_ARPEG_UP); bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_ENABLE, 1); break; case 1: /* Arpeggiation off */ bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_ENABLE, 0); bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_TRIGGER, 1); bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_RANGE, 2); break; case 0: /* Arpeggiation up/down */ bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_DIR, BRISTOL_ARPEG_UD); bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_ENABLE, 1); break; } } static void pro1Memory(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; int bank = synth->bank; int location = synth->location; event.value = 1.0; event.type = BRISTOL_FLOAT; if (synth->flags & MEM_LOADING) return; if ((synth->flags & OPERATIONAL) == 0) return; if (synth->dispatch[MEM_START].other2) { synth->dispatch[MEM_START].other2 = 0; return; } switch (c) { default: case 0: /* * We want to make these into memory buttons. To do so we need to * know what the last active button was, and deactivate its * display, then send any message which represents the most * recently configured value. Since this is a memory button we do * not have much issue with the message, but we are concerned with * the display. */ if (synth->dispatch[MEM_START].other1 != -1) { synth->dispatch[MEM_START].other2 = 1; if (synth->dispatch[MEM_START].other1 != o) event.value = 0; else event.value = 1; brightonParamChange(synth->win, synth->panel, synth->dispatch[MEM_START].other1 + MEM_START - 1, &event); } synth->dispatch[MEM_START].other1 = o; if (synth->flags & BANK_SELECT) { if ((synth->bank * 10 + o) >= 100) { synth->location = o; synth->flags &= ~BANK_SELECT; if (loadMemory(synth, "pro1", 0, synth->bank * 10 + synth->location, synth->mem.active, 0, BRISTOL_STAT) < 0) displayText(synth, "FREE MEM", synth->bank * 10 + synth->location, DISPLAY_DEV); else displayText(synth, "PROGRAM", synth->bank * 10 + synth->location, DISPLAY_DEV); } else { synth->bank = synth->bank * 10 + o; displayText(synth, "BANK", synth->bank * 10 + synth->location, DISPLAY_DEV); } } else { if (synth->bank < 1) synth->bank = 1; synth->location = o; if (loadMemory(synth, "pro1", 0, synth->bank * 10 + synth->location, synth->mem.active, 0, BRISTOL_STAT) < 0) displayText(synth, "FREE MEM", synth->bank * 10 + synth->location, DISPLAY_DEV); else displayText(synth, "PROGRAM", synth->bank * 10 + synth->location, DISPLAY_DEV); } break; case 1: if (synth->bank < 1) synth->bank = 1; if (synth->location == 0) synth->location = 1; if (loadMemory(synth, "pro1", 0, synth->bank * 10 + synth->location, synth->mem.active, 0, BRISTOL_FORCE) < 0) displayText(synth, "FREE MEM", synth->bank * 10 + synth->location, DISPLAY_DEV); else { displayText(synth, "PROGRAM", synth->bank * 10 + synth->location, DISPLAY_DEV); loadSequence(&synth->seq1, "pro1", synth->bank * 10 + synth->location, 0); fillSequencer(synth, (arpeggiatorMemory *) synth->seq1.param, 0); } synth->flags &= ~BANK_SELECT; break; case 2: if (synth->bank < 1) synth->bank = 1; if (synth->location == 0) synth->location = 1; saveMemory(synth, "pro1", 0, synth->bank * 10 + synth->location, 0); saveSequence(synth, "pro1", synth->bank * 10 + synth->location, 0); displayText(synth, "PROGRAM", synth->bank * 10 + synth->location, DISPLAY_DEV); synth->flags &= ~BANK_SELECT; break; case 3: if (synth->flags & BANK_SELECT) { synth->flags &= ~BANK_SELECT; if (loadMemory(synth, "pro1", 0, synth->bank * 10 + synth->location, synth->mem.active, 0, BRISTOL_STAT) < 0) displayText(synth, "FREE MEM", synth->bank * 10 + synth->location, DISPLAY_DEV); else { displayText(synth, "PROGRAM", synth->bank * 10 + synth->location, DISPLAY_DEV); loadSequence(&synth->seq1, "pro1", synth->bank * 10 + synth->location, 0); fillSequencer(synth, (arpeggiatorMemory *) synth->seq1.param, 0); } } else { synth->bank = 0; displayText(synth, "BANK", synth->bank, DISPLAY_DEV); synth->flags |= BANK_SELECT; } break; case 4: if (--location < 1) { location = 8; if (--bank < 1) bank = 88; } while (loadMemory(synth, "pro1", 0, bank * 10 + location, synth->mem.active, 0, BRISTOL_STAT) < 0) { if (--location < 1) { location = 8; if (--bank < 1) bank = 88; } if ((bank * 10 + location) == (synth->bank * 10 + synth->location)) break; } displayText(synth, "PROGRAM", bank * 10 + location, DISPLAY_DEV); synth->bank = bank; synth->location = location; loadMemory(synth, "pro1", 0, bank * 10 + location, synth->mem.active, 0, BRISTOL_FORCE); loadSequence(&synth->seq1, "pro1", bank * 10 + location, 0); fillSequencer(synth, (arpeggiatorMemory *) synth->seq1.param, 0); brightonParamChange(synth->win, 0, MEM_START - 1 + synth->location, &event); break; case 5: if (++location > 8) { location = 1; if (++bank > 88) bank = 1; } while (loadMemory(synth, "pro1", 0, bank * 10 + location, synth->mem.active, 0, BRISTOL_STAT) < 0) { if (++location > 8) { location = 1; if (++bank > 88) bank = 1; } if ((bank * 10 + location) == (synth->bank * 10 + synth->location)) break; } displayText(synth, "PROGRAM", bank * 10 + location, DISPLAY_DEV); synth->bank = bank; synth->location = location; loadMemory(synth, "pro1", 0, bank * 10 + location, synth->mem.active, 0, BRISTOL_FORCE); brightonParamChange(synth->win, 0, MEM_START - 1 + synth->location, &event); loadSequence(&synth->seq1, "pro1", bank * 10 + location, 0); fillSequencer(synth, (arpeggiatorMemory *) synth->seq1.param, 0); break; case 6: /* Find the next free mem */ if (++location > 8) { location = 1; if (++bank > 88) bank = 1; } while (loadMemory(synth, "pro1", 0, bank * 10 + location, synth->mem.active, 0, BRISTOL_STAT) >= 0) { if (++location > 8) { location = 1; if (++bank > 88) bank = 1; } if ((bank * 10 + location) == (synth->bank * 10 + synth->location)) break; } if (loadMemory(synth, "pro1", 0, bank * 10 + location, synth->mem.active, 0, BRISTOL_STAT) >= 0) displayText(synth, "PROGRAM", bank * 10 + location, DISPLAY_DEV); else displayText(synth, "FREE MEM", bank * 10 + location, DISPLAY_DEV); synth->bank = bank; synth->location = location; brightonParamChange(synth->win, 0, MEM_START - 1 + synth->location, &event); break; } /* printf(" pro1Memory(B: %i L %i: %i)\n", */ /* synth->bank, synth->location, o); */ } static int pro1Midi(guiSynth *synth, int fd, int chan, int c, int o, int v) { int newchan; if ((synth->flags & OPERATIONAL) == 0) return(0); if (c == 1) { if ((newchan = synth->midichannel - 1) < 0) { synth->midichannel = 0; return(0); } } else { if ((newchan = synth->midichannel + 1) >= 16) { synth->midichannel = 15; return(0); } } if (global.libtest == 0) { bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_MIDICHANNEL|newchan); } synth->midichannel = newchan; /* printf("P: going to display: %x, %x\n", synth, synth->win); */ displayText(synth, "MIDI CH", synth->midichannel + 1, DISPLAY_DEV); return(0); } static void pro1ShowParam(guiSynth *synth, int index, float value) { char showthis[64]; if (index >= pro1App.resources[0].ndevices) return; if (pro1App.resources[0].devlocn[index].name[0] == '\0') { if (pro1App.resources[0].devlocn[index].to == 1.0) sprintf(showthis, "%i: %1.3f", index, value); else sprintf(showthis, "%i: %1.1f", index, value); } else { if (pro1App.resources[0].devlocn[index].to == 1.0) sprintf(showthis, "%s: %1.3f", pro1App.resources[0].devlocn[index].name, value); else sprintf(showthis, "%s: %1.1f", pro1App.resources[0].devlocn[index].name, value); } displayPanel(synth, showthis, index, 0, DISPLAY_DEV); } /* * For the sake of ease of use, links have been placed here to be called * by any of the devices created. They would be better in some other file, * perhaps with this as a dispatch. * * Param refers to the device index in the locations table given below. */ static int pro1Callback(brightonWindow * win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); int sendvalue; /* printf("pro1Callback(%i, %f): %x\n", index, value, synth); */ if ((synth->flags & MEM_LOADING) == 0) pro1ShowParam(synth, index, value); if (synth == 0) return(0); if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0)) return(0); if (pro1App.resources[0].devlocn[index].to == 1.0) sendvalue = value * (CONTROLLER_RANGE - 1); else sendvalue = value; synth->mem.param[index] = value; if ((!global.libtest) || (index >= ACTIVE_DEVS)) synth->dispatch[index].routine(synth, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #ifdef DEBUG else printf("dispatch[%p,%i](%i, %i, %i, %i, %i)\n", synth, index, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #endif return(0); } static void pro1Hold(guiSynth *synth) { if ((synth->flags & OPERATIONAL) == 0) return; if (synth->mem.param[34]) bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_HOLD|1); else bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_HOLD|0); } /* * Any location initialisation required to run the callbacks. For bristol, this * will connect to the engine, and give it some base parameters. * May need to generate some application specific menus. * Will also then make specific requests to some of the devices to alter their * rendering. */ static int pro1Init(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); dispatcher *dispatch; int i; if (synth == 0) { synth = findSynth(global.synths, (int) 0); if (synth == 0) { printf("cannot init\n"); return(0); } } if ((initmem = synth->location) == 0) initmem = 11; synth->win = win; printf("Initialise the pro1 link to bristol: %p\n", synth->win); synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float)); synth->mem.count = DEVICE_COUNT; synth->mem.active = ACTIVE_DEVS; synth->dispatch = (dispatcher *) brightonmalloc(DEVICE_COUNT * sizeof(dispatcher)); dispatch = synth->dispatch; /* * We really want to have three connection mechanisms. These should be * 1. Unix named sockets. * 2. UDP sockets. * 3. MIDI pipe. */ if (!global.libtest) { if ((synth->sid = initConnection(&global, synth)) < 0) return(-1); } for (i = 0; i < DEVICE_COUNT; i++) synth->dispatch[i].routine = pro1MidiSendMsg; /* Mods source */ dispatch[0].controller = 3; dispatch[0].operator = 4; dispatch[1].controller = 126; dispatch[1].operator = 3; dispatch[2].controller = 126; dispatch[2].operator = 4; dispatch[3].controller = 126; dispatch[3].operator = 5; dispatch[4].controller = 126; dispatch[4].operator = 6; dispatch[5].controller = 126; dispatch[5].operator = 7; /* Mods dest */ dispatch[6].controller = 126; dispatch[6].operator = 10; dispatch[7].controller = 126; dispatch[7].operator = 11; dispatch[8].controller = 126; dispatch[8].operator = 12; dispatch[9].controller = 126; dispatch[9].operator = 13; dispatch[10].controller = 126; dispatch[10].operator = 14; /* Osc A */ dispatch[11].controller = 0; dispatch[11].operator = 2; dispatch[12].controller = 0; dispatch[12].operator = 1; dispatch[13].controller = 0; dispatch[13].operator = 4; dispatch[14].controller = 0; dispatch[14].operator = 6; dispatch[15].controller = 0; dispatch[15].operator = 0; dispatch[16].controller = 0; dispatch[16].operator = 7; /* Osc B */ dispatch[17].controller = 1; dispatch[17].operator = 2; dispatch[18].controller = 1; dispatch[18].operator = 1; dispatch[19].controller = 1; dispatch[19].operator = 4; dispatch[20].controller = 1; dispatch[20].operator = 5; dispatch[21].controller = 1; dispatch[21].operator = 6; dispatch[22].controller = 1; dispatch[22].operator = 0; dispatch[23].controller = 126; dispatch[23].operator = 18; dispatch[24].controller = 126; dispatch[24].operator = 19; /* LFO */ dispatch[25].controller = 2; dispatch[25].operator = 0; dispatch[25].routine = (synthRoutine) pro1Arpeggiate; dispatch[26].controller = 126; dispatch[26].operator = 24; dispatch[27].controller = 126; dispatch[27].operator = 25; dispatch[28].controller = 126; dispatch[28].operator = 26; /* Seqx2/Arpeg/modex3 */ dispatch[29].controller = 126; dispatch[29].operator = 0; dispatch[29].routine = (synthRoutine) pro1Sequence; dispatch[30].controller = 126; dispatch[30].operator = 1; dispatch[30].routine = (synthRoutine) pro1Sequence; dispatch[31].controller = 126; dispatch[31].operator = 101; dispatch[31].routine = (synthRoutine) pro1Arpeggiate; /* Modes, need to read up on function */ dispatch[32].controller = 126; /* multitrig envelope note */ dispatch[32].operator = 27; dispatch[33].controller = 126; /* Track LFO as trigger */ dispatch[33].operator = 9; dispatch[34].controller = 126; /* Force gate open */ dispatch[34].operator = 28; dispatch[34].routine = (synthRoutine) pro1Hold; /* Drone */ /* Mixer */ dispatch[35].controller = 126; dispatch[35].operator = 20; dispatch[36].controller = 126; dispatch[36].operator = 21; dispatch[37].controller = 126; dispatch[37].operator = 22; /* Glide */ dispatch[38].controller = 126; dispatch[38].operator = 0; dispatch[39].controller = 126; dispatch[39].operator = 8; /* Filter and Env */ dispatch[40].controller = 4; dispatch[40].operator = 0; dispatch[41].controller = 4; dispatch[41].operator = 1; dispatch[42].controller = 126; dispatch[42].operator = 23; dispatch[43].controller = 4; dispatch[43].operator = 3; dispatch[44].controller = 3; dispatch[44].operator = 0; dispatch[45].controller = 3; dispatch[45].operator = 1; dispatch[46].controller = 3; dispatch[46].operator = 2; dispatch[47].controller = 3; dispatch[47].operator = 3; /* Env */ dispatch[48].controller = 5; dispatch[48].operator = 0; dispatch[49].controller = 5; dispatch[49].operator = 1; dispatch[50].controller = 5; dispatch[50].operator = 2; dispatch[51].controller = 5; dispatch[51].operator = 3; /* Tune and Master */ dispatch[52].controller = 126; dispatch[52].operator = 2; dispatch[53].controller = 5; dispatch[53].operator = 4; /* Memory and MIDI */ dispatch[MEM_START + 0].operator = 1; dispatch[MEM_START + 1].operator = 2; dispatch[MEM_START + 2].operator = 3; dispatch[MEM_START + 3].operator = 4; dispatch[MEM_START + 4].operator = 5; dispatch[MEM_START + 5].operator = 6; dispatch[MEM_START + 6].operator = 7; dispatch[MEM_START + 7].operator = 8; dispatch[MEM_START + 8].controller = 1; dispatch[MEM_START + 9].controller = 2; dispatch[MEM_START + 10].controller = 3; dispatch[MEM_START + 11].controller = 4; dispatch[MEM_START + 12].controller = 5; dispatch[MEM_START + 13].controller = 6; dispatch[MEM_START + 0].routine = dispatch[MEM_START + 1].routine = dispatch[MEM_START + 2].routine = dispatch[MEM_START + 3].routine = dispatch[MEM_START + 4].routine = dispatch[MEM_START + 5].routine = dispatch[MEM_START + 6].routine = dispatch[MEM_START + 7].routine = dispatch[MEM_START + 8].routine = dispatch[MEM_START + 9].routine = dispatch[MEM_START + 10].routine = dispatch[MEM_START + 11].routine = dispatch[MEM_START + 12].routine = dispatch[MEM_START + 13].routine = (synthRoutine) pro1Memory; dispatch[DEVICE_COUNT - 3].routine = dispatch[DEVICE_COUNT - 2].routine = (synthRoutine) pro1Midi; dispatch[DEVICE_COUNT - 3].controller = 1; dispatch[DEVICE_COUNT - 2].controller = 2; dispatch[MEM_START].other1 = -1; /* No velocity on filter contour */ bristolMidiSendMsg(global.controlfd, synth->sid, 3, 5, 0); /* LFO retrigger on keypress */ bristolMidiSendMsg(global.controlfd, synth->sid, 2, 1, 1); bristolMidiSendMsg(global.controlfd, synth->sid, 4, 4, 4); return(0); } /* * This will be called to make any routine specific parameters available. */ static int pro1Configure(brightonWindow* win) { guiSynth *synth = findSynth(global.synths, win); brightonEvent event; if (synth == 0) { printf("problems going operational\n"); return(-1); } if (synth->flags & OPERATIONAL) return(0); printf("going operational\n"); synth->flags |= OPERATIONAL; synth->keypanel = 1; synth->keypanel2 = -1; synth->transpose = 36; if (synth->location == 0) { synth->bank = 1; synth->location = 1; } else { synth->bank = synth->location / 10; synth->location %= 10; } loadMemory(synth, "pro1", 0, initmem, synth->mem.active, 0, 0); loadSequence(&synth->seq1, "pro1", initmem, 0); fillSequencer(synth, (arpeggiatorMemory *) synth->seq1.param, 0); brightonPut(win, "bitmaps/blueprints/pro1shade.xpm", 0, 0, win->width, win->height); event.type = BRIGHTON_FLOAT; /* Tune */ event.value = 0.5; brightonParamChange(synth->win, 0, ACTIVE_DEVS + 0, &event); /* Volume */ event.value = 0.9; brightonParamChange(synth->win, 0, ACTIVE_DEVS + 1, &event); /* First memory location */ event.value = 1.0; brightonParamChange(synth->win, 0, MEM_START, &event); /* Some small amount of mod wheel */ event.value = 0.2; brightonParamChange(synth->win, 2, 1, &event); /* * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only * occurs on first paint, so we suppress the first paint, and then request * an expose here. */ event.type = BRIGHTON_EXPOSE; event.intvalue = 1; brightonParamChange(synth->win, KEY_PANEL, -1, &event); configureGlobals(synth); return(0); } bristol-0.60.11/brighton/brightonhelp.h0000644000175000017500000006464611746476475014775 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ char *helptext = "\nA synthesiser emulation package.\n\ \n\ You should start this package with the startBristol script. This script\n\ will start up the bristol synthesiser binaries evaluating the correct\n\ library paths and executable paths. There are emulation, synthesiser,\n\ operational and GUI parameters:\n\ \n\ Emulation:\n\ \n\ -mini - moog mini\n\ -explorer - moog voyager\n\ -voyager - moog voyager electric blue\n\ -memory - moog memory\n\ -sonic6 - moog sonic 6\n\ -mg1 - moog/realistic mg-1 concertmate\n\ -hammond - hammond module (deprecated, use -b3)\n\ -b3 - hammond B3 (default)\n\ -prophet - sequential circuits prophet-5\n\ -pro52 - sequential circuits prophet-5/fx\n\ -pro10 - sequential circuits prophet-10\n\ -pro1 - sequential circuits pro-one\n\ -rhodes - fender rhodes mark-I stage 73\n\ -rhodesbass - fender rhodes bass piano\n\ -roadrunner - crumar roadrunner electric piano\n\ -bitone - crumar bit 01\n\ -bit99 - crumar bit 99\n\ -bit100 - crumar bit + mods\n\ -stratus - crumar stratus synth/organ combo\n\ -trilogy - crumar trilogy synth/organ/string combo\n\ -obx - oberheim OB-X\n\ -obxa - oberheim OB-Xa\n\ -axxe - arp axxe\n\ -odyssey - arp odyssey\n\ -arp2600 - arp 2600\n\ -solina - arp/solina string ensemble\n\ -polysix - korg polysix\n\ -poly800 - korg poly-800\n\ -monopoly - korg mono/poly\n\ -ms20 - korg ms20 (unfinished: -libtest only)\n\ -vox - vox continental\n\ -voxM2 - vox continental super/300/II\n\ -juno - roland juno-60\n\ -jupiter - roland jupiter-8\n\ -bme700 - baumann bme-700\n\ -bm - bristol bassmaker sequencer\n\ -dx - yamaha dx-7\n\ -cs80 - yamaha cs-80 (unfinished)\n\ -sidney - commodore-64 SID chip synth\n\ -melbourne - commodore-64 SID polyphonic synth (unfinished)\n\ -granular - granular synthesiser (unfinished)\n\ -aks - ems synthi-a (unfinished)\n\ -mixer - 16 track mixer (unfinished: -libtest only)\n\ \n\ Synthesiser:\n\ \n\ -voices - operate with a total of 'n' voices (32)\n\ -mono - operate with a single voice (-voices 1)\n\ -lnp - low note preference (-mono)\n\ -hnp - high note preference (-mono)\n\ -nnp - no/last note preference (-mono)\n\ -retrig - monophonic note logic legato trigger (-mono)\n\ -lvel - monophonic note logic legato velocity (-mono)\n\ -channel - initial midi channel selected to 'c' (default 1)\n\ -lowkey - minimum MIDI note response (0)\n\ -highkey - maximum MIDI note response (127)\n\ -detune <%> - 'temperature sensitivity' of emulation (0)\n\ -gain - emulator output signal gain (default 1)\n\ -pwd - pitch wheel depth (2 semitones)\n\ -velocity - MIDI velocity mapping curve (510) (-mvc)\n\ -glide - MIDI glide duration (5)\n\ -emulate - search for the named synth or exit\n\ -register - name used for jack and alsa device regisration\n\ -lwf - emulator lightweight filters\n\ -nwf - emulator default filters\n\ -wwf - emulator welterweight filters\n\ -hwf - emulator heavyweight filters\n\ -blo - maximum # band limited harmonics (31)\n\ -blofraction - band limiting nyquist fraction (0.8)\n\ -scala - read the scala .scl tonal mapping table\n\ \n\ User Interface:\n\ \n\ -quality - color cache depth (bbp 2..8) (6)\n\ -grayscale - color or BW display (0..5) (0 = color)\n\ -antialias - antialias depth (0..100%) (30)\n\ -aliastype - antialias type (pre/texture/all)\n\ -opacity - opacity of the patch layer 20..100% (50)\n\ -scale - initial windowsize, fs = fullscreen (1.0)\n\ -width - the pixel width of the GUI window\n\ -autozoom - flip between min and max window on Enter/Leave\n\ -raise - disable auto raise on max resize\n\ -lower - disable auto lower on min resize\n\ -rud - constrain rotary tracking to up/down\n\ -pixmap - use the pixmap interface rather than ximage\n\ -dct - double click timeout (250 ms)\n\ -tracking - disable MIDI keyboard latching state\n\ -keytoggle - disable MIDI \n\ -load - load memory number 'm' (default 0)\n\ -neutral - initialise the emulator with a 'null' patch\n\ -import - import memory from file into synth\n\ -mbi - master bank index (0)\n\ -activesense - active sense rate (2000 ms)\n\ -ast - active sense timeout (15000 ms)\n\ -mct - midi cycle timeout (50 ms)\n\ -ar|-aspect - ignore emulator requested aspect ratio\n\ -iconify - start with iconified window\n\ -window - toggle switch to enable X11 window interfacen\n\ -cli - enable command line interface\n\ -libtest - gui test option, engine not invoked\n\ \n\ Gui keyboard shortcuts:\n\ \n\ 's' - save settings to current memory\n\ 'l' - (re)load current memory\n\ 'x' - exchange current with previous memory\n\ '+' - load next memory\n\ '-' - load previous memory\n\ '?' - show emulator help information\n\ 'h' - show emulator help information\n\ 'r' - show application readme information\n\ 'k' - show keyboard shortcuts\n\ 'p' - screendump to /tmp/.xpm\n\ 't' - toggle opacity\n\ 'o' - decrease opacity of patch layer\n\ 'O' - increase opacity of patch layer\n\ 'w' - display warranty\n\ 'g' - display GPL (copying conditions)\n\ '+' - increase window size\n\ '-' - decrease window size\n\ 'Enter'- toggle window between full screen size\n\ 'UpArrow' - controller motion up (shift key accelerator)\n\ 'DownArrow' - controller motion down (shift key accelerator)\n\ 'RightArrow' - more controller motion up (shift key accelerator)\n\ 'LeftArrow' - more controller motion down (shift key accelerator)\n\ \n\ Operational:\n\ \n\ General:\n\ \n\ -engine - don't start engine (connect to existing engine)\n\ -gui - don't start gui (only start engine)\n\ -server - run engine as a permanant server\n\ -daemon - run engine as a detached permanant server\n\ -watchdog - audio thread initialisation timeout (30s)\n\ -log - redirect diagnostic to $HOME/.bristol/log\n\ -syslog - redirect diagnostic to syslog\n\ -console - log all messages to console (must be 1st option)\n\ -exec - run all subprocesses in background\n\ -stop - terminate all bristol engines\n\ -exit - terminate all bristol engines and GUI\n\ -kill <-emu> - terminate all bristol processes emulating -emu\n\ -cache - memory and profile cache location (~/.bristol)\n\ -memdump - copy full set of memories to , with -emulate\n\ -debug <1-16> - debuging level (0)\n\ -readme [-] - show readme [for emulator ] to console\n\ -glwf - global lightweight filters - no overrides\n\ -host - connect to engine on host 'h' (localhost)\n\ -port

- connect to engine on TCP port 'p' (default 5028)\n\ -quiet - redirect diagnostic output to /dev/null\n\ -gmc - open a MIDI connection to the brighton GUI\n\ -oss - use OSS defaults for audio and MIDI\n\ -alsa - use ALSA defaults for audio and MIDI (default)\n\ -jack - use Jack defaults for audio and MIDI\n\ -jackstats - avoid use of bristoljackstats\n\ -jsmuuid - jack session unique identifier\n\ -jsmfile - jack session setting path\n\ -jsmd - jack session file load delay (5000)\n\ -sleep - delay init for 'n' seconds (jsm patch)\n\ -session - disable session management\n\ -jdo - use separate Jack clients for audio and MIDI\n\ -osc - use OSC for control interface (unfinished)\n\ -forward - disable MIDI event forwarding globally\n\ -localforward - disable emulator gui->engine event forwarding\n\ -remoteforward - disable emulator engine->gui event forwarding\n\ -o - Duplicate raw audio output data to file\n\ -nrp - enable NPR support globally\n\ -enrp - enable NPR/DE support in engine\n\ -gnrp - enable NPR/RP/DE support in GUI\n\ -nrpcc - size of NRP controller table (128)\n\ \n\ Audio driver:\n\ \n\ -audio [oss|alsa|jack] - audio driver selection (alsa)\n\ -audiodev - audio device selection\n\ -count - sample period count (256)\n\ -outgain - digital output signal gain (default 4)\n\ -ingain - digital input signal gain (default 4)\n\ -preload - configure preload buffer count (default 4)\n\ -rate - sample rate (44100)\n\ -priority

- audio RT priority, 0=no realtime (75)\n\ -autoconn - attempt jack port auto-connect\n\ -multi - register 'c' IO channels (jack only)\n\ -migc - multi IO input gain scaling (jack only)\n\ -mogc - multi IO output gain scaling (jack only)\n\ \n\ Midi driver:\n\ \n\ -midi [oss|[raw]alsa|jack] - midi driver selection (alsa)\n\ -mididev - midi device selection\n\ -seq - use the ALSA SEQ interface (default)\n\ -mididbg - midi debug-1 enable\n\ -mididbg2 - midi debug-2 enable\n\ -sysid - MIDI SYSEX system identifier\n\ \n\ LADI driver (level 1 compliant):\n\ \n\ -ladi brighton - only execute LADI in GUI\n\ -ladi bristol - only execute LADI in engine\n\ -ladi - LADI state memory index (1024)\n\ \n\ Audio drivers are PCM/PCM_plug or Jack. Midi drivers are either OSS/ALSA\n\ rawmidi interface, or ALSA SEQ. Multiple GUIs can connect to the single\n\ audio engine which then operates multitimbrally.\n\ \n\ The LADI interfaces does not use a state file but a memory in the normal\n\ memory locations. This should typically be outside of the range of the\n\ select buttons for the synth and the default of 1024 is taken for this\n\ reason.\n\ \n\ Examples:\n\ \n\ startBristol\n\ \n\ Print a terse help message.\n\ \n\ startBristol -v -h\n\ \n\ Hm, if you're reading this you found these switches already.\n\ \n\ startBristol -mini\n\ \n\ Run a minimoog using ALSA interface for audio and midi seq. This is\n\ equivalent to all the following options:\n\ -mini -alsa -audiodev plughw:0,0 -midi seq -count 256 -preload 8 \n\ -port 5028 -voices 32 -channel 1 -rate 44100 -gain 4 -ingain 4\n\ \n\ startBristol -alsa -mini\n\ \n\ Run a minimoog using ALSA interface for audio and midi. This is\n\ equivalent to all the following options:\n\ -mini -audio alsa -audiodev plughw:0,0 -midi alsa -mididev hw:0\n\ -count 256 -preload 8 -port 5028 -voices 32 -channel 1 -rate 44100\n\ \n\ startBristol -explorer -voices 1 -oss\n\ \n\ Run a moog explorer as a monophonic instrument, using OSS interface for\n\ audio and midi.\n\ \n\ startBristol -prophet -channel 3\n\ \n\ Run a prophet-5 using ALSA for audio and midi on channel 3.\n\ \n\ startBristol -b3 -count 512 -preload 2\n\ \n\ Run a hammond b3 with a buffer size of 512 samples, and preload two \n\ such buffers before going active. Some Live! cards need this larger\n\ buffer size with ALSA drivers.\n\ \n\ startBristol -oss -audiodev /dev/dsp1 -vox -voices 8\n\ \n\ Run a vox continental using OSS device 1, and default midi device\n\ /dev/midi0. Operate with just 8 voices.\n\ \n\ startBristol -b3 -audio alsa -audiodev plughw:0,0 -seq -mididev 128.0\n\ \n\ Run a B3 emulation over the ALSA PCM plug interface, using the ALSA\n\ sequencer over client 128, port 0.\n\ \n\ startBristol -juno &\n\ startBristol -prophet -channel 2 -engine\n\ \n\ Start two synthesisers, a juno and a prophet. Both synthesisers will\n\ will be executed on one engine (multitimbral) with 32 voices between \n\ them. The juno will be on default midi channel (1), and the prophet on\n\ channel 2. Output over the same default ALSA audio device.\n\ \n\ startBristol -juno &\n\ startBristol -port 5029 -audio oss -audiodev /dev/dsp1 -mididev /dev/midi1\n\ \n\ Start two synthesisers, a juno on the first ALSA soundcard, and a\n\ mini on the second OSS soundcard. Each synth is totally independent\n\ and runs with 32 voice polyphony (looks nice, not been tested).\n\ \n\ The location of the bristol binaries can be specified in the BRISTOL\n\ environment variable. Private memory and MIDI controller mapping files can\n\ be found in the directory BRISTOL_CACHE and defaults to $HOME/.bristol\n\ \n\ Setting the environment variable BRISTOL_LOG_CONSOLE to any value will result\n\ in the bristol logging output going to your console window without formatted\n\ timestamps\n\ \n\ Korg Inc. of Japan is the rightful owner of the Korg and Vox trademarks, and\n\ the Polysix, Mono/Poly, Poly-800, MS-20 and Continental tradenames. Their own\n\ Vintage Collection provides emulations for a selection of their classic\n\ synthesiser range, this product is in no manner related to Korg other than\n\ giving homage to their great instruments.\n\ \n\ Bristol is in no manner associated with any of the original manufacturers of\n\ any of the emulated instruments. All names and trademarks are property of\n\ their respective owners.\n\ \n\ author: Nick Copeland\n\ email: nickycopeland@hotmail.com\n\ \n\ http://bristol.sourceforge.net\n\ \n\ "; char *gplnotice = "\ Copyright (c) by Nick Copeland 1996,2012\n\ This program comes with ABSOLUTELY NO WARRANTY; for details type ` w'.\n\ This is free software, and you are welcome to redistribute it\n\ under certain conditions; type ` g' for details of GPL terms.\n"; char *gplwarranty = "\ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.\n\ EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\n\ PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR\n\ IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY\n\ AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND\n\ PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU\n\ ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n"; char *gplconditions = "\n\ The following are terms and conditions of the GNU General Public License. For\n\ full details please see \n\n\ 4. Conveying Verbatim Copies.\n\ \n\ You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.\n\ \n\ You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.\n\ 5. Conveying Modified Source Versions.\n\ \n\ You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:\n\ \n\ * a) The work must carry prominent notices stating that you modified it, and giving a relevant date.\n\ * b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all notices”.\n\ * c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.\n\ * d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.\n\ \n\ A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate” if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.\n\ 6. Conveying Non-Source Forms.\n\ \n\ You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:\n\ \n\ * a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.\n\ * b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.\n\ * c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.\n\ * d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.\n\ * e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.\n\ \n\ A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.\n\ \n\ A “User Product” is either (1) a “consumer product”, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used” refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.\n\ \n\ “Installation Information” for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.\n\ \n\ If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).\n\ \n\ The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.\n\ \n\ Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.\n\n"; char *summarytext = "\ arp2600 \ axxe \ bassmaker \ bitone \ bit99 \ bit100 \ BME700 \ dx \ explorer \ hammondB3 \ juno \ jupiter8 \ memoryMoog \ mini \ monopoly \ obx \ obxa \ odyssey \ poly \ poly800 \ pro1 \ prophet \ prophet10 \ prophet52 \ realistic \ rhodes \ rhodesbass \ roadrunner \ sidney \ solina \ sonic6 \ stratus \ trilogy \ vox \ voxM2 \ voyager \ "; char *oldsummarytext = "\ arp2600 \ axxe \ b3 \ bm \ bme700 \ bit1 \ bit99 \ bit100 \ dx \ explorer \ juno \ jupiter \ mg1 \ memoryMoog \ mini \ monopoly \ obx \ obxa \ odyssey \ poly800 \ polysix \ pro1 \ pro10 \ pro5 \ pro52 \ rhodes \ rhodesbass \ roadrunner \ sidney \ solina \ sonic6 \ stratus \ trilogy \ vox \ voxm2 \ voyager \ "; char *summarytextu = "\ mini \ explorer \ voyager \ memory \ sonic6 \ mg1 \ b3 \ prophet \ pro52 \ pro10 \ pro1 \ rhodes \ rhodesbass \ roadrunner \ bitone \ bit99 \ bit100 \ stratus \ trilogy \ obx \ obxa \ axxe \ odyssey \ arp2600 \ solina \ polysix \ poly800 \ monopoly \ vox \ voxm2 \ juno \ jupiter \ bme700 \ bm \ dx \ sidney \ "; bristol-0.60.11/brighton/brighton.c0000644000175000017500000016326111746476475014110 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include #include #include #include #include #include #include #include #include "brighton.h" #include "brightonMini.h" #include "bristolmidi.h" #include "brightonhelp.h" #include "brightonKeyboards.h" #include "brightonVImages.h" extern brightonApp miniApp; extern brightonApp prophetApp; extern brightonApp hammondApp; extern brightonApp junoApp; extern brightonApp dxApp; extern brightonApp explorerApp; extern brightonApp mixApp; extern brightonApp hammondB3App; extern brightonApp voxApp; extern brightonApp rhodesApp; extern brightonApp rhodesBassApp; extern brightonApp pro10App; extern brightonApp prophet52App; extern brightonApp obxApp; extern brightonApp obxaApp; extern brightonApp polyApp; extern brightonApp poly6App; extern brightonApp axxeApp; extern brightonApp odysseyApp; extern brightonApp memMoogApp; extern brightonApp arp2600App; extern brightonApp sAksApp; extern brightonApp ms20App; extern brightonApp solinaApp; extern brightonApp roadrunnerApp; extern brightonApp granularApp; extern brightonApp realisticApp; extern brightonApp voxM2App; extern brightonApp jupiterApp; extern brightonApp bitoneApp; extern brightonApp bit99App; extern brightonApp bit100App; extern brightonApp masterApp; extern brightonApp cs80App; extern brightonApp pro1App; extern brightonApp voyagerApp; extern brightonApp sonic6App; extern brightonApp trilogyApp; extern brightonApp stratusApp; extern brightonApp poly800App; extern brightonApp bme700App; extern brightonApp bmApp; extern brightonApp sidApp; extern brightonApp sid2App; extern int brightonCLIcheck(guimain *); extern int brightonCLIinit(guimain *, int *); #define BRIGHTON_BIT99APP (BRISTOL_SYNTHCOUNT + 1) char *bristolhome = NULL; guimain global; brightonApp *synthesisers[BRISTOL_SYNTHCOUNT]; #include "brightonreadme.h" static char *defname = "bristol"; void *eventMgr(); static int readMe = 0; static int gmc = 0; static int opacity = 60; static int gs = 1; static int nar = 0; static int azoom = 0; static int quality = 6; static int deswidth = -1; static float scale = 1.0; static float antialias = 0.0; static int aliastype = 0; static int library = 1; static int dcTimeout = 500000; static int sampleRate = 44100; static int sampleCount = 256; static int mwt = 50000; static int activeSense = 2000; static int activeSensePeriod = 15000; static int bwflags = BRIGHTON_POST_WINDOW; static int rlflags = BRIGHTON_SET_RAISE|BRIGHTON_SET_LOWER; static int nrpcc = BRIGHTON_NRP_COUNT; static int cli = 0; static int cli_fd[2]; static char defaultcdev[16]; extern int vuInterval; void printBrightonHelp(int); void printBrightonReadme(); extern int brightonMidiInput(bristolMidiMsg *); extern void brightonControlKeyInput(brightonWindow *, int, int); /* * Some of the emulations really benefit from a bit of detune, this is the * value they will use unless another has been requested. */ #define NON_DEF_DETUNE 100 static int asc, emStart = 0, midiHandle = -1; volatile sig_atomic_t ladiRequest = 0; static void savehandler() { if (global.synths->flags & LADI_ENABLE && global.synths->ladimode) ladiRequest = 1; else ladiRequest = 0; } static void loadhandler() { if (global.synths->flags & LADI_ENABLE && global.synths->ladimode) ladiRequest = 2; else ladiRequest = 0; } static void printSummaryText() { int i; for (i = 0 ; i < BRISTOL_SYNTHCOUNT; i++) { if ((synthesisers[i] != NULL) && (synthesisers[i]->name != NULL) && (synthesisers[i]->name[0] != '\0')) printf("%s ", synthesisers[i]->name); } printf("\n"); } static void brightonFindEmulation(int argc, char **argv) { int argCount, i, found = -1; for (argCount = 1; argCount < argc; argCount++) { if (argv[argCount][0] != '-') continue; for (i = 0 ; i < BRISTOL_SYNTHCOUNT; i++) { if (synthesisers[i] == NULL) continue; /* Check for a few aliases */ if (strcmp("-2600", argv[argCount]) == 0) found = global.synths->synthtype = BRISTOL_2600; if (strcmp("-mg1", argv[argCount]) == 0) found = global.synths->synthtype = BRISTOL_REALISTIC; if (strcmp("-bme700", argv[argCount]) == 0) found = global.synths->synthtype = BRISTOL_BME700; if (strcmp("-pro10", argv[argCount]) == 0) found = global.synths->synthtype = BRISTOL_PROPHET10; if (strcmp("-pro52", argv[argCount]) == 0) found = global.synths->synthtype = BRISTOL_PRO52; if ((strcmp("-poly6", argv[argCount]) == 0) || (strcmp("-polysix", argv[argCount]) == 0)) found = global.synths->synthtype = BRISTOL_POLY6; if ((strcmp("-memmoog", argv[argCount]) == 0) || (strcmp("-memorymoog", argv[argCount]) == 0)) found = global.synths->synthtype = BRISTOL_MEMMOOG; if ((strcmp("-emulate", argv[argCount]) == 0) && (argCount < (argc - 1))) { if (strcmp(synthesisers[i]->name, argv[argCount + 1]) == 0) found = global.synths->synthtype = i; } else { if (strcmp(synthesisers[i]->name, &argv[argCount][1]) == 0) found = global.synths->synthtype = i; } } } /* * Global.synths->synthtype will now either be the last emulator found or * will be the usual default (b3). Stuff this back into i, that is nicely * confusing but makes the lines shorter. Hm. */ i = global.synths->synthtype; if (found > 0) printf("%s emulation defaults:\n", synthesisers[i]->name); else { printf("emulation defaults:\n"); } if ((global.synths->voices = synthesisers[i]->emulate.voices) < 0) { printf(" -voices %i\n", BRISTOL_VOICECOUNT); global.synths->voices = BRISTOL_VOICECOUNT; } else printf(" -voices %i\n",synthesisers[i]->emulate.voices); if (global.synths->voices == 1) { printf(" -retrig\n"); printf(" -lvel\n"); printf(" -hnp\n"); printf(" -wwf\n"); global.synths->lwf = 2; global.synths->legatovelocity = 1; global.synths->notepref = BRIGHTON_HNP; global.synths->notetrig = 1; } if (i == BRISTOL_2600) printf(" -multi 4\n"); printf(" -detune %i\n", synthesisers[i]->emulate.detune); printf(" -gain %i\n", synthesisers[i]->emulate.gain); printf(" -pwd %i\n", synthesisers[i]->emulate.pwd); printf(" -glide %i\n", synthesisers[i]->emulate.glide); printf(" -curve %i\n", synthesisers[i]->emulate.velocity); global.synths->detune = synthesisers[i]->emulate.detune; global.synths->gain = synthesisers[i]->emulate.gain * 16; global.synths->pwd = synthesisers[i]->emulate.pwd; global.synths->glide = synthesisers[i]->emulate.glide; global.synths->velocity = synthesisers[i]->emulate.velocity; if (synthesisers[i]->emulate.opacity != 0) printf(" -opacity %i\n", opacity = synthesisers[i]->emulate.opacity); } /* * Need to make this multithreaded? */ int main(int argc, char **argv) { int argCount = 1, i, j, logtype = BRISTOL_LOG_BRIGHTON; pthread_t emgrThread, logthread; char appname[65], *devname = defname; int reqW = 0, reqH = 0, reqX = 0, reqY = 0; signal(SIGINT, cleanupBristol); signal(SIGPIPE, cleanupBristolQuietly); signal(SIGHUP, cleanupBristol); signal(SIGUSR1, savehandler); signal(SIGUSR2, loadhandler); global.home = getenv("BRISTOL"); global.synths = (guiSynth *) brightonmalloc(sizeof(guiSynth)); global.controlfd = -1; global.voices = BRISTOL_VOICECOUNT; global.synths->voices = BRISTOL_VOICECOUNT; global.synths->pwd = 2; global.synths->gain = 32; global.synths->ladimem = 1024; global.synths->synthtype = BRISTOL_HAMMONDB3; global.synths->velocity = 510; /* linear tracking */ global.synths->glide = 5; /* maximum glide delay - up to 30s */ global.synths->detune = 40; global.synths->lowkey = 0; global.synths->highkey = 127; global.synths->lwf = 0; //3; global.synths->mbi = 0; global.synths->notepref = BRIGHTON_POLYPHONIC; global.synths->notetrig = 0; global.synths->win = NULL; global.synths->flags = REQ_FORWARD|REQ_LOCAL_FORWARD|REQ_REMOTE_FORWARD|NO_LATCHING_KEYS; global.port = 5028; snprintf(defaultcdev, 16, "localhost"); global.host = defaultcdev; memset(synthesisers, 0, sizeof(synthesisers)); synthesisers[BRISTOL_MINI] = &miniApp; synthesisers[BRISTOL_PROPHET] = &prophetApp; synthesisers[BRISTOL_PRO52] = &prophet52App; synthesisers[BRISTOL_HAMMOND] = &hammondB3App; synthesisers[BRISTOL_JUNO] = &junoApp; synthesisers[BRISTOL_DX] = &dxApp; synthesisers[BRISTOL_EXPLORER] = &explorerApp; synthesisers[BRISTOL_HAMMONDB3] = &hammondB3App; synthesisers[BRISTOL_VOX] = &voxApp; synthesisers[BRISTOL_RHODES] = &rhodesApp; synthesisers[BRISTOL_RHODES_BASS] = &rhodesBassApp; synthesisers[BRISTOL_PROPHET10] = &pro10App; synthesisers[BRISTOL_MIXER] = &mixApp; synthesisers[BRISTOL_OBX] = &obxApp; synthesisers[BRISTOL_OBXA] = &obxaApp; synthesisers[BRISTOL_POLY] = &polyApp; synthesisers[BRISTOL_POLY6] = &poly6App; synthesisers[BRISTOL_AXXE] = &axxeApp; synthesisers[BRISTOL_ODYSSEY] = &odysseyApp; synthesisers[BRISTOL_MEMMOOG] = &memMoogApp; synthesisers[BRISTOL_2600] = &arp2600App; synthesisers[BRISTOL_SAKS] = &sAksApp; synthesisers[BRISTOL_MS20] = &ms20App; synthesisers[BRISTOL_SOLINA] = &solinaApp; synthesisers[BRISTOL_ROADRUNNER] = &roadrunnerApp; synthesisers[BRISTOL_GRANULAR] = &granularApp; synthesisers[BRISTOL_REALISTIC] = &realisticApp; synthesisers[BRISTOL_VOXM2] = &voxM2App; synthesisers[BRISTOL_JUPITER8] = &jupiterApp; synthesisers[BRISTOL_BIT_ONE] = &bitoneApp; synthesisers[BRISTOL_MASTER] = &masterApp; synthesisers[BRISTOL_CS80] = &cs80App; synthesisers[BRISTOL_PRO1] = &pro1App; synthesisers[BRISTOL_VOYAGER] = &voyagerApp; synthesisers[BRISTOL_SONIC6] = &sonic6App; synthesisers[BRISTOL_TRILOGY] = &trilogyApp; synthesisers[BRISTOL_STRATUS] = &stratusApp; synthesisers[BRISTOL_POLY800] = &poly800App; synthesisers[BRISTOL_BME700] = &bme700App; synthesisers[BRISTOL_BASSMAKER] = &bmApp; synthesisers[BRISTOL_SID_M1] = &sidApp; synthesisers[BRISTOL_SID_M2] = &sid2App; readme[BRISTOL_PRO52] = readme[BRISTOL_PROPHET]; readme[BRISTOL_VOYAGER] = readme[BRISTOL_EXPLORER]; if (argc == 1) { printf("You probably prefer to use the startBristol script.\n"); exit(0); } if (strcmp(argv[1], "-console") == 0) logtype = BRISTOL_LOG_CONSOLE; if (strcmp(argv[1], "-readme") == 0) { readMe = 1; logtype = BRISTOL_LOG_CONSOLE; if (argc == 2) { printBrightonReadme(); exit(0); } } if (((strcmp(argv[argCount], "-V") == 0) || (strcmp(argv[argCount], "-version") == 0)) && (strlen(argv[argCount]) == 2)) { printf("Version %s\n", VERSION); exit(0); } if ((argc > 1) && (strcmp(argv[1], "--summary") == 0)) { printSummaryText(); exit(0); } if ((argc > 1) && (strcmp(argv[1], "-summary") == 0)) { printf("%s\n", summarytext); exit(0); } if (argc < 2) { printf("You probably prefer to use the startBristol script.\n"); exit(1); } if ((argc == 2) && ((strcmp(argv[argCount], "--help") == 0) || (strcmp(argv[argCount], "-help") == 0) || (strcmp(argv[argCount], "-h") == 0) || (strcmp(argv[argCount], "--h") == 0))) { #ifdef BRISTOL_BUILD if (BRISTOL_BUILD == 0) printf("bristol %i.%i.%i: ", BRISTOL_MAJOR, BRISTOL_MINOR, BRISTOL_PATCH); else printf("bristol %i.%i.%i-%i: ", BRISTOL_MAJOR, BRISTOL_MINOR, BRISTOL_PATCH, BRISTOL_BUILD); #else printf("bristol %s\n", VERSION); #endif printf("%s", helptext); exit(0); } if (readMe == 0) printf("%s", gplnotice); global.synths->location = 0; if ((getenv("BRISTOL_LOG_CONSOLE") != NULL) && (strcmp(getenv("BRISTOL_LOG_CONSOLE"), "true") == 0)) logtype = BRISTOL_LOG_CONSOLE; cli_fd[0] = 0;//dup(0); cli_fd[1] = 1;//dup(1); logthread = bristolOpenStdio(logtype); /* Set up a default SYSEX ID, may get changed later */ bristolMidiOption(0, BRISTOL_NRP_SYSID_H, 0x534C); bristolMidiOption(0, BRISTOL_NRP_SYSID_L, 0x6162); brightonFindEmulation(argc, argv); /* * close our standard input, create a pipe which will never be used. */ while (argc > argCount) { if ((strcmp(argv[argCount], "-log") == 0) && (logtype != BRISTOL_LOG_CONSOLE)) bristolOpenStdio(BRISTOL_LOG_DAEMON); if ((strcmp(argv[argCount], "-syslog") == 0) && (logtype != BRISTOL_LOG_CONSOLE)) bristolOpenStdio(BRISTOL_LOG_SYSLOG); if ((strcmp(argv[argCount], "-V") == 0) && (strlen(argv[argCount]) == 2)) { #ifdef BRISTOL_BUILD if (BRISTOL_BUILD == 0) printf("brighton version %i.%i.%i\n", BRISTOL_MAJOR, BRISTOL_MINOR, BRISTOL_PATCH); else printf("brighton version %i.%i.%i-%i\n", BRISTOL_MAJOR, BRISTOL_MINOR, BRISTOL_PATCH, BRISTOL_BUILD); #endif exit(0); } if (strcmp(argv[argCount], "-libtest") == 0) global.libtest = 1 - global.libtest; if (strcmp(argv[argCount], "-pixmap") == 0) library = 0; if ((strcmp(argv[argCount], "-synth") == 0) && (argCount < argc)) { int i; for (i = 0 ; i < BRISTOL_SYNTHCOUNT; i++) { if (synthesisers[i] == NULL) continue; if (strcmp(synthesisers[i]->name, argv[argCount + 1]) == 0) { printf("found %s at %i\n", synthesisers[i]->name, i); global.synths->synthtype = i; break; } } if (i == BRISTOL_SYNTHCOUNT) { printf("Could not find synth named \"%s\"\n", argv[argCount + 1]); exit(-1); } else { /* * We found the emulation, now we should put in the default * from its application definition. */ printf("emulation defaults:\n"); printf(" -voices %i\n", synthesisers[i]->emulate.voices); printf(" -detune: %i\n", synthesisers[i]->emulate.detune); printf(" -gain: %i\n", synthesisers[i]->emulate.gain); printf(" -pwd: %i\n", synthesisers[i]->emulate.pwd); printf(" -glide: %i\n", synthesisers[i]->emulate.glide); printf(" -curve: %i\n", synthesisers[i]->emulate.velocity); if ((global.synths->voices = synthesisers[i]->emulate.voices) < 0) global.synths->voices = BRISTOL_VOICECOUNT; global.synths->detune = synthesisers[i]->emulate.detune; global.synths->gain = synthesisers[i]->emulate.gain * 128; global.synths->pwd = synthesisers[i]->emulate.pwd; global.synths->glide = synthesisers[i]->emulate.glide; global.synths->velocity = synthesisers[i]->emulate.velocity; if (synthesisers[i]->emulate.opacity != 0) printf(" -opacity:%i\n", opacity = synthesisers[i]->emulate.opacity); if (global.synths->voices == 1) global.synths->notepref = BRIGHTON_HNP; devname = argv[argCount + 1]; } argCount++; continue; } if (((strcmp(argv[argCount], "-geometry") == 0) || (strcmp(argv[argCount], "-geom") == 0)) && (argCount < argc)) { int i = 0; char *yp; argCount++; /* * We want WxH+x+y * If we only have +-x+-y then don't apply w.h * If we have H+x+y then use H as a width and use it to scale * the image to a given bitmap. If we have W+H then automatically * set -ar. */ /* * Start looking for width */ while ((argv[argCount][i] != '-') && (argv[argCount][i] != '+') && (argv[argCount][i] != '\0') && (argv[argCount][i] != 'x')) { reqW = reqW * 10 + argv[argCount][i] - 48; i++; } if (argv[argCount][i] == 'x') i++; /* Look for height */ while ((argv[argCount][i] != '-') && (argv[argCount][i] != '+') && (argv[argCount][i] != '\0') && (argv[argCount][i] != 'x')) { reqH = reqH * 10 + argv[argCount][i] - 48; i++; } /* Take an X if it is available */ if (argv[argCount][i] != '\0') reqX = atoi(&argv[argCount][i]); if ((reqX == 0) && (argv[argCount][i] == '-')) reqX = -1; if ((yp = strchr(&argv[argCount][++i], '+'))) reqY = atoi(yp); else if ((yp = strchr(&argv[argCount][++i], '-'))) reqY = atoi(yp); if ((reqY == 0) && (argv[argCount][i] == '-')) reqY = -1; } if (strcmp(argv[argCount], "-iconify") == 0) bwflags &= ~BRIGHTON_POST_WINDOW; if ((strcmp(argv[argCount], "-quality") == 0) && (argCount < argc)) { if ((quality = atoi(argv[argCount + 1])) < 2) quality = 2; else if (quality > 8) quality = 8; argCount++; continue; } if ((strcmp(argv[argCount], "-aliastype") == 0) && (argCount < argc)) { /* * I want this to take a text value and if not recognised then * an integer. Text will be 'texture' or 'all'. */ if (strcmp(argv[argCount + 1], "texture") == 0) { aliastype = 1; argCount++; if (antialias == 0.0) antialias = 0.3; continue; } else if (strcmp(argv[argCount + 1], "pre") == 0) { aliastype = 5; argCount++; if (antialias == 0.0) antialias = 0.3; continue; } else if (strcmp(argv[argCount + 1], "all") == 0) { aliastype = 3; argCount++; if (antialias == 0.0) antialias = 0.3; continue; } else if ((aliastype = atoi(argv[argCount + 1])) < 0) { aliastype = 0; continue; } else if (aliastype > 4) { aliastype = 0; continue; } argCount++; continue; } if ((strcmp(argv[argCount], "-antialias") == 0) && (argCount < argc)) { if ((antialias = (float) atoi(argv[argCount + 1])) < 0) antialias = 0.0; else if (antialias > 99) antialias = 0.01; else antialias = 1.0 - antialias / 100.0; if (aliastype == 0) aliastype = 1; argCount++; continue; } if ((strcmp(argv[argCount], "-jsmuuid") == 0) && (argCount < argc)) { global.synths->ladimem += atoi(argv[argCount + 1]); argCount++; continue; } /* * LADI level 1 options: */ if ((strcmp(argv[argCount], "-ladi") == 0) && (argCount < argc)) { global.synths->flags |= LADI_ENABLE; if (strcmp(argv[argCount + 1], "both") == 0) global.synths->ladimode = 1; else if (strcmp(argv[argCount + 1], "bristol") == 0) global.synths->ladimode = 0; else if (strcmp(argv[argCount + 1], "brighton") == 0) global.synths->ladimode = 1; else { if ((global.synths->ladimem = atoi(argv[argCount + 1])) <= 0) { global.synths->ladimem = 1024; global.synths->ladiStateFile = argv[argCount + 1]; } } /* * We also need to force the startup to open this memory location * as well, that can get overridden if there is a -load option * anywhere later on the command line. */ global.synths->location = global.synths->ladimem; global.synths->mbi = (global.synths->location / 1000) * 1000; global.synths->location = global.synths->location % 1000; argCount++; continue; } if ((strcmp(argv[argCount], "-audiodev") == 0) && (argCount < argc)) { argCount++; devname = argv[argCount]; } if ((strcmp(argv[argCount], "-register") == 0) && (argCount < argc) && (argv[argCount + 1][0] != '-')) { argCount++; devname = argv[argCount]; } if ((strcmp(argv[argCount], "-lowkey") == 0) && (argCount < argc)) { argCount++; global.synths->lowkey = atoi(argv[argCount]); } if ((strcmp(argv[argCount], "-highkey") == 0) && (argCount < argc)) { argCount++; global.synths->highkey = atoi(argv[argCount]); } if (strcmp(argv[argCount], "-rate") == 0) { if ((sampleRate = atoi(argv[argCount + 1])) <= 0) sampleRate = 44100; argCount++; continue; } if (strcmp(argv[argCount], "-count") == 0) { if ((sampleCount = atoi(argv[argCount + 1])) <= 0) sampleCount = 256; argCount++; continue; } if (((strcmp(argv[argCount], "-activesense") == 0) || (strcmp(argv[argCount], "-as") == 0)) && (argCount < argc)) { activeSense = atoi(argv[argCount + 1]); if ((activeSense != 0) && (activeSense < 50)) activeSense = 50; /* * This is now set to the default timer to pass to the engine * It is defaulted to three times the update rate. We should do * a quick check to ensure this is larger than the sample period * count by a little bit but we can only do that later. */ if (activeSense > 5000) activeSense = 5000; if ((activeSensePeriod = activeSense * 3) > 16000) activeSensePeriod = 16000; argCount++; } if ((strcmp(argv[argCount], "-ast") == 0) && (argCount < argc)) { if ((activeSensePeriod = atoi(argv[argCount + 1])) < 50) activeSensePeriod = 50; if (activeSensePeriod < activeSense * 2) activeSensePeriod = activeSense * 3; if (activeSensePeriod > 16000) activeSensePeriod = 16000; /* * This is now set to the default timer to pass to the engine * It is defaulted to three times the update rate. activeSensePeriod = activeSensePeriod * sampleRate / 1000; */ argCount++; } if (strcmp(argv[argCount], "-gmc") == 0) gmc = 1; if ((strcmp(argv[argCount], "-mct") == 0) && (argCount < argc)) { if ((mwt = atoi(argv[argCount + 1]) * 1000) < 0) mwt = 50000; argCount++; } if ((strcmp(argv[argCount], "-dct") == 0) && (argCount < argc)) { if ((dcTimeout = atoi(argv[argCount + 1]) * 1000) < 10000) dcTimeout = 250000; argCount++; } if ((strcmp(argv[argCount], "-opacity") == 0) && (argCount < argc)) { if ((opacity = atoi(argv[argCount + 1])) < 20) opacity = 20; else if (opacity > 100) opacity = 100; argCount++; continue; } if ((strcmp(argv[argCount], "-width") == 0) && (argCount < argc)) { deswidth = atoi(argv[argCount + 1]); argCount++; } if ((strcmp(argv[argCount], "-scale") == 0) && (argCount < argc)) { if ((strcmp(argv[argCount + 1], "fs") == 0) || (strcmp(argv[argCount + 1], "fullscreen") == 0)) { aliastype = 5; scale = 100.0; argCount++; continue; } if ((scale = atof(argv[argCount + 1])) > 0) { if ((scale > 1.1) || (scale < 0.9)) aliastype = 5; else aliastype = 0; argCount++; continue; } scale = 1.0; } if (strcmp(argv[argCount], "-raise") == 0) rlflags &= ~BRIGHTON_SET_RAISE; if (strcmp(argv[argCount], "-lower") == 0) rlflags &= ~BRIGHTON_SET_LOWER; if ((strcmp(argv[argCount], "-rotaryUD") == 0) || (strcmp(argv[argCount], "-rud") == 0)) rlflags |= BRIGHTON_ROTARY_UD; if (strcmp(argv[argCount], "-autozoom") == 0) { azoom = 1; if (deswidth < 1) deswidth = 100; } if ((strcmp(argv[argCount], "-ar") == 0) || (strcmp(argv[argCount], "-nar") == 0) || (strcmp(argv[argCount], "-aspect") == 0)) nar = 1; if (((strcmp(argv[argCount], "-gs") == 0) || (strcmp(argv[argCount], "-grayscale") == 0) || (strcmp(argv[argCount], "-greyscale") == 0)) && (argCount < argc)) { gs = atoi(argv[argCount + 1]); argCount++; } if ((strcmp(argv[argCount], "-detune") == 0) && (argCount < argc)) { if (argCount < argc) global.synths->detune = atoi(argv[argCount + 1]); argCount++; } if ((strcmp(argv[argCount], "-gain") == 0) && (argCount < argc)) { if (argCount < argc) global.synths->gain = atoi(argv[argCount + 1]) * 128; argCount++; } if ((strcmp(argv[argCount], "-pwd") == 0) && (argCount < argc)) { if (argCount < argc) global.synths->pwd = atoi(argv[argCount + 1]); argCount++; } /* Need to add in PitchWheel Depth (done), Find and Coarse tuning*/ if (strcmp(argv[argCount], "-neutral") == 0) global.synths->location = -1; if ((strcmp(argv[argCount], "-load") == 0) && (argCount < argc)) { if (argCount < argc) global.synths->location = atoi(argv[argCount + 1]); global.synths->mbi = (global.synths->location / 1000) * 1000; global.synths->location = global.synths->location % 1000; argCount++; } /* SYSEX System ID */ if ((strcmp(argv[argCount], "-sysid") == 0) && (argCount < argc)) { unsigned int sysid = 0x534C6162, o = argCount + 1; /* * We will get 0x534C6162 for example */ if ((argv[o][0] == '0') || (argv[o][1] == 'x') || (strlen(argv[o]) == 10)) { sscanf(argv[o], "0x%x", &sysid); sysid &= 0x7f7f7f7f; bristolMidiOption(0, BRISTOL_NRP_SYSID_H, sysid >> 16); bristolMidiOption(0, BRISTOL_NRP_SYSID_L, sysid & 0x0000ffff); printf("fixing sysex system id at 0x%x\n", sysid); } } if ((strcmp(argv[argCount], "-nrpcc") == 0) && (argCount < argc)) { nrpcc = atoi(argv[argCount + 1]); printf("Reserving %i NRP controllers\n", nrpcc); argCount++; } /* Master Bank Index */ if ((strcmp(argv[argCount], "-mbi") == 0) && (argCount < argc)) { int mbi; if (argCount < argc) mbi = atoi(argv[argCount + 1]) * 1000; if ((global.synths->mbi != 0) && (global.synths->mbi != mbi)) printf("Master bank index and loaded memory conflict (%i/%i)\n", mbi/1000, global.synths->mbi/1000); global.synths->mbi = mbi; argCount++; } if ((strcmp(argv[argCount], "-glide") == 0) && (argCount < argc)) { if (argCount < argc) global.synths->glide = atoi(argv[argCount + 1]); if (global.synths->glide <= 0) global.synths->glide = 30; if (global.synths->glide > 30) global.synths->glide = 30; argCount++; } if ((strcmp(argv[argCount], "-voices") == 0) && (argCount < argc)) { if ((atoi(argv[argCount + 1]) > 0) && ((global.synths->voices = atoi(argv[argCount + 1])) == 1) && (global.synths->notepref == BRIGHTON_POLYPHONIC)) global.synths->notepref = BRIGHTON_HNP; else if (atoi(argv[argCount + 1]) == 0) global.synths->voices = BRISTOL_VOICECOUNT; argCount++; } if (strcmp(argv[argCount], "-mono") == 0) { global.synths->voices = 1; global.synths->notepref = BRIGHTON_HNP; } if (strcmp(argv[argCount], "-localforward") == 0) global.synths->flags &= ~REQ_LOCAL_FORWARD; if (strcmp(argv[argCount], "-remoteforward") == 0) global.synths->flags &= ~REQ_REMOTE_FORWARD; if (strcmp(argv[argCount], "-forward") == 0) global.synths->flags &= ~(REQ_FORWARD|REQ_LOCAL_FORWARD|REQ_REMOTE_FORWARD); if (strcmp(argv[argCount], "-mididbg2") == 0) global.synths->flags |= REQ_MIDI_DEBUG2; if ((strcmp(argv[argCount], "-mididbg") == 0) || (strcmp(argv[argCount], "-mididbg1") == 0)) global.synths->flags |= REQ_MIDI_DEBUG; if (strcmp(argv[argCount], "-debug") == 0) { if ((argCount < argc) && (argv[argCount + 1][0] != '-')) { int i; if ((i = atoi(argv[argCount + 1])) > 15) global.synths->flags |= REQ_DEBUG_MASK; else { global.synths->flags &= ~REQ_DEBUG_MASK; global.synths->flags |= (i << 12); } } else { /* * If we only have -debug and no value then increment the debug * level. */ global.synths->flags = (global.synths->flags & ~REQ_DEBUG_MASK) | (((global.synths->flags & REQ_DEBUG_MASK) + REQ_DEBUG_1) & REQ_DEBUG_MASK); } if (global.synths->flags & REQ_DEBUG_MASK) printf("debuging level set to %i\n", (global.synths->flags&REQ_DEBUG_MASK)>>12); } if (strcmp(argv[argCount], "-gnrp") == 0) global.synths->flags ^= GUI_NRP; if (strcmp(argv[argCount], "-enrp") == 0) global.synths->flags ^= MIDI_NRP; if (strcmp(argv[argCount], "-nrp") == 0) global.synths->flags |= MIDI_NRP|GUI_NRP; if ((strcmp(argv[argCount], "-channel") == 0) && (argCount < argc)) { if (argCount < argc) global.synths->midichannel = atoi(argv[argCount + 1]) - 1; argCount++; } if (((strcmp(argv[argCount], "-velocity") == 0) || (strcmp(argv[argCount], "-curve") == 0) || (strcmp(argv[argCount], "-mvc") == 0)) && (argCount < argc)) { if (argCount < argc) global.synths->velocity = atoi(argv[argCount + 1]); argCount++; } if (strcmp(argv[argCount], "-tracking") == 0) { global.synths->flags |= NO_KEYTRACK; argCount++; } if (strcmp(argv[argCount], "-keytoggle") == 0) global.synths->flags &= ~NO_LATCHING_KEYS; if (strcmp(argv[argCount], "-port") == 0) { if ((argCount < (argc - 1)) && (argv[argCount + 1] != NULL)) global.port = atoi(argv[argCount + 1]); argCount++; } if (strcmp(argv[argCount], "-host") == 0) snprintf(defaultcdev, 16, "%s", argv[++argCount]); if (strcmp(argv[argCount], "-window") == 0) synthesisers[global.synths->synthtype]->flags ^= BRIGHTON_WINDOW; if (strcmp(argv[argCount], "-cli") == 0) { cli = 1; brightonCLIinit(&global, cli_fd); //synthesisers[global.synths->synthtype]->flags ^= BRIGHTON_WINDOW; } if (strcmp(argv[argCount], "-nwf") == 0) global.synths->lwf = 0; if (strcmp(argv[argCount], "-lwf") == 0) global.synths->lwf = 1; if (strcmp(argv[argCount], "-lwf2") == 0) global.synths->lwf = 2; if (strcmp(argv[argCount], "-wwf") == 0) global.synths->lwf = 2; if (strcmp(argv[argCount], "-hwf") == 0) global.synths->lwf = 3; if (strcmp(argv[argCount], "-lnp") == 0) global.synths->notepref = BRIGHTON_LNP; if (strcmp(argv[argCount], "-hnp") == 0) global.synths->notepref = BRIGHTON_HNP; if (strcmp(argv[argCount], "-nnp") == 0) global.synths->notepref = BRIGHTON_POLYPHONIC; if (strcmp(argv[argCount], "-retrig") == 0) global.synths->notetrig = 1 - global.synths->notetrig; if (strcmp(argv[argCount], "-lvel") == 0) global.synths->legatovelocity = 1 - global.synths->legatovelocity; /* * And finally all the different synths */ if ((strcmp(argv[argCount], "-mini") == 0) ||(strcmp(argv[argCount], "-minimoog") == 0)) global.synths->synthtype = BRISTOL_MINI; if (strcmp(argv[argCount], "-hammond") == 0) global.synths->synthtype = BRISTOL_HAMMONDB3; if (strcmp(argv[argCount], "-prophet10") == 0) global.synths->synthtype = BRISTOL_PROPHET10; if ((strcmp(argv[argCount], "-pro1") == 0) || (strcmp(argv[argCount], "-proone") == 0) || (strcmp(argv[argCount], "-prophet1") == 0)) { global.synths->synthtype = BRISTOL_PRO1; opacity = 60; } if ((strcmp(argv[argCount], "-pro52") == 0) || (strcmp(argv[argCount], "-prophet52") == 0)) global.synths->synthtype = BRISTOL_PRO52; if ((strcmp(argv[argCount], "-prophet") == 0) || (strcmp(argv[argCount], "-sequential") == 0) || (strcmp(argv[argCount], "-sequentialcircuits") == 0) || (strcmp(argv[argCount], "-prophet5") == 0)) global.synths->synthtype = BRISTOL_PROPHET; if (strcmp(argv[argCount], "-prophet10") == 0) global.synths->synthtype = BRISTOL_PROPHET10; if (strcmp(argv[argCount], "-pro5") == 0) global.synths->synthtype = BRISTOL_PROPHET; if (strcmp(argv[argCount], "-pro10") == 0) { if (global.synths->detune == 0) global.synths->detune = NON_DEF_DETUNE; global.synths->synthtype = BRISTOL_PROPHET10; } if (strcmp(argv[argCount], "-dx") == 0) global.synths->synthtype = BRISTOL_DX; if (strcmp(argv[argCount], "-juno") == 0) global.synths->synthtype = BRISTOL_JUNO; if (strcmp(argv[argCount], "-cs80") == 0) { global.synths->synthtype = BRISTOL_CS80; printf("The CS80 is not an operational emulator\n"); global.libtest = 1; } if ((strcmp(argv[argCount], "-jupiter8") == 0) || (strcmp(argv[argCount], "-uranus") == 0) || (strcmp(argv[argCount], "-jupiter") == 0)) { if (global.synths->voices == BRISTOL_VOICECOUNT) global.synths->voices = 8; /* Two 4 voice Jupiters */ if (global.synths->detune == 0) global.synths->detune = NON_DEF_DETUNE; global.synths->synthtype = BRISTOL_JUPITER8; opacity = 40; } if (strcmp(argv[argCount], "-sampler") == 0) { global.synths->synthtype = BRISTOL_SAMPLER; printf("The sampler is not an operational emulator\n"); global.libtest = 1; } if (strcmp(argv[argCount], "-bristol") == 0) global.synths->synthtype = BRISTOL_BRISTOL; if (strcmp(argv[argCount], "-voyager") == 0) global.synths->synthtype = BRISTOL_EXPLORER; if (strcmp(argv[argCount], "-sonic6") == 0) global.synths->synthtype = BRISTOL_SONIC6; if (strcmp(argv[argCount], "-explorer") == 0) global.synths->synthtype = BRISTOL_EXPLORER; if (strcmp(argv[argCount], "-voyager") == 0) global.synths->synthtype = BRISTOL_VOYAGER; if (strcmp(argv[argCount], "-mixer") == 0) { global.libtest = 1; printf("The bristol mixer is not an operational emulator\n"); global.synths->synthtype = BRISTOL_MIXER; } if (strcmp(argv[argCount], "-rhodesbass") == 0) global.synths->synthtype = BRISTOL_RHODES_BASS; else if (strcmp(argv[argCount], "-rhodes") == 0) global.synths->synthtype = BRISTOL_RHODES; if (strcmp(argv[argCount], "-vox") == 0) global.synths->synthtype = BRISTOL_VOX; if ((strcmp(argv[argCount], "-voxm2") == 0) || (strcmp(argv[argCount], "-voxM2") == 0) || (strcmp(argv[argCount], "-vox300") == 0)) global.synths->synthtype = BRISTOL_VOXM2; if (strcmp(argv[argCount], "-ddd") == 0) global.synths->synthtype = BRISTOL_DDD; if (strcmp(argv[argCount], "-b3") == 0) global.synths->synthtype = BRISTOL_HAMMONDB3; if (strcmp(argv[argCount], "-obxa") == 0) { if (global.synths->detune == 0) global.synths->detune = NON_DEF_DETUNE; global.synths->synthtype = BRISTOL_OBXA; if (opacity == 40) opacity = 60; } else if (strcmp(argv[argCount], "-obx") == 0) { if (global.synths->detune == 0) global.synths->detune = NON_DEF_DETUNE; global.synths->synthtype = BRISTOL_OBX; } if (strcmp(argv[argCount], "-moog") == 0) global.synths->synthtype = BRISTOL_MINI; if (strcmp(argv[argCount], "-arp") == 0) global.synths->synthtype = BRISTOL_2600; if (strcmp(argv[argCount], "-roland") == 0) global.synths->synthtype = BRISTOL_JUNO; if (strcmp(argv[argCount], "-oberheim") == 0) global.synths->synthtype = BRISTOL_OBXA; if ((strcmp(argv[argCount], "-polysix") == 0) || (strcmp(argv[argCount], "-korg") == 0) || (strcmp(argv[argCount], "-poly6") == 0) || (strcmp(argv[argCount], "-poly") == 0)) global.synths->synthtype = BRISTOL_POLY6; if (strcmp(argv[argCount], "-monopoly") == 0) global.synths->synthtype = BRISTOL_POLY; if (strcmp(argv[argCount], "-poly800") == 0) { global.synths->synthtype = BRISTOL_POLY800; global.synths->voices = 8; } if (strcmp(argv[argCount], "-ms20") == 0) { global.synths->synthtype = BRISTOL_MS20; printf("The ms20 is not an operational emulator\n"); global.libtest = 1; } if (strcmp(argv[argCount], "-bme700") == 0) { global.synths->synthtype = BRISTOL_BME700; global.synths->voices = 1; global.synths->notepref = BRIGHTON_HNP; } if ((strcmp(argv[argCount], "-bassmaker") == 0) || (strcmp(argv[argCount], "-bm") == 0)) { global.synths->synthtype = BRISTOL_BASSMAKER; global.synths->voices = 1; } if ((strcmp(argv[argCount], "-sid") == 0) || (strcmp(argv[argCount], "-sidney") == 0)) { global.synths->synthtype = BRISTOL_SID_M1; global.synths->voices = 1; global.synths->notepref = BRIGHTON_LNP; global.synths->notetrig = 1; antialias = 0.5; aliastype = 1; opacity = 50; } if ((strcmp(argv[argCount], "-sid2") == 0) || (strcmp(argv[argCount], "-melbourne") == 0) || (strcmp(argv[argCount], "-canberra") == 0) || (strcmp(argv[argCount], "-perth") == 0) || (strcmp(argv[argCount], "-resid") == 0) || (strcmp(argv[argCount], "-asid") == 0) || (strcmp(argv[argCount], "-acid") == 0)) { global.synths->synthtype = BRISTOL_SID_M2; global.synths->voices = 1; global.synths->notepref = BRIGHTON_HNP; global.synths->notetrig = 1; antialias = 0.5; aliastype = 1; opacity = 50; } if (strcmp(argv[argCount], "-arp2600") == 0) global.synths->synthtype = BRISTOL_2600; if (strcmp(argv[argCount], "-2600") == 0) global.synths->synthtype = BRISTOL_2600; if (strcmp(argv[argCount], "-axxe") == 0) global.synths->synthtype = BRISTOL_AXXE; if (strcmp(argv[argCount], "-odyssey") == 0) global.synths->synthtype = BRISTOL_ODYSSEY; if (strcmp(argv[argCount], "-solina") == 0) global.synths->synthtype = BRISTOL_SOLINA; if (strcmp(argv[argCount], "-roadrunner") == 0) global.synths->synthtype = BRISTOL_ROADRUNNER; if ((strcmp(argv[argCount], "-memory") == 0) || (strcmp(argv[argCount], "-memmoog") == 0) || (strcmp(argv[argCount], "-memorymoog") == 0)) global.synths->synthtype = BRISTOL_MEMMOOG; if ((strcmp(argv[argCount], "-mas") == 0) || (strcmp(argv[argCount], "-ems") == 0) || (strcmp(argv[argCount], "-aks") == 0)) { global.synths->synthtype = BRISTOL_SAKS; printf("AKS is not an operational emulator\n"); global.libtest = 1; } if ((strcmp(argv[argCount], "-granular") == 0) || (strcmp(argv[argCount], "-quantum") == 0)) { global.synths->synthtype = BRISTOL_GRANULAR; printf("The granular is not an operational emulator\n"); global.libtest = 1; } if ((strcmp(argv[argCount], "-realistic") == 0) || (strcmp(argv[argCount], "-mg1") == 0)) global.synths->synthtype = BRISTOL_REALISTIC; #define BIT1_ACTIVE 200 /* * Also add some hacks for a bit-99, same algorithm but different * GUI template */ if ((strcmp(argv[argCount], "-bitone") == 0) || (strcmp(argv[argCount], "-crumar") == 0) || (strcmp(argv[argCount], "-bit01") == 0) || (strcmp(argv[argCount], "-bit1") == 0)) { int i; if (global.synths->detune == 0) global.synths->detune = NON_DEF_DETUNE; global.synths->synthtype = BRISTOL_BIT_ONE; for (i = 68; i < 77; i++) bit99App.resources[0].devlocn[i].flags |= BRIGHTON_WITHDRAWN; if (opacity == 40) opacity = 60; bit99App.resources[0].devlocn[48].flags |= BRIGHTON_WITHDRAWN; /* * Hide the stereo button */ bit99App.resources[0].devlocn[BIT1_ACTIVE + 2].flags |= BRIGHTON_WITHDRAWN; bit99App.resources[0].devlocn[BIT1_ACTIVE + 2].x = 50; bit99App.resources[0].devlocn[BIT1_ACTIVE + 2].y = 50; /* And add the unison button */ bit99App.resources[0].devlocn[BIT1_ACTIVE + 38].flags &= ~BRIGHTON_WITHDRAWN; } /* * The bit-99 hack, same algorithm but different GUI template */ if (strcmp(argv[argCount], "-bit99") == 0) { synthesisers[BRISTOL_BIT_ONE] = &bit99App; global.synths->synthtype = BRISTOL_BIT_ONE; if (global.synths->detune == 0) global.synths->detune = NON_DEF_DETUNE; if (opacity == 40) opacity = 60; /* * Enable a few extra parameters. bit99App.resources[0].devlocn[77].flags &= ~BRIGHTON_WITHDRAWN; bit99App.resources[0].devlocn[78].flags &= ~BRIGHTON_WITHDRAWN; bit99App.resources[0].devlocn[79].flags &= ~BRIGHTON_WITHDRAWN; bit99App.resources[0].devlocn[80].flags &= ~BRIGHTON_WITHDRAWN; */ bit99App.resources[0].devlocn[12].flags &= ~BRIGHTON_WITHDRAWN; bit99App.resources[0].devlocn[BIT1_ACTIVE - 1].flags &= ~BRIGHTON_WITHDRAWN; /* Show the stereo button */ bit99App.resources[0].devlocn[BIT1_ACTIVE + 2].flags &= ~BRIGHTON_WITHDRAWN; /* And remove the unison button */ bit99App.resources[0].devlocn[BIT1_ACTIVE + 38].flags |= BRIGHTON_WITHDRAWN; } /* * The bit-99 black hack, same algorithm but different GUI template */ if ((strcmp(argv[argCount], "-bit99m2") == 0) || (strcmp(argv[argCount], "-bit100") == 0)) { synthesisers[BRISTOL_BIT_ONE] = &bit100App; global.synths->synthtype = BRISTOL_BIT_ONE; if (global.synths->detune == 0) global.synths->detune = NON_DEF_DETUNE; if (opacity == 40) opacity = 60; /* * Enable a few extra parameters. */ bit100App.resources[0].devlocn[88].flags &= ~BRIGHTON_WITHDRAWN; // bit100App.resources[0].devlocn[74].flags |= BRIGHTON_WITHDRAWN; // bit100App.resources[0].devlocn[75].flags |= BRIGHTON_WITHDRAWN; // bit100App.resources[0].devlocn[76].flags |= BRIGHTON_WITHDRAWN; bit100App.resources[0].devlocn[78].flags &= ~BRIGHTON_WITHDRAWN; bit100App.resources[0].devlocn[79].flags &= ~BRIGHTON_WITHDRAWN; bit100App.resources[0].devlocn[80].flags &= ~BRIGHTON_WITHDRAWN; bit100App.resources[0].devlocn[12].flags &= ~BRIGHTON_WITHDRAWN; bit100App.resources[0].devlocn[199].flags &= ~BRIGHTON_WITHDRAWN; /* Show the stereo button */ bit100App.resources[0].devlocn[BIT1_ACTIVE + 2].flags &= ~BRIGHTON_WITHDRAWN; /* And remove the unison button */ bit100App.resources[0].devlocn[BIT1_ACTIVE + 38].flags |= BRIGHTON_WITHDRAWN; bit100App.resources[0].devlocn[BIT1_ACTIVE - 5].flags |= BRIGHTON_CHECKBUTTON; } if (strcmp(argv[argCount], "-trilogy") == 0) { global.synths->synthtype = BRISTOL_TRILOGY; global.synths->detune = 150; opacity = 60; } if (strcmp(argv[argCount], "-stratus") == 0) { global.synths->synthtype = BRISTOL_STRATUS; global.synths->detune = 150; opacity = 60; } argCount++; } if (strncmp("unix:", defaultcdev, 5) == 0) { if (strlen(defaultcdev) == 5) snprintf(defaultcdev, 16, "unix:%i", global.port); else global.port = atoi(&defaultcdev[5]); } #ifndef BRIGHTON_HAS_X11 /* Reverse the window logic */ synthesisers[global.synths->synthtype]->flags ^= BRIGHTON_WINDOW; #endif if (reqW) { /* Width is a scaler */ float scale; scale = ((float) reqW) / synthesisers[global.synths->synthtype]->width; /* Have been given some width value */ if (reqH) { nar = 1; synthesisers[global.synths->synthtype]->width = reqW; synthesisers[global.synths->synthtype]->height = reqH; } else { synthesisers[global.synths->synthtype]->width = reqW; synthesisers[global.synths->synthtype]->height *= scale; } if ((scale > 1.1) || (scale < 0.9)) aliastype = 5; else aliastype = 0; } { char statfile[1024]; struct stat statres; sprintf(statfile, "%s/%s.gz", getenv("BRISTOL"), synthesisers[global.synths->synthtype]->resources[0].image); if ((synthesisers[global.synths->synthtype]->resources[0].image != 0) && (stat(statfile, &statres) != 0)) { sprintf(statfile, "%s/%s", getenv("BRISTOL"), synthesisers[global.synths->synthtype]->resources[0].image); if (stat(statfile, &statres) != 0) { printf("unknown emulator\n"); sleep(1); exit(-1); } } } if (readMe) { printBrightonHelp(global.synths->synthtype); exit(0); } printf("brighton version %s\n", VERSION); sleep(1); printf(" %s", argv[0]); for (i = 1; i < argc; i++) { if (argv[i][0] == '-') printf("\n %s", argv[i]); else printf(" %s", argv[i]); } printf("\n"); /* * Hm, this is a joke really. The Tandy, Realistic, whatever, is an old * synth and this mimics random slider changes. Should not really do it * but its fun: the original used to lose its white caps. Once the gui is * created its more work to change the image. */ if (global.synths->synthtype == BRISTOL_REALISTIC) { int cont, i; struct timeval now; gettimeofday(&now, NULL); srand(now.tv_usec); for (i = 0; i < 6; i++) { cont = rand() & 0x01f; if (synthesisers[BRISTOL_REALISTIC]->resources[0].devlocn[cont].device == 1) { synthesisers[BRISTOL_REALISTIC]->resources[0].devlocn[cont].image = "bitmaps/knobs/knob8.xpm"; } } } if (synthesisers[global.synths->synthtype] == 0) exit(0); global.synths->resources = synthesisers[global.synths->synthtype]; synthesisers[global.synths->synthtype]->width *= scale; synthesisers[global.synths->synthtype]->height *= scale; /* * Finally go and let the event manager handle our interface. Going to * create a separate GUI thread, which will allow us to handle things like * MIDI events from the engine, timed operations, etc, from there. */ if (pthread_create(&emgrThread, NULL, eventMgr, &global) != 0) printf("Could not create GUI thread\n"); /* * We should not detach the thread, we should wait for it later before exit if (pthread_detach(thread) != 0) printf("Could not detach GUI thread\n"); */ /* * win is actually set by the configuration routines, but we use it * here anyway. The configuration options are a structure, they were a * list of parameters however that became unwieldy. */ if ((global.synths->flags & REQ_DEBUG_MASK) >= (REQ_DEBUG_4|REQ_DEBUG_1)) aliastype |= BRIGHTON_LIB_DEBUG; synthesisers[global.synths->synthtype]->flags |= bwflags; /* * We play around with the names here so that the window title gets filled * with more information than just the emulator name. This enhancement was * added for JSM but could be any Jack installation. If multiple instances * of the same emulator are started then it is not clear which is which: * both have the same title bar but different names in Jack. What we do here * is add the Jack registration name to the title bar. */ snprintf(appname, 64, "%s (%s)", synthesisers[global.synths->synthtype]->name, devname); devname = synthesisers[global.synths->synthtype]->name; synthesisers[global.synths->synthtype]->name = appname; if ((global.synths->win = brightonInterface(synthesisers[global.synths->synthtype], quality, library, aliastype, antialias, gs, reqX, reqY)) == NULL) { printf("could not create window\n"); exit(-1); } synthesisers[global.synths->synthtype]->name = devname; global.synths->resources->name = devname; /* * We now need to decide which memory to load. There are a few choices. * If we had a LADI declaration it will have been copied to both ladimem * and to the emulator memory. If they are still the same then use it. * * If the emulator location has change then we should look and see if the * LADI memory actually exists, if so, use it (overwrite the emulator * memory location again). If it does not exist we will then continue to * access the emulator memory and it becomes the template for the eventual * LADI state information. */ if ((global.synths->flags & LADI_ENABLE) && (global.synths->ladimem != (global.synths->location + global.synths->mbi))) { int memHold = global.synths->location + global.synths->mbi; global.synths->mbi = 0; global.synths->location = global.synths->ladimem; /* Location has changed. Stat the ladimem */ if (loadMemory(global.synths, global.synths->resources->name, 0, global.synths->ladimem, global.synths->mem.active, 0, BRISTOL_STAT) < 0) { /* No LADI mem */ global.synths->location = memHold; global.synths->mbi = (global.synths->location / 1000) * 1000; global.synths->location = global.synths->location % 1000; printf("did not find LADI memory %i, using %i\n", global.synths->ladimem, memHold); } else printf("using LADI state memory %i\n", global.synths->ladimem); } if (global.flags & REQ_EXIT) { printf("early termination logging thread (%i)\n", global.controlfd); bristolOpenStdio(BRISTOL_LOG_TERMINATE); if ((logthread != 0) && (pthread_join(logthread, NULL) != 0)) return(1); exit(global.controlfd < 0? 1: 0); } global.synths->win->dcTimeout = dcTimeout; global.synths->win->flags |= rlflags; if (azoom) { global.synths->win->flags |= BRIGHTON_AUTOZOOM; if (deswidth >= 100) { global.synths->win->minw = deswidth; global.synths->win->minh = deswidth * global.synths->win->template->height / global.synths->win->template->width; global.synths->win->maxw = synthesisers[global.synths->synthtype]->width * scale; global.synths->win->maxh = synthesisers[global.synths->synthtype]->height * scale; } else { global.synths->win->minw = global.synths->win->maxw = global.synths->win->minh = global.synths->win->maxh = 0; } } if (nar) global.synths->win->flags |= BRIGHTON_NO_ASPECT; brightonOpacity(global.synths->win, ((float) opacity) / 100.0f); /* * These should be synth specific? */ for (i = 0; i < 128; i++) { global.synths->win->midimap[i] = i; for (j = 0; j < 128; j++) global.synths->win->valuemap[i][j] = j; } printf("user r %i/%i, e %i/%i\n", getuid(), getgid(), geteuid(), getegid()); global.synths->win->nrpcount = nrpcc; global.synths->win->nrpcontrol = malloc(sizeof(brightonNRPcontrol) * nrpcc); memset(global.synths->win->nrpcontrol, 0, sizeof(brightonNRPcontrol) * nrpcc); brightonReadConfiguration(global.synths->win, synthesisers[global.synths->synthtype], global.synths->midichannel, synthesisers[global.synths->synthtype]->name, NULL); if (bristolMidiSendMsg(global.controlfd, global.synths->sid, BRISTOL_ACTIVE_SENSE, 0, activeSense == 0? 0:16383) != 0) { printf("Active sense transmit failure\n"); sleep(1); exit(1); } if (global.synths->flags & REQ_MIDI_DEBUG) printf("Sent Active sense\n"); if ((global.synths->sid2 > 0) && (bristolMidiSendMsg(global.manualfd, global.synths->sid2, BRISTOL_ACTIVE_SENSE, 0, activeSense == 0? 0:16383) != 0)) { printf("Active sense transmit failure\n"); sleep(1); exit(1); } if (global.synths->flags & REQ_MIDI_DEBUG) printf("Sent Active sense on second channel\n"); emStart = 1; if (global.libtest != 1) { if (global.synths->flags & REQ_FORWARD) bristolMidiOption(0, BRISTOL_NRP_FORWARD, 1); if (global.synths->flags & NO_KEYTRACK) bristolMidiOption(0, BRISTOL_NRP_MIDI_GO, 0); else bristolMidiOption(0, BRISTOL_NRP_MIDI_GO, 1); /* * The Hammond needs a note event on the upper manual to kick the * gearbox into action. */ if (global.synths->synthtype == BRISTOL_HAMMONDB3) { sleep(1); bristolMidiSendMsg(global.controlfd, global.synths->midichannel, BRISTOL_EVENT_KEYON, 0, 10 + global.synths->transpose); usleep(50000); bristolMidiSendMsg(global.controlfd, global.synths->midichannel, BRISTOL_EVENT_KEYOFF, 0, 10 + global.synths->transpose); } } /* if we are CLI, somebody needs to force this to happen */ if (synthesisers[global.synths->synthtype]->flags & BRIGHTON_WINDOW) brightonWorldChanged(global.synths->win, 500, 500); /* if (cli == 0) { close(cli_fd[0]); close(cli_fd[1]); } */ while (~global.flags & REQ_EXIT) { /* * Do whatever we want. Will turn into a wait routine on the MIDI * channel. This could be merged with the UI heartbeat code. */ if (cli) { if (brightonCLIcheck(&global) < 0) cleanupBristol(); } /* * This was never operational anyway: if (vuInterval != 0) { usleep(vuInterval); if (global.synths->flags & OPERATIONAL) doAlarm(); } else if (cli == 0) */ else sleep(1); } if (pthread_join(emgrThread, NULL) != 0) printf("brighton event thread exit error\n"); else printf("brighton event thread exited\n"); /* Now that the event manager thread has exit, put key repeat back on */ BAutoRepeat(global.synths->win->display, 1); printf("terminating logging thread (%i)\n", global.controlfd); if (global.libtest == 0) sleep(1); bristolOpenStdio(BRISTOL_LOG_TERMINATE); if ((logthread != 0) && (pthread_join(logthread, NULL) != 0)) return(1); exit(global.controlfd < 0? 1: 0); } void * eventMgr() { bristolMidiMsg msg; int i = 50, r; int midiFD, cFD; /* This will send activesense as soon as the interface initialises */ asc = activeSense * 4; printf("starting event management thread\n"); if (global.libtest == 0) { while (global.controlfd < 0) { usleep(100000); if (i-- < 0) { global.flags |= REQ_EXIT; pthread_exit(0); } } /* * Here we should open an ALSA SEQ interface. We want to get an index * back and pass that to the event handler for selection. This should * not really be a SEQ interface, it should depend on the flags given * to the GUI. */ if (gmc) { if ((midiHandle = bristolMidiOpen("brighton", BRISTOL_CONN_SEQ|BRISTOL_RDONLY, -1, -1, brightonMidiInput, &global)) < 0) printf("Error opening midi device %s\n", "0.0"); } } while (global.synths->win == NULL) { usleep(100000); printf("waiting for window creation\n"); } midiFD = bristolGetMidiFD(midiHandle); cFD = bristolGetMidiFD(global.controlfd); printf("opened GUI midi handles: %i, %i\n", midiFD, cFD); /* if (global.libtest != 1) { if (global.synths->flags & REQ_FORWARD) bristolMidiOption(0, BRISTOL_NRP_FORWARD, 1); if (global.synths->flags & NO_KEYTRACK) bristolMidiOption(0, BRISTOL_NRP_MIDI_GO, 0); else bristolMidiOption(0, BRISTOL_NRP_MIDI_GO, 1); bristolMidiSendMsg(global.controlfd, global.synths->midichannel, BRISTOL_EVENT_KEYON, 0, 10 + global.synths->transpose); bristolMidiSendMsg(global.controlfd, global.synths->midichannel, BRISTOL_EVENT_KEYOFF, 0, 10 + global.synths->transpose); } */ while ((global.flags & REQ_EXIT) == 0) { if (emStart) i = brightonEventMgr(); else i = 0; /* * This will now become a select on the ALSA SEQ socket looking for * MIDI events. Not certain how they will be linked into the GUI at * the moment. For now this is just a sleep until the ALSA SEQ interface * registration code has been finalised. * * What we will be looking for are events on a MIDI channel, we will * look for that MIDI channel in our window lists. We want to respond * to key events and reflect that in the GUI optionally, but not send * the key events since the engine will handle all those. We also want * to look for controller values and have some configurable method to * link those to our controls. Now this linkage will be done via the * GUI, preferably, with the . * Since the GUI handles this then we can dispatch events to another * module that does the linkage. Need to be able to save and retrieve * configurations - will go to this module, and all * MIDI controller events as well, and it will make the linkage and * dispatch the events. * * We should try and have a vkeydb type X event keymap. * * With certain intense events the activeSensing can fail, most notably * with window resizing. Since 0.30.8 only a single window configure * event is handled in any one pass of the event list to reduce this * effect. * * This would perform better if X would give me its socket descriptors * for a select operation. We should look at some point in putting * this into a separate thread and using a semaphore since the 'busy' * waiting is ugly. * * We should also look into separating the MIDI and GUI threads more, * it would require a bit of internal signalling to prevent both wanting * X Server access at the same time. */ /* * CHANGE TO READ ON EVERY OPENED HANDLE bristolMidiDevRead(cFD, &msg); bristolMidiDevRead(2, &msg); */ while ((r = bristolMidiDevRead(midiFD, &msg)) > 0) ; if (r == BRISTOL_MIDI_CHANNEL) { if ((global.synths->flags & REQ_DEBUG_MASK) >= REQ_DEBUG_4) printf("Read failed on Midi FD\n"); global.flags |= REQ_EXIT; pthread_exit(0); } while ((r = bristolMidiTCPRead(&msg)) > 0) ; if ((r < 0) && (global.libtest == 0)) { if ((global.synths->flags & REQ_DEBUG_MASK) >= REQ_DEBUG_4) printf("Read failed on TCP fd (no devices?)\n"); global.flags |= REQ_EXIT; pthread_exit(0); } if (i == 0) usleep(mwt); /* * We should have some 'tack' in here where we call a routine in the * library that will execute any timed events that have been requested, * this will cover things like flashing lights, VU metering. It will * also be used to cover the midi sequencer. * * We should also attempt to recover lost time in graphical processing * by changing mwt into a target sleep period by getting the current * time and looking at the ms delta. */ brightonFastTimer(0, 0, 0, BRIGHTON_FT_CLOCK, mwt / 1000); if ((activeSense > 0) && ((asc -= mwt / 1000) < 0) && (emStart)) { asc = activeSense; /* * Hm, this is wrong, we should scan the whole synths list but for * now we actually need to send one for each emulation, dual manual * and all that. * The check on send status is not really necessary, we will * probably end up seeing the SIGPIPE handler have us exit if the * socket closes at the remote end. */ if (bristolMidiSendMsg(global.controlfd, global.synths->sid, BRISTOL_ACTIVE_SENSE, 0, activeSensePeriod) != 0) { printf("Active sense transmit failure\n"); sleep(1); exit(1); } if ((global.synths->sid2 > 0) && (bristolMidiSendMsg(global.manualfd, global.synths->sid2, BRISTOL_ACTIVE_SENSE, 0, activeSensePeriod) != 0)) { printf("Active sense transmit failure\n"); sleep(1); exit(1); } if ((ladiRequest == 1) && global.synths->flags & LADI_ENABLE) { int memHold = global.synths->cmem; ladiRequest = 0; printf("LADI save state signalled\n"); global.synths->cmem = global.synths->ladimem; brightonControlKeyInput(global.synths->win, 's', 0); global.synths->cmem = memHold; } if ((ladiRequest == 2) && global.synths->flags & LADI_ENABLE) { int memHold = global.synths->cmem; ladiRequest = 0; printf("LADI load state signalled\n"); global.synths->cmem = global.synths->ladimem; brightonControlKeyInput(global.synths->win, 'l', 0); global.synths->cmem = memHold; } /* * We are going to piggyback the slow event timer onto this code. * It means the slow events will be related to the activeSensing * but if anybody has issues due to changing AS or its timers we * can review it at that time. */ brightonSlowTimer(0, 0, BRIGHTON_ST_CLOCK); } } printf("brighton event manager thread exiting\n"); global.flags |= REQ_EXIT; pthread_exit(0); } void cleanout(void *id) { if (id) brightonRemoveInterface(id); cleanupBristol(); exit(4); } void clearout(int result) { /* * This is not the right way to do things. We should request an exit and * let all the processes do their work. The issue here is that this can * get called very early in the window creation process which causes other * issues if we try to close down nicely. A better option here would be * to assert the result is '0'. That way we get a nice core memory dump * to debug under other circumstances. */ printf("clearing out via early exit\n"); exit(result); } void printBrightonHelp(int synth) { if ((synth >= BRISTOL_SYNTHCOUNT) || (readme[synth] == NULL)) return; printf("\n%s\n", readme[synth]); } void printBrightonReadme() { int i; printf("\n%s\n\n\n", readmeheader); for (i = 0; i < BRISTOL_SYNTHCOUNT; i++) { if ((synthesisers[i] != NULL) && (readme[i] != NULL)) printf("%s\n\n\n", readme[i]); } printf("\n%s\n", readmetrailer); printf("%s", helptext); } bristol-0.60.11/brighton/brightonSID.c0000644000175000017500000016332711746476475014453 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include #include "brighton.h" #include "brightonMini.h" #include "brightoninternals.h" static int sidInit(); static int sidConfigure(); static int sidCallback(brightonWindow *, int, int, float); static int sidModCallback(brightonWindow *, int, int, float); static int midiCallback(brightonWindow *, int, int, float); static int sidKeyCallback(brightonWindow *, int, int, float); extern guimain global; #include "brightonKeys.h" #define SYNTH_NAME synth->resources->name #define DEVICE_COUNT 135 #define ACTIVE_DEVS 118 #define MEM_START ACTIVE_DEVS #define ENTRY_POT 18 #define KEY_PANEL 1 #define MODS_PANEL 2 #define DISPLAY_DEV (DEVICE_COUNT - 1) static int dc, mbh = 0; /* * This structure is for device definition. The structure is defined in * include/brighton.h, further definitions in brighton/brightonDevtable.h and * include/brightoninternals.h * * typedef int (*brightonCallback)(int, float); * typedef struct BrightonLocations { * int device; 0=rotary, 1=scale, etc. * float relx, rely; relative position with regards to 1000 by 1000 window * float relw, relh; relative height. * int from, to; * brightonCallback callback; specific to this dev * char *image; bitmap. If zero take a device default. * int flags; * } brightonLocations; * * This example is for a sidBristol type synth interface. */ /* * The GUI should give three voices with all the OSC, ENV, RM, SYNC options * and then separately the test, multi and detune. * * Tri/Ramp/Square/Noise * PW/Tune/transpose(/Glide?) * RM/SYNC/Mute/Routing * Att/Dec/Sust/Rel * * osc3 -> PWM osc 1/2 * * Filter: * freq, res, pole * HP/BP/LP inc 24dB * * should add in option * of osc3 and env3 to filter cutoff. * Multi * * Must have S/N, leakage, global tuning. DC bias? Reset?. * * Voice options to include: * * mono (with detune then between voices in emulator) * three voice poly-1: all play same sound * three voice poly-2: all have their own sound * two voice poly, voice 3 arpeggio - argeggiate all other held notes * * Arpeggiator to have rate, retrig and wavescanning, rates down to X samples. * * We should consider using two SID, the second one could be used just for * an extra Env and Osc(LF) to modulate the first one, later look at more * voices or other layer options? * * The second SID will have voices 1 + 2 in TEST state, no output will be taken * just clocked, no filter selections made to all reduce overhead - we only * want env3 and osc3 outputs from the registers anyway. * * MODS: * * Env will have adsr plus routing * LFO will have waveform, rate (0.1-10Hz) and routing * * Destinations can be * vibrato, PW -> v1/v2/v3. * wah * * Notes: * * Lost multi, vol - replaced them. FIXED * Lost detune in multi FIXED CHECK * * S/N ratio is far too high (value levels needs reducing) FIXED * Filter res is not working FIXED * Mixed 12/24 filters not working FIXED * Mods are mixed up re lfo/env to what parameters FIXED * Mods are overloaded FIXED * Mods default to noise FIXED * Noise MOD does not work - no signal output from SID-2. FIXED * Tune/Transpose are not proactive Fixed * Glide not implemented. FIXED * Pitch bend implemented. FIXED, but leaves notes shifted when disabled. * RM damaged FIXED * Memories using S&H do not get LFO Mod loaded correctly. FIXED * * Key assign modes finished. FIXED * Need to clear out keys when changing modes in engine. FIXED * Arpeggio finished, needs more testing, esp trig FIXED * * Implemented two new arpeggiation modes, Arpeg-1 and Arpeg-2. Both will split * the keyboard at note 52 then Arpeg-1 will apply on the top half, the bottom * half can play duophonic baselines. Arpeg-2 will apply to the bottom half * and the upper half can play duophonic leads. * * Review volume levels direct/filter and Multi. * * Linux audio drivers are broken, stutter with window changes. * * May need more Poly modes: * lowest key, highest key, arpeggiate rest. * * Future release * * need Mod env retrig option - legato? * need Aud env retrig option - legato? * access to analogue parameters from GUI * filter tracking keyboard - whick key? * velocity to mod, filter, pw * arpeg direction */ /* SID-1 */ #define V1R1 50 #define V1R2 120 #define V1R3 240 #define V1R4 430 #define VD1 36 #define VD2 22 #define VD3 2 #define VBW1 28 #define VBW2 10 #define VBW3 45 #define VBH1 45 #define VBH2 110 #define VBH3 370 #define VBH4 290 #define V1C1 25 #define V1C2 (V1C1 + VD1) #define V1C3 (V1C2 + VD1) #define V1C4 (V1C3 + VD1) #define V1C1b (V1C1 + VD3) #define V1C2b (V1C2 + VD3) #define V1C3b (V1C3 + VD3) #define V1C4b (V1C4 + VD3) #define V1C5 (V1C4 + VD1 + 15) #define V1C6 (V1C5 + VD2) #define V1C7 (V1C6 + VD2) #define V1C8 (V1C7 + VD2) #define V2C1 (V1C8 + VD2 + VD1) #define V2C2 (V2C1 + VD1) #define V2C3 (V2C2 + VD1) #define V2C4 (V2C3 + VD1) #define V2C1b (V2C1 + VD3) #define V2C2b (V2C2 + VD3) #define V2C3b (V2C3 + VD3) #define V2C4b (V2C4 + VD3) #define V2C5 (V2C4 + VD1 + 15) #define V2C6 (V2C5 + VD2) #define V2C7 (V2C6 + VD2) #define V2C8 (V2C7 + VD2) #define V3C1 (V2C8 + VD2 + VD1) #define V3C2 (V3C1 + VD1) #define V3C3 (V3C2 + VD1) #define V3C4 (V3C3 + VD1) #define V3C1b (V3C1 + VD3) #define V3C2b (V3C2 + VD3) #define V3C3b (V3C3 + VD3) #define V3C4b (V3C4 + VD3) #define V3C5 (V3C4 + VD1 + 15) #define V3C6 (V3C5 + VD2) #define V3C7 (V3C6 + VD2) #define V3C8 (V3C7 + VD2) #define FC1 (V3C8 + VD2 + VD1) #define FC2 (FC1 + VD1) #define FC3 (FC2 + VD1) #define FC1b (FC1 + VD3) #define FC2b (FC2 + VD3) #define FC3b (FC3 + VD3) /* SID-2 Mods */ #define S2R0 650 #define S2R1 (S2R0 + 30) //630 #define S2R2 (S2R1 + 45) //675 #define S2R3 (S2R2 + 75) //750 #define S2R4 (S2R3 + 75) //825 #define S2C0 20 #define S2C1 (S2C0 + VD1 + VD1 + 5) #define S2C1b (S2C1 + VD1/2) #define S2C2 (S2C1 + VD1) #define S2C2b (S2C1 + VD1 + VD1/2) #define S2C3 (S2C2 + VD1) #define S2C3b (S2C3 + VD1/2) #define S2C4 (S2C3 + VD1) #define S2C5 (S2C4 + VD1 + VD2) #define S2C6 (S2C5 + VD1) #define S2C7 (S2C6 + VD1 + VD1) #define S2C8 (S2C7 + VD1) #define S2C8b (S2C8 + VD1 + VD2) #define S2C9 (S2C8b + VD2) #define S2C10 (S2C9 + VD2) #define S2C11 (S2C10 + VD2) #define S2C12 (S2C11 + VD2) #define S2C13 (S2C12 + VD1 + 10) #define S2C14 (S2C13 + VD1/2) #define S2C15 (S2C13 + VD1) #define S2C16 (S2C15 + VD1 + VD2) #define S2C17 (S2C16 + VD1) #define S2C18 (S2C17 + VD1) #define S2C19 (S2C18 + VD1) #define S2C20 (S2C19 + VD1) #define S2C21 (S2C20 + VD1) #define S2C22 (S2C21 + VD1) #define S2C23 (S2C22 + VD1) static brightonLocations modwheel[5] = { {"", BRIGHTON_MODWHEEL, 0, 0, 380, 1000, 0, 1, 0, "bitmaps/knobs/modwheel.xpm", 0, BRIGHTON_HSCALE|BRIGHTON_NOSHADOW|BRIGHTON_NOTCH}, {"", 2, 500, 50, 500, 130, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, 500, 306, 500, 130, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, 500, 562, 500, 130, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, 500, 820, 500, 130, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbongreen.xpm", 0}, }; static brightonLocations locations[DEVICE_COUNT] = { /* * Three voices with same parameterisation, roughly * Tri/Ramp/Square/Noise Buttons * RM/SYNC/Mute/Routing(Multi global) Buttons * PW/Tune/transpose(/Glide?) - Pots * Att/Dec/Sust/Rel - Sliders */ {"V1-Noise", 2, V1C1, V1R2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"V1-Tri", 2, V1C2, V1R2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"V1-Ramp", 2, V1C3, V1R2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"V1-Square", 2, V1C4, V1R2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"V1-PW", 0, V1C1b, V1R3, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobred.xpm", 0, 0}, {"V1-Tune", 0, V1C2b, V1R3, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobred.xpm", 0, BRIGHTON_NOTCH}, {"V1-Transpose", 0, V1C3b, V1R3, VBW3, VBH2, 0, 24,0, "bitmaps/knobs/knobred.xpm", 0, 0}, {"V1-Glide", 0, V1C4b, V1R3, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobred.xpm", 0, 0}, {"V1-RM", 2, V1C1, V1R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"V1-3-1-Sync", 2, V1C2, V1R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"V1-Mute", 2, V1C3, V1R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"V1-Filt", 2, V1C4, V1R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"V1-Attack", 1, V1C5, V1R2, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, 0}, {"V1-Decay", 1, V1C6, V1R2, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, 0}, {"V1-Sustain", 1, V1C7, V1R2, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, 0}, {"V1-Release", 1, V1C8, V1R2, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, 0}, /* Dummies */ {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, /* Voice 2 - 20 */ {"V2-Noise", 2, V2C1, V1R2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"V2-Tri", 2, V2C2, V1R2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"V2-Ramp", 2, V2C3, V1R2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"V2-Square", 2, V2C4, V1R2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"V2-PW", 0, V2C1b, V1R3, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobred.xpm", 0,0}, {"V2-Tune", 0, V2C2b, V1R3, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobred.xpm", 0, BRIGHTON_NOTCH}, {"V2-Transpose", 0, V2C3b, V1R3, VBW3, VBH2, 0, 24, 0, "bitmaps/knobs/knobred.xpm",0,0}, {"V2-Glide", 0, V2C4b, V1R3, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobred.xpm", 0,0}, {"V2-RM-1-2", 2, V2C1, V1R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"V2-Sync", 2, V2C2, V1R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"V2-Mute", 2, V2C3, V1R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"V2-Filt", 2, V2C4, V1R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"V2-Attack", 1, V2C5, V1R2, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, 0}, {"V2-Decay", 1, V2C6, V1R2, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, 0}, {"V2-Sustain", 1, V2C7, V1R2, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, 0}, {"V2-Release", 1, V2C8, V1R2, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, 0}, /* Dummies */ {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, /* Voice 3 - 40 */ {"V3-Noise", 2, V3C1, V1R2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"V3-Tri", 2, V3C2, V1R2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"V3-Ramp", 2, V3C3, V1R2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"V3-Square", 2, V3C4, V1R2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"V3-PW", 0, V3C1b, V1R3, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobred.xpm", 0, 0}, {"V3-Tune", 0, V3C2b, V1R3, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobred.xpm", 0, BRIGHTON_NOTCH}, {"V3-Transpose", 0, V3C3b, V1R3, VBW3, VBH2, 0, 24, 0, "bitmaps/knobs/knobred.xpm", 0,0}, {"V3-Glide", 0, V3C4b, V1R3, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobred.xpm", 0, 0}, {"V3-RM-2-3", 2, V3C1, V1R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"V3-Sync", 2, V3C2, V1R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"V3-Mute", 2, V3C3, V1R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"V3-Filt", 2, V3C4, V1R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"V3-Attack", 1, V3C5, V1R2, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, 0}, {"V3-Decay", 1, V3C6, V1R2, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, 0}, {"V3-Sustain", 1, V3C7, V1R2, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, 0}, {"V3-Release", 1, V3C8, V1R2, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, 0}, /* Dummies */ {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, /* Filter - 60 */ {"VCF-HP", 2, FC1, V1R2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"VCF-BP", 2, FC2, V1R2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"VCF-LP", 2, FC3, V1R2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"VCF-Cutoff", 0, FC1b, V1R3, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobred.xpm", 0, 0}, {"VCF-Resonance", 0, FC2b, V1R3, VBW3, VBH2, 0, 15,0, "bitmaps/knobs/knobred.xpm", 0, 0}, {"VCF-Mix", 0, FC3b, V1R3, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobred.xpm", 0, 0}, {"VCF-LPF24", 2, FC3, V1R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, /* VCF Multi and MasterVol */ {"VCF-Multi", 2, FC1, V1R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"MasterVolume", 0, S2C23+8, S2R0 - 50, VBW3, VBH2, 0, 15, 0, "bitmaps/knobs/knobyellow.xpm", 0, 0}, /* * MODS: 69 (was 70) * * Env will have adsr plus routing * LFO will have waveform, rate (0.1-10Hz) and routing * * Destinations can be * vibrato, PW -> v1/v2/v3. * wah */ /* Key Mode */ {"Mode Mono", 2, S2C0-3, S2R0, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"Mode Poly1", 2, S2C0-3, S2R0+60, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"Mode Poly2", 2, S2C0-3, S2R0+120, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"Mode Arpeg1", 2, S2C0-3, S2R0+180, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"Mode Arpeg2", 2, S2C0-3, S2R0+240, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, /* Mods - 76 */ {"LFO-Rate", 0, S2C1b+2, S2R1, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobgreen.xpm", 0, 0}, {"LFO-Depth", 0, S2C3b+2, S2R1, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobgreen.xpm", 0, 0}, {"???1", 2, S2C1, S2R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"???2", 2, S2C2, S2R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"???3", 2, S2C3, S2R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"???4", 2, S2C4, S2R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, /* 80 */ {"LFO-PW-V1", 2, S2C5, S2R0, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"LFO-PW-V2", 2, S2C5, S2R2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"LFO-PW-V3", 2, S2C5, S2R3, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"LFO-FM-V1", 2, S2C6, S2R0, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"LFO-FM-V2", 2, S2C6, S2R2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"LFO-FM-V3", 2, S2C6, S2R3, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"LFO-FM-Filt", 2, S2C6, S2R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, /* Mod Touch control */ {"LFO-F-Touch", 2, S2C1b, S2R0 - 70, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"LFO-G-Touch", 2, S2C3b, S2R0 - 70, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, /* Env mods 95 */ {"ModEnv-FM-V1", 2, S2C7, S2R0, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"ModEnv-FM-V2", 2, S2C7, S2R2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"ModEnv-FM-V3", 2, S2C7, S2R3, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"ModEnv-FM-Filt", 2, S2C7, S2R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"ModEnv-PW-V1", 2, S2C8, S2R0, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"ModEnv-PW-V2", 2, S2C8, S2R2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"ModEnv-PW-V3", 2, S2C8, S2R3, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, /* 102 - Mod Env */ {"ModEnv-Attack", 1, S2C8b, S2R0, VBW2, VBH4, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, 0}, {"ModEnv-Sustain", 1, S2C9, S2R0, VBW2, VBH4, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, 0}, {"ModEnv-Decay", 1, S2C10, S2R0, VBW2, VBH4, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, 0}, {"ModEnv-Release", 1, S2C11, S2R0, VBW2, VBH4, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, 0}, {"ModEnv-Gain", 1, S2C12, S2R0, VBW2, VBH4, 0, 1, 0, "bitmaps/buttons/polywhiteV.xpm", 0, 0}, {"ModEnv-Touch", 2, S2C11+13, S2R0-70, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, /* * This will shadow the version of the memory. Existing memories will have * a zero in here (0.40) ones saved by this release (0.40.2) will have a * 1 in there, this allows the GUI to adjust the keymode parameter. */ {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, /* 110 - These shadow the mod panel */ {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"Arpeg-Rate", 0, S2C14, S2R1, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm",0,0}, {"Arpeg-Trig", 2, S2C13, S2R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"Arpeg-Scan", 2, S2C15, S2R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, /* Memories 118 - first 8 digits */ {"", 2, S2C17, S2R3, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbongreen.xpm", 0}, {"", 2, S2C18, S2R3, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbongreen.xpm", 0}, {"", 2, S2C19, S2R3, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbongreen.xpm", 0}, {"", 2, S2C20, S2R3, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbongreen.xpm", 0}, {"", 2, S2C17, S2R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbongreen.xpm", 0}, {"", 2, S2C18, S2R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbongreen.xpm", 0}, {"", 2, S2C19, S2R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbongreen.xpm", 0}, {"", 2, S2C20, S2R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbongreen.xpm", 0}, /* Then load/save */ {"", 2, S2C16, S2R3, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, S2C16, S2R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", BRIGHTON_CHECKBUTTON}, /* Then Bank, down, up, find */ {"", 2, S2C21, S2R3, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, S2C22, S2R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, S2C22, S2R3, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, S2C21, S2R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, S2C23 + 6, S2R3, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, S2C23 + 6, S2R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", BRIGHTON_CHECKBUTTON}, /* Done */ {"", 3, S2C17, S2R1, 175, 60, 0, 1, 0, 0, "bitmaps/images/alphadisplay3.xpm", 0} }; /* * This is a set of globals for the main window rendering. Again taken from * include/brighton.h * Hm, the bit-1 was black, and the bit 99 was in various builds including a * white one, but also a black one and a black one with wood panels. I would * like the black one with wood panels, so that will have to be the bit-1, the * bit-99 will be white with thin metal panels. */ brightonApp sidApp = { "sidney", 0, /* no blueprint on wood background. */ "bitmaps/textures/metal1.xpm", //"bitmaps/textures/p8b.xpm", BRIGHTON_STRETCH, sidInit, sidConfigure, /* 3 callbacks, unused? */ midiCallback, destroySynth, {1, 100, 2, 2, 5, 520, 0, 0}, 1000, 330, 0, 0, 3, /* panels */ { { "Sid800", "bitmaps/blueprints/sid.xpm", "bitmaps/textures/metal1.xpm", BRIGHTON_STRETCH, /* flags */ 0, 0, sidCallback, 25, 29, 950, 620, DEVICE_COUNT, locations }, { "Keyboard", 0, // "bitmaps/keys/kbg.xpm", "bitmaps/newkeys/nkbg.xpm", 0x020|BRIGHTON_STRETCH, 0, 0, sidKeyCallback, 90, 680, 893, 318, KEY_COUNT_5OCTAVE, keysprofile2 }, { "mods", "bitmaps/buttons/blue.xpm", "bitmaps/textures/metal1.xpm", 0, 0, 0, sidModCallback, 32, 695, 50, 220, 5, modwheel }, } }; /* * We really want to just use one midi channel and let the midi library decide * that we have multiple synths on the channel with their own split points. * The lower layer should define the midi channel, split point and transpose * of upper layer. */ static int sidKeyCallback(brightonWindow *win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); if (global.libtest) return(0); /* * So we have a single key event and two MIDI channels. Just send the * event on both channels, no need to be difficult about it since if this * was a split configuration the library filters out the events. */ if (value) { bristolMidiSendMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_KEYON, 0, index + synth->transpose); } else { bristolMidiSendMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_KEYOFF, 0, index + synth->transpose); } return(0); } /* * At this point we have loaded a memory so we need to send those actual new * parameters to the engine. This is an issue for MIDI program load, perhaps * we should consider dual load above memory 74 as per the original? * * The path of least resistance here is to scan through the the memory table * incrementing the input selector and delivering the memory value to the * data entry pot..... */ static void loadMemoryShim(guiSynth *synth) { brightonEvent event; /* We need to force some exclusion on LFO mods and Mode */ synth->dispatch[76].other1 = synth->mem.param[76] != 0? 0: synth->mem.param[77] != 0? 1: synth->mem.param[78] != 0? 2: synth->mem.param[79] != 0? 3: 0; /* Key mode changed between releases, this recovers them */ if (synth->mem.param[109] == 0) { int on; synth->dispatch[69].other1 = synth->mem.param[70] != 0? 0: synth->mem.param[71] != 0? 1: synth->mem.param[72] != 0? 2: synth->mem.param[73] != 0? 3: 0; on = 69 + synth->dispatch[69].other1; event.type = BRISTOL_FLOAT; event.value = 0; brightonParamChange(synth->win, 0, 70 + synth->dispatch[69].other1, &event); event.value = 1; brightonParamChange(synth->win, 0, on, &event); } else synth->dispatch[69].other1 = synth->mem.param[69] != 0? 0: synth->mem.param[70] != 0? 1: synth->mem.param[71] != 0? 2: synth->mem.param[72] != 0? 3: synth->mem.param[73] != 0? 4: 0; bristolMidiSendMsg(global.controlfd, synth->sid, 126, 5, synth->dispatch[69].other1); /* Set up the trigger options */ /* Then we can look at the mod panel options */ event.type = BRISTOL_FLOAT; event.value = synth->mem.param[111]; brightonParamChange(synth->win, MODS_PANEL, 1, &event); event.value = synth->mem.param[112]; brightonParamChange(synth->win, MODS_PANEL, 2, &event); event.value = synth->mem.param[113]; brightonParamChange(synth->win, MODS_PANEL, 3, &event); event.value = synth->mem.param[114]; brightonParamChange(synth->win, MODS_PANEL, 4, &event); /* And we should enforce mod waveform */ bristolMidiSendMsg(global.controlfd, synth->sid, 126, 66, synth->mem.param[76] == 0?0:1); bristolMidiSendMsg(global.controlfd, synth->sid, 126, 67, synth->mem.param[77] == 0?0:1); bristolMidiSendMsg(global.controlfd, synth->sid, 126, 68, synth->mem.param[78] == 0?0:1); bristolMidiSendMsg(global.controlfd, synth->sid, 126, 69, synth->mem.param[79] == 0?0:1); if (synth->mem.param[76] != 0) bristolMidiSendMsg(global.controlfd, synth->sid, 126, 66, 1); /* See if we have to force memory variables */ if (synth->mem.param[70] != 0) { int i; for (i = 0; i < 20; i++) { event.value = synth->mem.param[i]; brightonParamChange(synth->win, 0, i, &event); brightonParamChange(synth->win, 0, i + 20, &event); brightonParamChange(synth->win, 0, i + 40, &event); } } } static void loadMemoryMidiShim(guiSynth *synth, int from) { loadMemory(synth, SYNTH_NAME, 0, synth->bank * 10 + from, synth->mem.active, 0, BRISTOL_FORCE); loadMemoryShim(synth); } int loadMemoryKeyShim(guiSynth *synth, char *algo, char *name, int location, int active, int skip, int flags) { loadMemory(synth, SYNTH_NAME, 0, location, synth->mem.active, 0, BRISTOL_FORCE); loadMemoryShim(synth); return(0); } static int midiCallback(brightonWindow *win, int controller, int value, float n) { guiSynth *synth = findSynth(global.synths, win); switch(controller) { case MIDI_PROGRAM: if (synth->mem.param[87] == 0) return(0); /* * We should accept 0..74 as lower layer and above that as dual * loading requests. */ printf("midi program: %x, %i\n", controller, value); synth->location = value; loadMemoryMidiShim(synth, synth->location); break; case MIDI_BANK_SELECT: printf("midi banksel: %x, %i\n", controller, value); synth->bank = value; break; } return(0); } static int sidMidiNull(void *synth, int fd, int chan, int c, int o, int v) { if (global.libtest) printf("This is a null callback on %i id %i\n", c, o); return(0); } static int vexclude = 0; /* * Typically this should just do what sidMidiShim does, send the parameter to * the target however in mode Poly-1 all voices need to have the same set of * parameters. This really means the GUI needs to replicate the parameter * changes all voice params. There are many ways to do this, the coolest is * actually to redistribute the requests, ganging the controls. */ static void sidVoiceShim(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; int off1 = 20, off2 = 40; if (synth->mem.param[70] != 0) { if (vexclude) return; event.value = synth->mem.param[o - 10]; vexclude = 1; /* Find out what parameters we need to use */ if (o >= 50) { off1 = -40; off2 = -20; } else if (o >= 30) { off1 = -20; off2 = 20; } /* Update the displays */ brightonParamChange(synth->win, synth->panel, o - 10 + off1, &event); brightonParamChange(synth->win, synth->panel, o - 10 + off2, &event); vexclude = 0; /* Send the messages for the other voices */ bristolMidiSendMsg(fd, synth->sid, c, o + off1, v); bristolMidiSendMsg(fd, synth->sid, c, o + off2, v); } bristolMidiSendMsg(fd, synth->sid, c, o, v); } static void sidMidiShim(guiSynth *synth, int fd, int chan, int c, int o, int v) { bristolMidiSendMsg(fd, synth->sid, c, o, v); } static void sidLFOWave(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; event.value = 1.0; event.type = BRISTOL_FLOAT; if (synth->flags & MEM_LOADING) return; if ((synth->flags & OPERATIONAL) == 0) return; if (synth->dispatch[76].other2) { synth->dispatch[76].other2 = 0; return; } /* * We want to make these into memory buttons. To do so we need to * know what the last active button was, and deactivate its * display, then send any message which represents the most * recently configured value. Since this is a memory button we do * not have much issue with the message, but we are concerned with * the display. */ if (synth->dispatch[76].other1 != -1) { synth->dispatch[76].other2 = 1; if (synth->dispatch[76].other1 != o) event.value = 0; else event.value = 1; brightonParamChange(synth->win, synth->panel, synth->dispatch[76].other1 + 76, &event); bristolMidiSendMsg(fd, synth->sid, 126, 66 + synth->dispatch[76].other1, 0); } synth->dispatch[76].other1 = o; bristolMidiSendMsg(fd, synth->sid, 126, 66 + o, 1); } static int mode = -1; static void sidMode(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; int i, sv; event.value = 1.0; event.type = BRISTOL_FLOAT; if (synth->flags & MEM_LOADING) return; if ((synth->flags & OPERATIONAL) == 0) return; if (synth->dispatch[69].other2) { synth->dispatch[69].other2 = 0; return; } /* * We want to make these into memory buttons. To do so we need to * know what the last active button was, and deactivate its * display, then send any message which represents the most * recently configured value. Since this is a memory button we do * not have much issue with the message, but we are concerned with * the display. */ if (synth->dispatch[69].other1 != -1) { synth->dispatch[69].other2 = 1; if (synth->dispatch[69].other1 != o) event.value = 0; else event.value = 1; brightonParamChange(synth->win, synth->panel, synth->dispatch[69].other1 + 69, &event); } synth->dispatch[69].other1 = o; bristolMidiSendMsg(fd, synth->sid, 126, 5, o); /* * This code would sync all the voice parameters as we enter Poly-1 however * that is always desirable. We should either sync the engine parameters * to voice-3 entering Poly-1 and reset them to GUI parameters on exit, * or do nothing. */ if (synth->mem.param[70] != 0) { /* * Sync voices in engine */ if (mode != 1) for (i = 0; i < 20; i++) { if (sidApp.resources[0].devlocn[i].to == 1) sv = synth->mem.param[i+40] * C_RANGE_MIN_1; else sv = synth->mem.param[i+40]; bristolMidiSendMsg(fd, synth->sid, 126, i + 10, sv); bristolMidiSendMsg(fd, synth->sid, 126, i + 30, sv); } } else { if (mode == 1) for (i = 0; i < 60; i++) { event.value = synth->mem.param[i]; brightonParamChange(synth->win, synth->panel, i, &event); } } mode = o; } static void sidMemory(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; int bank = synth->bank; int location = synth->location; event.value = 1.0; event.type = BRISTOL_FLOAT; if (synth->flags & MEM_LOADING) return; if ((synth->flags & OPERATIONAL) == 0) return; if (synth->dispatch[MEM_START].other2) { synth->dispatch[MEM_START].other2 = 0; return; } switch (c) { default: case 0: /* * We want to make these into memory buttons. To do so we need to * know what the last active button was, and deactivate its * display, then send any message which represents the most * recently configured value. Since this is a memory button we do * not have much issue with the message, but we are concerned with * the display. */ if (synth->dispatch[MEM_START].other1 != -1) { synth->dispatch[MEM_START].other2 = 1; if (synth->dispatch[MEM_START].other1 != o) event.value = 0; else event.value = 1; brightonParamChange(synth->win, synth->panel, synth->dispatch[MEM_START].other1 + MEM_START - 1, &event); } synth->dispatch[MEM_START].other1 = o; if (synth->flags & BANK_SELECT) { if ((synth->bank * 10 + o) >= 100) { synth->location = o; synth->flags &= ~BANK_SELECT; if (loadMemory(synth, SYNTH_NAME, 0, synth->bank * 10 + synth->location, synth->mem.active, 0, BRISTOL_STAT) < 0) displayText(synth, "FREE MEM", synth->bank * 10 + synth->location, DISPLAY_DEV); else displayText(synth, "PROGRAM", synth->bank * 10 + synth->location, DISPLAY_DEV); } else { synth->bank = synth->bank * 10 + o; displayText(synth, "BANK", synth->bank * 10 + synth->location, DISPLAY_DEV); } } else { if (synth->bank < 1) synth->bank = 1; synth->location = o; if (loadMemory(synth, SYNTH_NAME, 0, synth->bank * 10 + synth->location, synth->mem.active, 0, BRISTOL_STAT) < 0) displayText(synth, "FREE MEM", synth->bank * 10 + synth->location, DISPLAY_DEV); else displayText(synth, "PROGRAM", synth->bank * 10 + synth->location, DISPLAY_DEV); } break; case 1: if (synth->bank < 1) synth->bank = 1; if (synth->location == 0) synth->location = 1; if (loadMemory(synth, SYNTH_NAME, 0, synth->bank * 10 + synth->location, synth->mem.active, 0, BRISTOL_FORCE) < 0) displayText(synth, "FREE MEM", synth->bank * 10 + synth->location, DISPLAY_DEV); else { loadMemoryShim(synth); displayText(synth, "PROGRAM", synth->bank * 10 + synth->location, DISPLAY_DEV); } synth->flags &= ~BANK_SELECT; /* * Doubleclick on load will toggle debugging if (brightonDoubleClick(dc) != 0) bristolMidiSendMsg(fd, synth->sid, 126, 4, 1); */ break; case 2: if (synth->bank < 1) synth->bank = 1; if (synth->location == 0) synth->location = 1; if (brightonDoubleClick(dc) != 0) { synth->mem.param[109] = 1.0; saveMemory(synth, SYNTH_NAME, 0, synth->bank * 10 + synth->location, 0); displayText(synth, "PROGRAM", synth->bank * 10 + synth->location, DISPLAY_DEV); synth->flags &= ~BANK_SELECT; } break; case 3: if (synth->flags & BANK_SELECT) { synth->flags &= ~BANK_SELECT; if (loadMemory(synth, SYNTH_NAME, 0, synth->bank * 10 + synth->location, synth->mem.active, 0, BRISTOL_STAT) < 0) displayText(synth, "FREE MEM", synth->bank * 10 + synth->location, DISPLAY_DEV); else displayText(synth, "PROGRAM", synth->bank * 10 + synth->location, DISPLAY_DEV); } else { synth->bank = 0; displayText(synth, "BANK", synth->bank, DISPLAY_DEV); synth->flags |= BANK_SELECT; } break; case 4: if (--location < 1) { location = 8; if (--bank < 1) bank = 88; } while (loadMemory(synth, SYNTH_NAME, 0, bank * 10 + location, synth->mem.active, 0, BRISTOL_STAT) < 0) { if (--location < 1) { location = 8; if (--bank < 1) bank = 88; } if ((bank * 10 + location) == (synth->bank * 10 + synth->location)) break; } displayText(synth, "PROGRAM", bank * 10 + location, DISPLAY_DEV); synth->bank = bank; synth->location = location; loadMemory(synth, SYNTH_NAME, 0, bank * 10 + location, synth->mem.active, 0, BRISTOL_FORCE); loadMemoryShim(synth); brightonParamChange(synth->win, 0, MEM_START - 1 + synth->location, &event); break; case 5: if (++location > 8) { location = 1; if (++bank > 88) bank = 1; } while (loadMemory(synth, SYNTH_NAME, 0, bank * 10 + location, synth->mem.active, 0, BRISTOL_STAT) < 0) { if (++location > 8) { location = 1; if (++bank > 88) bank = 1; } if ((bank * 10 + location) == (synth->bank * 10 + synth->location)) break; } displayText(synth, "PROGRAM", bank * 10 + location, DISPLAY_DEV); synth->bank = bank; synth->location = location; loadMemory(synth, SYNTH_NAME, 0, bank * 10 + location, synth->mem.active, 0, BRISTOL_FORCE); loadMemoryShim(synth); brightonParamChange(synth->win, 0, MEM_START - 1 + synth->location, &event); break; case 6: /* Find the next free mem */ if (++location > 8) { location = 1; if (++bank > 88) bank = 1; } while (loadMemory(synth, SYNTH_NAME, 0, bank * 10 + location, synth->mem.active, 0, BRISTOL_STAT) >= 0) { if (++location > 8) { location = 1; if (++bank > 88) bank = 1; } if ((bank * 10 + location) == (synth->bank * 10 + synth->location)) break; } if (loadMemory(synth, SYNTH_NAME, 0, bank * 10 + location, synth->mem.active, 0, BRISTOL_STAT) >= 0) displayText(synth, "PROGRAM", bank * 10 + location, DISPLAY_DEV); else displayText(synth, "FREE MEM", bank * 10 + location, DISPLAY_DEV); synth->bank = bank; synth->location = location; brightonParamChange(synth->win, 0, MEM_START - 1 + synth->location, &event); break; } } static int sidModCallback(brightonWindow *win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); brightonEvent event; event.type = BRISTOL_FLOAT; synth->mem.param[110 + index] = value; switch (index) { case 0: /* Wheel - we don't send pitch, just mod */ bristolMidiControl(global.controlfd, synth->midichannel, 0, 1, ((int) (value * (C_RANGE_MIN_1 - 1))) >> 7); break; case 1: /* Pitch select - these should actually just flag the engine */ bristolMidiSendMsg(global.controlfd, synth->sid, 126, 100, value == 0?0:1); break; case 2: /* LFO Select - these should actually just flag the engine */ bristolMidiSendMsg(global.controlfd, synth->sid, 126, 98, value == 0?0:1); if ((synth->mem.param[110 + index] = value) == 0) return(0); bristolMidiControl(global.controlfd, synth->midichannel, 0, 1, ((int) (synth->mem.param[110] * (C_RANGE_MIN_1 - 1))) >> 7); break; case 3: /* ENV Select - these should actually just flag the engine */ bristolMidiSendMsg(global.controlfd, synth->sid, 126, 99, value == 0?0:1); if ((synth->mem.param[110 + index] = value) == 0) return(0); bristolMidiControl(global.controlfd, synth->midichannel, 0, 1, ((int) (synth->mem.param[110] * (C_RANGE_MIN_1 - 1))) >> 7); break; case 4: /* Center spring */ if (value == 0) win->app->resources[panel].devlocn[0].flags &= ~BRIGHTON_CENTER; else { win->app->resources[panel].devlocn[0].flags |= BRIGHTON_CENTER; /* And centre the control */ event.value = 0.5; brightonParamChange(synth->win, panel, 0, &event); } break; }; return(0); } /* * For the sake of ease of use, links have been placed here to be called * by any of the devices created. They would be better in some other file, * perhaps with this as a dispatch. * * Param refers to the device index in the locations table given below. */ static int sidCallback(brightonWindow *win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); int sendvalue; if (global.libtest) printf("sidCallback(%i, %i, %f)\n", panel, index, value); if (synth == 0) return(0); if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0)) return(0); if ((index >= 111) && (index <= 114)) return(sidModCallback(win, MODS_PANEL, index - 110, value)); if (sidApp.resources[0].devlocn[index].to == 1) sendvalue = value * C_RANGE_MIN_1; else sendvalue = value; synth->mem.param[index] = value; // if (index < 100) synth->dispatch[index].routine(synth, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); return(0); } static void sidMidiChannel(guiSynth *synth, int fd, int chan, int c, int o, int v) { if ((c == 0) && (++synth->midichannel > 15)) synth->midichannel = 15; else if ((c == 1) && (--synth->midichannel < 0)) synth->midichannel = 0; displayText(synth, "MIDI CHAN", synth->midichannel + 1, DISPLAY_DEV); if (global.libtest) return; bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_MIDICHANNEL|synth->midichannel); } /* * Any location initialisation required to run the callbacks. For bristol, this * will connect to the engine, and give it some base parameters. * May need to generate some application specific menus. * Will also then make specific requests to some of the devices to alter their * rendering. */ static int sidInit(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); dispatcher *dispatch; int i; if (synth == 0) { synth = findSynth(global.synths, 0); if (synth == 0) { printf("cannot init\n"); return(0); } } synth->win = win; printf("Initialise the sid link to bristol: %p\n", synth->win); synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float)); synth->mem.count = DEVICE_COUNT; synth->mem.active = ACTIVE_DEVS; synth->dispatch = (dispatcher *) brightonmalloc(DEVICE_COUNT * sizeof(dispatcher)); dispatch = synth->dispatch; /* * We really want to have three connection mechanisms. These should be * 1. Unix named sockets. * 2. UDP sockets (actually implements TCP unfortunately). * 3. MIDI pipe. */ if (!global.libtest) { if ((synth->sid = initConnection(&global, synth)) < 0) return(-1); } for (i = 0; i < DEVICE_COUNT; i++) { synth->dispatch[i].routine = (synthRoutine) sidMidiNull; synth->dispatch[i].controller = i; synth->dispatch[i].operator = i; } /* Voice 1 */ dispatch[0].controller = 126; dispatch[0].operator = 10; dispatch[0].routine = (synthRoutine) sidVoiceShim; dispatch[1].controller = 126; dispatch[1].operator = 11; dispatch[1].routine = (synthRoutine) sidVoiceShim; dispatch[2].controller = 126; dispatch[2].operator = 12; dispatch[2].routine = (synthRoutine) sidVoiceShim; dispatch[3].controller = 126; dispatch[3].operator = 13; dispatch[3].routine = (synthRoutine) sidVoiceShim; /* PW, tune, transpose, glide */ dispatch[4].controller = 126; dispatch[4].operator = 14; dispatch[4].routine = (synthRoutine) sidVoiceShim; dispatch[5].controller = 126; dispatch[5].operator = 15; dispatch[5].routine = (synthRoutine) sidVoiceShim; dispatch[6].controller = 126; dispatch[6].operator = 16; dispatch[6].routine = (synthRoutine) sidVoiceShim; dispatch[7].controller = 126; dispatch[7].operator = 17; dispatch[7].routine = (synthRoutine) sidVoiceShim; /* RM/sync/mute/route */ dispatch[8].controller = 126; dispatch[8].operator = 18; dispatch[8].routine = (synthRoutine) sidVoiceShim; dispatch[9].controller = 126; dispatch[9].operator = 19; dispatch[9].routine = (synthRoutine) sidVoiceShim; dispatch[10].controller = 126; dispatch[10].operator = 20; dispatch[10].routine = (synthRoutine) sidVoiceShim; dispatch[11].controller = 126; dispatch[11].operator = 21; dispatch[11].routine = (synthRoutine) sidVoiceShim; /* Env */ dispatch[12].controller = 126; dispatch[12].operator = 22; dispatch[12].routine = (synthRoutine) sidVoiceShim; dispatch[13].controller = 126; dispatch[13].operator = 23; dispatch[13].routine = (synthRoutine) sidVoiceShim; dispatch[14].controller = 126; dispatch[14].operator = 24; dispatch[14].routine = (synthRoutine) sidVoiceShim; dispatch[15].controller = 126; dispatch[15].operator = 25; dispatch[15].routine = (synthRoutine) sidVoiceShim; /* Voice 2 */ dispatch[20].controller = 126; dispatch[20].operator = 30; dispatch[20].routine = (synthRoutine) sidVoiceShim; dispatch[21].controller = 126; dispatch[21].operator = 31; dispatch[21].routine = (synthRoutine) sidVoiceShim; dispatch[22].controller = 126; dispatch[22].operator = 32; dispatch[22].routine = (synthRoutine) sidVoiceShim; dispatch[23].controller = 126; dispatch[23].operator = 33; dispatch[23].routine = (synthRoutine) sidVoiceShim; /* PW, tune, transpose, glide */ dispatch[24].controller = 126; dispatch[24].operator = 34; dispatch[24].routine = (synthRoutine) sidVoiceShim; dispatch[25].controller = 126; dispatch[25].operator = 35; dispatch[25].routine = (synthRoutine) sidVoiceShim; dispatch[26].controller = 126; dispatch[26].operator = 36; dispatch[26].routine = (synthRoutine) sidVoiceShim; dispatch[27].controller = 126; dispatch[27].operator = 37; dispatch[27].routine = (synthRoutine) sidVoiceShim; /* RM/sync/mute/route */ dispatch[28].controller = 126; dispatch[28].operator = 38; dispatch[28].routine = (synthRoutine) sidVoiceShim; dispatch[29].controller = 126; dispatch[29].operator = 39; dispatch[29].routine = (synthRoutine) sidVoiceShim; dispatch[30].controller = 126; dispatch[30].operator = 40; dispatch[30].routine = (synthRoutine) sidVoiceShim; dispatch[31].controller = 126; dispatch[31].operator = 41; dispatch[31].routine = (synthRoutine) sidVoiceShim; /* Env */ dispatch[32].controller = 126; dispatch[32].operator = 42; dispatch[32].routine = (synthRoutine) sidVoiceShim; dispatch[33].controller = 126; dispatch[33].operator = 43; dispatch[33].routine = (synthRoutine) sidVoiceShim; dispatch[34].controller = 126; dispatch[34].operator = 44; dispatch[34].routine = (synthRoutine) sidVoiceShim; dispatch[35].controller = 126; dispatch[35].operator = 45; dispatch[35].routine = (synthRoutine) sidVoiceShim; /* Voice 3 */ dispatch[40].controller = 126; dispatch[40].operator = 50; dispatch[40].routine = (synthRoutine) sidVoiceShim; dispatch[41].controller = 126; dispatch[41].operator = 51; dispatch[41].routine = (synthRoutine) sidVoiceShim; dispatch[42].controller = 126; dispatch[42].operator = 52; dispatch[42].routine = (synthRoutine) sidVoiceShim; dispatch[43].controller = 126; dispatch[43].operator = 53; dispatch[43].routine = (synthRoutine) sidVoiceShim; /* PW, tune, transpose, glide */ dispatch[44].controller = 126; dispatch[44].operator = 54; dispatch[44].routine = (synthRoutine) sidVoiceShim; dispatch[45].controller = 126; dispatch[45].operator = 55; dispatch[45].routine = (synthRoutine) sidVoiceShim; dispatch[46].controller = 126; dispatch[46].operator = 56; dispatch[46].routine = (synthRoutine) sidVoiceShim; dispatch[47].controller = 126; dispatch[47].operator = 57; dispatch[47].routine = (synthRoutine) sidVoiceShim; /* RM/sync/mute/route */ dispatch[48].controller = 126; dispatch[48].operator = 58; dispatch[48].routine = (synthRoutine) sidVoiceShim; dispatch[49].controller = 126; dispatch[49].operator = 59; dispatch[49].routine = (synthRoutine) sidVoiceShim; dispatch[50].controller = 126; dispatch[50].operator = 60; dispatch[50].routine = (synthRoutine) sidVoiceShim; dispatch[51].controller = 126; dispatch[51].operator = 61; dispatch[51].routine = (synthRoutine) sidVoiceShim; /* Env */ dispatch[52].controller = 126; dispatch[52].operator = 62; dispatch[52].routine = (synthRoutine) sidVoiceShim; dispatch[53].controller = 126; dispatch[53].operator = 63; dispatch[53].routine = (synthRoutine) sidVoiceShim; dispatch[54].controller = 126; dispatch[54].operator = 64; dispatch[54].routine = (synthRoutine) sidVoiceShim; dispatch[55].controller = 126; dispatch[55].operator = 65; dispatch[55].routine = (synthRoutine) sidVoiceShim; /* Filter */ dispatch[60].controller = 126; dispatch[60].operator = 70; dispatch[60].routine = (synthRoutine) sidMidiShim; dispatch[61].controller = 126; dispatch[61].operator = 71; dispatch[61].routine = (synthRoutine) sidMidiShim; dispatch[62].controller = 126; dispatch[62].operator = 72; dispatch[62].routine = (synthRoutine) sidMidiShim; /* Cutoff/res/OBmix */ dispatch[63].controller = 126; dispatch[63].operator = 73; dispatch[63].routine = (synthRoutine) sidMidiShim; dispatch[64].controller = 126; dispatch[64].operator = 74; dispatch[64].routine = (synthRoutine) sidMidiShim; dispatch[65].controller = 126; dispatch[65].operator = 75; dispatch[65].routine = (synthRoutine) sidMidiShim; dispatch[66].controller = 126; dispatch[66].operator = 76; dispatch[66].routine = (synthRoutine) sidMidiShim; /* Multi and master vol */ dispatch[67].controller = 126; dispatch[67].operator = 2; dispatch[67].routine = (synthRoutine) sidMidiShim; dispatch[68].controller = 126; dispatch[68].operator = 3; dispatch[68].routine = (synthRoutine) sidMidiShim; dispatch[69].operator = 0; dispatch[70].operator = 1; dispatch[71].operator = 2; dispatch[72].operator = 3; dispatch[73].operator = 4; dispatch[69].routine = dispatch[70].routine = dispatch[71].routine = dispatch[72].routine = dispatch[73].routine = (synthRoutine) sidMode; /* Mod freq, gain and waveform */ dispatch[74].controller = 126; dispatch[74].operator = 77; dispatch[74].routine = (synthRoutine) sidMidiShim; dispatch[75].controller = 126; dispatch[75].operator = 78; dispatch[75].routine = (synthRoutine) sidMidiShim; dispatch[76].operator = 0; dispatch[77].operator = 1; dispatch[78].operator = 2; dispatch[79].operator = 3; dispatch[76].routine = dispatch[77].routine = dispatch[78].routine = dispatch[79].routine = (synthRoutine) sidLFOWave; /* Then we have the routing buttons, TBD */ dispatch[80].controller = 126; dispatch[80].operator = 79; dispatch[80].routine = (synthRoutine) sidMidiShim; dispatch[81].controller = 126; dispatch[81].operator = 80; dispatch[81].routine = (synthRoutine) sidMidiShim; dispatch[82].controller = 126; dispatch[82].operator = 81; dispatch[82].routine = (synthRoutine) sidMidiShim; dispatch[83].controller = 126; dispatch[83].operator = 82; dispatch[83].routine = (synthRoutine) sidMidiShim; dispatch[84].controller = 126; dispatch[84].operator = 83; dispatch[84].routine = (synthRoutine) sidMidiShim; dispatch[85].controller = 126; dispatch[85].operator = 84; dispatch[85].routine = (synthRoutine) sidMidiShim; dispatch[86].controller = 126; dispatch[86].operator = 85; dispatch[86].routine = (synthRoutine) sidMidiShim; dispatch[87].controller = 126; dispatch[87].operator = 101; dispatch[87].routine = (synthRoutine) sidMidiShim; dispatch[88].controller = 126; dispatch[88].operator = 102; dispatch[88].routine = (synthRoutine) sidMidiShim; dispatch[95].controller = 126; dispatch[95].operator = 89; dispatch[95].routine = (synthRoutine) sidMidiShim; dispatch[96].controller = 126; dispatch[96].operator = 90; dispatch[96].routine = (synthRoutine) sidMidiShim; dispatch[97].controller = 126; dispatch[97].operator = 91; dispatch[97].routine = (synthRoutine) sidMidiShim; dispatch[98].controller = 126; dispatch[98].operator = 92; dispatch[98].routine = (synthRoutine) sidMidiShim; dispatch[99].controller = 126; dispatch[99].operator = 86; dispatch[99].routine = (synthRoutine) sidMidiShim; dispatch[100].controller = 126; dispatch[100].operator = 87; dispatch[100].routine = (synthRoutine) sidMidiShim; dispatch[101].controller = 126; dispatch[101].operator = 88; dispatch[101].routine = (synthRoutine) sidMidiShim; /* Env mod */ dispatch[102].controller = 126; dispatch[102].operator = 93; dispatch[102].routine = (synthRoutine) sidMidiShim; dispatch[103].controller = 126; dispatch[103].operator = 94; dispatch[103].routine = (synthRoutine) sidMidiShim; dispatch[104].controller = 126; dispatch[104].operator = 95; dispatch[104].routine = (synthRoutine) sidMidiShim; dispatch[105].controller = 126; dispatch[105].operator = 96; dispatch[105].routine = (synthRoutine) sidMidiShim; dispatch[106].controller = 126; dispatch[106].operator = 97; dispatch[106].routine = (synthRoutine) sidMidiShim; dispatch[107].controller = 126; dispatch[107].operator = 103; dispatch[107].routine = (synthRoutine) sidMidiShim; /* Arpeggiator */ dispatch[115].controller = 126; dispatch[115].operator = 6; dispatch[115].routine = (synthRoutine) sidMidiShim; dispatch[116].controller = 126; dispatch[116].operator = 7; dispatch[116].routine = (synthRoutine) sidMidiShim; dispatch[117].controller = 126; dispatch[117].operator = 8; dispatch[117].routine = (synthRoutine) sidMidiShim; /* Memory and MIDI */ dispatch[MEM_START + 0].operator = 1; dispatch[MEM_START + 1].operator = 2; dispatch[MEM_START + 2].operator = 3; dispatch[MEM_START + 3].operator = 4; dispatch[MEM_START + 4].operator = 5; dispatch[MEM_START + 5].operator = 6; dispatch[MEM_START + 6].operator = 7; dispatch[MEM_START + 7].operator = 8; dispatch[MEM_START + 8].controller = 1; dispatch[MEM_START + 9].controller = 2; dispatch[MEM_START + 10].controller = 3; dispatch[MEM_START + 11].controller = 4; dispatch[MEM_START + 12].controller = 5; dispatch[MEM_START + 13].controller = 6; dispatch[MEM_START + 0].routine = dispatch[MEM_START + 1].routine = dispatch[MEM_START + 2].routine = dispatch[MEM_START + 3].routine = dispatch[MEM_START + 4].routine = dispatch[MEM_START + 5].routine = dispatch[MEM_START + 6].routine = dispatch[MEM_START + 7].routine = dispatch[MEM_START + 8].routine = dispatch[MEM_START + 9].routine = dispatch[MEM_START + 10].routine = dispatch[MEM_START + 11].routine = dispatch[MEM_START + 12].routine = dispatch[MEM_START + 13].routine = (synthRoutine) sidMemory; dispatch[132].controller = 0; dispatch[133].controller = 1; dispatch[132].routine = dispatch[133].routine = (synthRoutine) sidMidiChannel; /* Osc-1 settings */ /* Env settings */ /* Filter */ dispatch[MEM_START].other1 = 1; dispatch[69].other1 = 0; dispatch[76].other1 = 0; return(0); } /* * This will be called to make any routine specific parameters available. */ static int sidConfigure(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); brightonEvent event; if (synth == 0) { printf("problems going operational\n"); return(-1); } if (synth->location == 0) { synth->bank = 1; synth->location = 1; } else if (synth->location > 0) { mbh = (synth->location / 100) * 100; if ((synth->bank = synth->location / 10) > 10) synth->bank = synth->bank % 10; if (((synth->location = synth->location % 10) == 0) || (synth->location > 8)) synth->location = 1; } if (synth->flags & OPERATIONAL) return(0); printf("going operational\n"); synth->flags |= OPERATIONAL; synth->keypanel = 1; synth->keypanel2 = -1; synth->transpose = 24; brightonPut(win, "bitmaps/blueprints/sidshade.xpm", 0, 0, win->width, win->height); /* * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only * occurs on first paint, so we suppress the first paint, and then request * an expose here. */ event.type = BRIGHTON_EXPOSE; event.intvalue = 1; brightonParamChange(synth->win, KEY_PANEL, -1, &event); event.type = BRISTOL_FLOAT; event.value = 1; brightonParamChange(synth->win, MODS_PANEL, 1, &event); brightonParamChange(synth->win, MODS_PANEL, 2, &event); brightonParamChange(synth->win, MODS_PANEL, 4, &event); configureGlobals(synth); /* First memory location */ event.value = 1.0; brightonParamChange(synth->win, 0, MEM_START + synth->location-1, &event); brightonParamChange(synth->win, 0, 69, &event); brightonParamChange(synth->win, 0, 76, &event); loadMemory(synth, SYNTH_NAME, 0, synth->bank * 10 + synth->location, synth->mem.active, 0, BRISTOL_FORCE); loadMemoryShim(synth); event.value = 0.505; brightonParamChange(synth->win, MODS_PANEL, 0, &event); synth->dispatch[MEM_START].other1 = synth->location; dc = brightonGetDCTimer(1000000); synth->loadMemory = (loadRoutine) loadMemoryKeyShim; return(0); } bristol-0.60.11/brighton/brightonOdyssey.c0000644000175000017500000011217611746476475015467 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* ARP Axxe */ #include #include "brighton.h" #include "brightonMini.h" #include "brightoninternals.h" static int initmem; static int odysseyInit(); static int odysseyConfigure(); static int odysseyCallback(brightonWindow *, int, int, float); /*static int keyCallback(void *, int, int, float); */ static int odysseyMemory(brightonWindow *, int, int, float); static void odysseyPanelSwitch(brightonWindow *); static int odysseyMidi(guiSynth *, int); static int midiCallback(brightonWindow *, int, int, float); extern guimain global; #include "brightonKeys.h" #define DEVICE_COUNT 61 #define ACTIVE_DEVS 61 /* Actually 57 - should not sve pitch control. */ #define MEM_START 0 #define MIDI_START (MEM_START + 18) #define RADIOSET_1 (ACTIVE_DEVS - 2) #define RADIOSET_2 (RADIOSET_1 + 1) #define KEY_PANEL 1 #define CDIFF 34 #define CDIFF2 15 #define C0 35 #define C1 85 #define C2 132 #define C3 (C2 + CDIFF) #define C4 (C3 + CDIFF) #define C5 (C4 + CDIFF) #define C6 (C5 + CDIFF + CDIFF2) #define C7 (C6 + CDIFF) #define C8 (C7 + CDIFF) #define C9 (C8 + CDIFF) #define C10 (C9 + CDIFF + CDIFF2) #define C11 (C10 + CDIFF) #define C12 (C11 + CDIFF + CDIFF) #define C13 (C12 + CDIFF) #define C14 (C13 + CDIFF) #define C15 (C14 + CDIFF) #define C16 (C15 + CDIFF) #define C17 (C16 + CDIFF) #define C18 (C17 + CDIFF) #define C19 (C18 + CDIFF + CDIFF + CDIFF2) #define C20 (C19 + CDIFF) #define C21 (C20 + CDIFF) #define C22 (C21 + CDIFF) #define C23 (C22 + CDIFF) #define R4 98 #define R0 (R4 + 428) #define R1 (R0 + 205) #define R2 (R0 + 75) #define R5 (R0 + 332) #define W1 12 #define W2 15 #define L1 242 /* * This structure is for device definition. The structure is defined in * include/brighton.h, further definitions in brighton/brightonDevtable.h and * include/brightoninternals.h * * typedef int (*brightonCallback)(int, float); * typedef struct BrightonLocations { * int device; 0=rotary, 1=scale, etc. * float relx, rely; relative position with regards to 1000 by 1000 window * float relw, relh; relative height. * int from, to; * brightonCallback callback; specific to this dev * char *image; bitmap. If zero take a device default. * int flags; * } brightonLocations; * * This example is for a odysseyBristol type synth interface. */ static brightonLocations locations[DEVICE_COUNT] = { /* Glide/Tranpose - 0 */ {"Glide", 1, C0 - 4, R0, W2, L1, 0, 1, 0, "bitmaps/knobs/sliderArpBlack.xpm", 0, 0}, {"Transpose", 2, C1, R2 + 20, 15, L1/2 - 40, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW}, /* VCO - 2 */ {"VCO1-FM-1", 1, C2, R0, W2, L1, 0, 1, 0, "bitmaps/knobs/sliderArpBlue.xpm", 0, 0}, {"VCO1-FM-2", 1, C3, R0, W2, L1, 0, 1, 0, "bitmaps/knobs/sliderArpRed.xpm", 0, 0}, {"VCO1-PW", 1, C4, R0, W2, L1, 0, 1, 0, "bitmaps/knobs/sliderArpBlack.xpm", 0, 0}, {"VCO1-PWM", 1, C5, R0, W2, L1, 0, 1, 0, "bitmaps/knobs/sliderArpYellow.xpm", 0, 0}, {"VCO1-Coarse", 1, C2, R4, W2, L1, 0, 1, 0, "bitmaps/knobs/sliderArpBlue.xpm", 0, BRIGHTON_NOTCH}, {"VCO1-Fine", 1, C3, R4, W2, L1, 0, 1, 0, "bitmaps/knobs/sliderArpRed.xpm", 0, BRIGHTON_NOTCH}, {"VCO1-Mod1-SinSqr", 2, C2, R5, W1 * 3/2, 60, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, {"VCO1-Mod2-SH/Env", 2, C3, R5, W1 * 3/2, 60, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, {"VCO1-PWM-Sine/Env", 2, C5, R5, W1 * 3/2, 60, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, {"VCO1-KBD/LFO", 2, C4, R4, W1 * 3/2, 60, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, /* VCO2 - 12 */ {"VCO2-FM-1", 1, C6, R0, W2, L1, 0, 1, 0, "bitmaps/knobs/sliderArpBlue.xpm", 0, 0}, {"VCO2-FM-2", 1, C7, R0, W2, L1, 0, 1, 0, "bitmaps/knobs/sliderArpRed.xpm", 0, 0}, {"VCO2-PW", 1, C8, R0, W2, L1, 0, 1, 0, "bitmaps/knobs/sliderArpBlack.xpm", 0, 0}, {"VCO2-PWM", 1, C9, R0, W2, L1, 0, 1, 0, "bitmaps/knobs/sliderArpYellow.xpm", 0, 0}, {"VCO2-Coarse", 1, C6, R4, W2, L1, 0, 1, 0, "bitmaps/knobs/sliderArpBlue.xpm", 0, BRIGHTON_NOTCH}, {"VCO2-Fine", 1, C7, R4, W2, L1, 0, 1, 0, "bitmaps/knobs/sliderArpRed.xpm", 0, BRIGHTON_NOTCH}, {"VCO2-Mod1-SinS/H", 2, C6, R5, W1 * 3/2, 60, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, {"VCO2-Mod2-SH/Env", 2, C7, R5, W1 * 3/2, 60, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, {"VCO2-PWM-Sine/Env", 2, C9, R5, W1 * 3/2, 60, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, {"VCO2-Sync", 2, C8, R4, W1 * 3/2, 60, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, /* Mods - 22 */ {"S/H-Mix-1", 1, C10, R0, W2, L1, 0, 1, 0, "bitmaps/knobs/sliderArpWhite.xpm", 0, 0}, {"S/H-Mix-2", 1, C11, R0, W2, L1, 0, 1, 0, "bitmaps/knobs/sliderArpWhite.xpm", 0, 0}, {"S/H-Gain", 1, C12, R0, W2, L1, 0, 1, 0, "bitmaps/knobs/sliderArpBlack.xpm", 0, 0}, {"LFO-Freq", 1, C12, R4, W2, L1, 0, 1, 0, "bitmaps/knobs/sliderArpBlack.xpm", 0, 0}, {"S/H-Mix1-RampSqr", 2, C10, R5, W1 * 3/2, 60, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, {"S/H-Mix2-NoiseVCO2", 2, C11, R5, W1 * 3/2, 60, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, {"S/H-Trig-KBD/LFO", 2, C12 - CDIFF, R5, W1 * 3/2, 60, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, /* Filter, etc - 29 */ {"Mix-1-Lvl", 1, C13, R0, W2, L1, 0, 1, 0, "bitmaps/knobs/sliderArpYellow.xpm", 0, 0}, {"Mix-2-Lvl", 1, C14, R0, W2, L1, 0, 1, 0, "bitmaps/knobs/sliderArpBlue.xpm", 0, 0}, {"Mix-3-Lvl", 1, C15, R0, W2, L1, 0, 1, 0, "bitmaps/knobs/sliderArpRed.xpm", 0, 0}, {"VCF-Mod-1", 1, C16, R0, W2, L1, 0, 1, 0, "bitmaps/knobs/sliderArpGreen.xpm", 0, 0}, {"VCF-Mod-2", 1, C17, R0, W2, L1, 0, 1, 0, "bitmaps/knobs/sliderArpGreen.xpm", 0, 0}, {"VCF-Mod-3", 1, C18, R0, W2, L1, 0, 1, 0, "bitmaps/knobs/sliderArpGreen.xpm", 0, 0}, {"VCA-EnvLvl", 1, C19, R0, W2, L1, 0, 1, 0, "bitmaps/knobs/sliderArpRed.xpm", 0, 0}, {"VCF-Cutoff", 1, C13, R4, W2, L1, 0, 1, 0, "bitmaps/knobs/sliderArpWhite.xpm", 0, 0}, {"VCF-Res", 1, C14, R4, W2, L1, 0, 1, 0, "bitmaps/knobs/sliderArpWhite.xpm", 0, 0}, {"HPF-Cutoff", 1, C18, R4, W2, L1, 0, 1, 0, "bitmaps/knobs/sliderArpGreen.xpm", 0, 0}, {"VCA-Gain", 1, C19, R4, W2, L1, 0, 1, 0, "bitmaps/knobs/sliderArpRed.xpm", 0, 0}, /* And its routing - 40 */ {"MIX-Noise/RM", 2, C13, R5, W1 * 3/2, 60, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, {"MIX-VCO1-RampSqr", 2, C14, R5, W1 * 3/2, 60, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, {"MIX-VCO2-RampSqr", 2, C15, R5, W1 * 3/2, 60, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, {"VCO-Mod1-KBD/SH", 2, C16, R5, W1 * 3/2, 60, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, {"VCO-Mod2-SH/LFO", 2, C17, R5, W1 * 3/2, 60, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, {"VCO-Mod3-ADSR/SR", 2, C18, R5, W1 * 3/2, 60, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, {"VCA-ADSR/AR", 2, C19, R5, W1 * 3/2, 60, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, /* ADSR - 47 */ {"Attack", 1, C20, R0, W2, L1, 0, 1, 0, "bitmaps/knobs/sliderArpRed.xpm", 0, 0}, {"Decay", 1, C21, R0, W2, L1, 0, 1, 0, "bitmaps/knobs/sliderArpRed.xpm", 0, 0}, {"Sustain", 1, C22, R0, W2, L1, 0, 1, 0, "bitmaps/knobs/sliderArpRed.xpm", 0, 0}, {"Release", 1, C23, R0, W2, L1, 0, 1, 0, "bitmaps/knobs/sliderArpRed.xpm", 0, 0}, {"AR-Attack", 1, C20, R4, W2, L1, 0, 1, 0, "bitmaps/knobs/sliderArpRed.xpm", 0, 0}, {"AR-Release", 1, C21, R4, W2, L1, 0, 1, 0, "bitmaps/knobs/sliderArpRed.xpm", 0, 0}, {"ADSR-KBD/REPEAT", 2, C20, R5, W1 * 3/2, 60, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, {"ADSR-KBD/AUTO", 2, C22, R5, W1 * 3/2, 60, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, {"AR-KBD/REPEAT", 2, C23, R5, W1 * 3/2, 60, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, /* Pink/White noise - 56 */ {"Noise-White/Pink", 2, C1, R4, W1 * 3/2, 60, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, /* Pitch Control - 57 */ {"Pitch-Flat", 2, 25, R5, 30, 60, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlw.xpm", 0}, {"Pitch-Trill", 2, 53, R5, 30, 60, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlw.xpm", 0}, {"Pitch-Sharp", 2, 80, R5, 30, 60, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlw.xpm", 0}, /* Dual osc frequencies */ {"VCO2-Dual", 2, C8, R4 + 160, W1 * 3/2, 60, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, }; static brightonLocations locations2[DEVICE_COUNT] = { /* Glide/Tranpose - 0 */ {"", 1, C0, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack3.xpm", 0, 0}, // {"", 2, C1, R2, 15, L1/2 - 10, 0, 2, 0, 0, 0, {"Transpose", 2, C1, R2 + 20, 15, L1/2 - 40, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW}, /* VCO - 2 */ {"", 1, C2, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack3.xpm", 0, 0}, {"", 1, C3, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack3.xpm", 0, 0}, {"", 1, C4, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack3.xpm", 0, 0}, {"", 1, C5, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack3.xpm", 0, 0}, {"", 1, C2, R4, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack3.xpm", 0, BRIGHTON_NOTCH}, {"", 1, C3, R4, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack3.xpm", 0, BRIGHTON_NOTCH}, {"", 2, C2, R5, W1 * 3/2, 60, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, {"", 2, C3, R5, W1 * 3/2, 60, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, {"", 2, C5, R5, W1 * 3/2, 60, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, {"", 2, C4, R4, W1 * 3/2, 60, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, /* VCO2 - 12 */ {"", 1, C6, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack3.xpm", 0, 0}, {"", 1, C7, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack3.xpm", 0, 0}, {"", 1, C8, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack3.xpm", 0, 0}, {"", 1, C9, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack3.xpm", 0, 0}, {"", 1, C6, R4, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack3.xpm", 0, BRIGHTON_NOTCH}, {"", 1, C7, R4, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack3.xpm", 0, BRIGHTON_NOTCH}, {"", 2, C6, R5, W1 * 3/2, 60, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, {"", 2, C7, R5, W1 * 3/2, 60, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, {"", 2, C9, R5, W1 * 3/2, 60, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, {"", 2, C8, R4, W1 * 3/2, 60, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, /* Mods - 22 */ {"", 1, C10, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack3.xpm", 0, 0}, {"", 1, C11, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack3.xpm", 0, 0}, {"", 1, C12, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack3.xpm", 0, 0}, {"", 1, C12, R4, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack3.xpm", 0, 0}, {"", 2, C10, R5, W1 * 3/2, 60, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, {"", 2, C11, R5, W1 * 3/2, 60, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, {"", 2, C12 - CDIFF, R5, W1 * 3/2, 60, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, /* Filter, etc - 29 */ {"", 1, C13, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack3.xpm", 0, 0}, {"", 1, C14, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack3.xpm", 0, 0}, {"", 1, C15, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack3.xpm", 0, 0}, {"", 1, C16, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack3.xpm", 0, 0}, {"", 1, C17, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack3.xpm", 0, 0}, {"", 1, C18, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack3.xpm", 0, 0}, {"", 1, C19, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack3.xpm", 0, 0}, {"", 1, C13, R4, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack3.xpm", 0, 0}, {"", 1, C14, R4, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack3.xpm", 0, 0}, {"", 1, C18, R4, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack3.xpm", 0, 0}, {"", 1, C19, R4, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack3.xpm", 0, 0}, /* And its routing - 40 */ {"", 2, C13, R5, W1 * 3/2, 60, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, {"", 2, C14, R5, W1 * 3/2, 60, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, {"", 2, C15, R5, W1 * 3/2, 60, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, {"", 2, C16, R5, W1 * 3/2, 60, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, {"", 2, C17, R5, W1 * 3/2, 60, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, {"", 2, C18, R5, W1 * 3/2, 60, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, {"", 2, C19, R5, W1 * 3/2, 60, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, /* ADSR - 47 */ {"", 1, C20, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack3.xpm", 0, 0}, {"", 1, C21, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack3.xpm", 0, 0}, {"", 1, C22, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack3.xpm", 0, 0}, {"", 1, C23, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack3.xpm", 0, 0}, {"", 1, C20, R4, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack3.xpm", 0, 0}, {"", 1, C21, R4, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack3.xpm", 0, 0}, {"", 2, C20, R5, W1 * 3/2, 60, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, {"", 2, C22, R5, W1 * 3/2, 60, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, {"", 2, C23, R5, W1 * 3/2, 60, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, /* Pink/White noise - 56 */ {"", 2, C1, R4, W1 * 3/2, 60, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, /* Pitch Control - 57 */ {"", 2, 25, R5, 30, 60, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlw.xpm", 0}, {"", 2, 53, R5, 30, 60, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlw.xpm", 0}, {"", 2, 80, R5, 30, 60, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlw.xpm", 0}, /* Dual osc frequencies */ {"VCO2-Dual", 2, C8, R4 + 160, W1 * 3/2, 60, 0, 1, 0, "bitmaps/buttons/klunk.xpm", 0, BRIGHTON_VERTICAL}, }; #define BDIFF (CDIFF) #define BDIFF2 (CDIFF2) #define B0 190 #define B1 (B0 + BDIFF + BDIFF2) #define B2 (B1 + BDIFF) #define B3 (B2 + BDIFF) #define B4 (B3 + BDIFF) #define B5 (B4 + BDIFF) #define B6 (B5 + BDIFF) #define B7 (B6 + BDIFF) #define B8 (B7 + BDIFF) #define B9 (B8 + BDIFF + BDIFF2) #define B10 (B9 + BDIFF) #define B11 (B10 + BDIFF) #define B12 (B11 + BDIFF) #define B13 (B12 + BDIFF) #define B14 (B13 + BDIFF) #define B15 (B14 + BDIFF) #define B16 (B15 + BDIFF) #define B17 (B16 + BDIFF + BDIFF2) #define B20 40 #define B18 (B20 + BDIFF + BDIFF2 + 10) #define B19 (B18 + BDIFF + BDIFF2) #define BL1 500 #define R3 200 static brightonLocations memories[21] = { /* Memory Load, mem, Save - 61 */ {"", 2, B0, R3, 20, BL1, 0, 1, 0, "bitmaps/buttons/pressoffw.xpm", "bitmaps/buttons/pressonw.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, B1, R3, 20, BL1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B2, R3, 20, BL1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B3, R3, 20, BL1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B4, R3, 20, BL1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B5, R3, 20, BL1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B6, R3, 20, BL1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B7, R3, 20, BL1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B8, R3, 20, BL1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B9, R3, 20, BL1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B10, R3, 20, BL1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B11, R3, 20, BL1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B12, R3, 20, BL1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B13, R3, 20, BL1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B14, R3, 20, BL1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B15, R3, 20, BL1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B16, R3, 20, BL1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, B17, R3, 20, BL1, 0, 1, 0, "bitmaps/buttons/pressoffo.xpm", "bitmaps/buttons/pressono.xpm", BRIGHTON_CHECKBUTTON}, /* MIDI */ {"", 2, B18, R3, 20, BL1, 0, 1, 0, "bitmaps/buttons/pressoffw.xpm", "bitmaps/buttons/pressonw.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, B19, R3, 20, BL1, 0, 1, 0, "bitmaps/buttons/pressoffw.xpm", "bitmaps/buttons/pressonw.xpm", BRIGHTON_CHECKBUTTON}, /* Panel switch */ {"", 2, B20, R3, 20, BL1, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON}, }; /* */ /* * This is a set of globals for the main window rendering. Again taken from * include/brighton.h */ brightonApp odysseyApp = { "odyssey", 0, /* no blueprint on background. */ "bitmaps/textures/metal4.xpm", 0, /* BRIGHTON_STRETCH, //flags */ odysseyInit, odysseyConfigure, /* 3 callbacks, unused? */ midiCallback, destroySynth, {1, 100, 2, 2, 5, 520, 0, 0}, 600, 450, 0, 0, 6, /* Panels */ { { "Odyssey", "bitmaps/blueprints/odyssey2.xpm", "bitmaps/textures/metal4.xpm", BRIGHTON_REVERSE|BRIGHTON_STRETCH, /* flags */ 0, 0, odysseyCallback, 15, 0, 970, 680, DEVICE_COUNT, locations }, { "Keyboard", 0, "bitmaps/newkeys/ekbg.xpm", /* flags */ 0x020|BRIGHTON_STRETCH, 0, 0, keyCallback, 60, 750, 900, 250, KEY_COUNT_3OCTAVE, keys3octave }, { "Odyssey", 0, "bitmaps/textures/metal4.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 0, 0, 15, 1000, 0, 0 }, { "Odyssey", 0, "bitmaps/textures/metal4.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 985, 0, 15, 1000, 0, 0 }, { "Odyssey", "bitmaps/blueprints/odyssey.xpm", "bitmaps/textures/metal6.xpm", BRIGHTON_STRETCH, /* flags */ 0, 0, odysseyCallback, 15, 0, 970, 680, DEVICE_COUNT, locations2 }, { "Odyssey", "bitmaps/blueprints/odysseymem.xpm", "bitmaps/textures/metal6.xpm", BRIGHTON_STRETCH, /* flags */ 0, 0, odysseyMemory, 15, 680, 970, 70, 21, memories } } }; static int midiCallback(brightonWindow *win, int controller, int value, float n) { guiSynth *synth = findSynth(global.synths, win); printf("midi callback: %x, %i\n", controller, value); switch(controller) { case MIDI_PROGRAM: printf("midi program: %x, %i\n", controller, value); synth->location = value; loadMemory(synth, "odyssey", 0, synth->bank + synth->location, synth->mem.active, 0, 0); break; case MIDI_BANK_SELECT: printf("midi banksel: %x, %i\n", controller, value); synth->bank = value; break; } return(0); } static int odysseyMidiSendMsg(void *synth, int fd, int chan, int c, int o, int v) { bristolMidiSendMsg(fd, chan, c, o, v); return(0); } /* * This will be called back with memories, midi and panel switch. */ static int odysseyMemory(brightonWindow * win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); brightonEvent event; /*printf("odysseyMemory(%i, %f)\n", index, value); */ switch(index) { case 17: saveMemory(synth, "odyssey", 0, synth->bank + synth->location, 0); return(0); break; case 0: loadMemory(synth, "odyssey", 0, synth->bank + synth->location, synth->mem.active, 0, 0); return(0); break; case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: if (synth->dispatch[RADIOSET_1].other2) { synth->dispatch[RADIOSET_1].other2 = 0; return(0); } if (synth->dispatch[RADIOSET_1].other1 != -1) { synth->dispatch[RADIOSET_1].other2 = 1; if (synth->dispatch[RADIOSET_1].other1 != index) event.value = 0; else event.value = 1; brightonParamChange(synth->win, 5, synth->dispatch[RADIOSET_1].other1 + MEM_START, &event); } synth->dispatch[RADIOSET_1].other1 = index; synth->bank = index * 10; break; case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: if (synth->dispatch[RADIOSET_2].other2) { synth->dispatch[RADIOSET_2].other2 = 0; return(0); } if (synth->dispatch[RADIOSET_2].other1 != -1) { synth->dispatch[RADIOSET_2].other2 = 1; if (synth->dispatch[RADIOSET_2].other1 != index) event.value = 0; else event.value = 1; brightonParamChange(synth->win, 5, synth->dispatch[RADIOSET_2].other1 + MEM_START, &event); } synth->dispatch[RADIOSET_2].other1 = index; /* Do radio buttons */ synth->location = index - 8; break; case 18: /* * Midi down */ odysseyMidi(synth, 1); break; case 19: /* * Midi Up */ odysseyMidi(synth, 0); break; case 20: /* * Midi Panel Switch */ odysseyPanelSwitch(win); break; } return(0); } static int odysseyMidi(guiSynth *synth, int c) { int newchan; if ((synth->flags & OPERATIONAL) == 0) return(0); if (c == 1) { if ((newchan = synth->midichannel - 1) < 0) { synth->midichannel = 0; return(0); } } else { if ((newchan = synth->midichannel + 1) >= 16) { synth->midichannel = 15; return(0); } } if (global.libtest == 0) { /* * To overcome that we should consider checking a sequence number in * the message library? That is non trivial since it requires that * our midi messges have a 'ack' flag included - we cannot check for * ack here (actually, we could, and in the app is probably the right * place to do it rather than the lib however both would have to be * changed to suppor this - nc). */ bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_MIDICHANNEL|newchan); } synth->midichannel = newchan; return(0); } static int oMark = 4; static float *bs; static void odysseyPanelSwitch(brightonWindow * win) { brightonEvent event; guiSynth *synth = findSynth(global.synths, win); /*printf("odysseyPanelSwitch()\n"); */ /* bcopy(synth->mem.param, bs, DEVICE_COUNT * sizeof(float)); */ if (oMark == 0) { event.type = BRIGHTON_EXPOSE; event.intvalue = 0; brightonParamChange(synth->win, 0, -1, &event); event.intvalue = 1; brightonParamChange(synth->win, 4, -1, &event); oMark = 4; /* And toggle the filter type - rooney. */ /*bristolMidiSendMsg(global.controlfd, synth->sid, 3, 4, 3); */ bristolMidiSendMsg(global.controlfd, synth->sid, 3, 4, 4); } else { event.type = BRIGHTON_EXPOSE; event.intvalue = 0; brightonParamChange(synth->win, 4, -1, &event); event.intvalue = 1; brightonParamChange(synth->win, 0, -1, &event); oMark = 0; /* And toggle the filter type - chamberlain. */ bristolMidiSendMsg(global.controlfd, synth->sid, 3, 4, 0); } /* printf("odysseyPanelSwitch(%i)\n", oMark); event.type = BRIGHTON_FLOAT; for (i = 0; i < ACTIVE_DEVS; i++) { event.value = bs[i]; synth->mem.param[i] = bs[i] - 1; brightonParamChange(synth->win, oMark, i, &event); } */ } int calling = 0; /* * For the sake of ease of use, links have been placed here to be called * by any of the devices created. They would be better in some other file, * perhaps with this as a dispatch. * * Param refers to the device index in the locations table given below. */ static int odysseyCallback(brightonWindow * win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); int sendvalue; /*printf("odysseyCallback(%i, %f): %x\n", index, value, synth); */ if (synth == 0) return(0); if (panel != 0) { brightonEvent event; /* * We are in the second panel, alternative skin. The GUI will have * changed, but call ourselves back in panel 0 for all other changes. */ event.type = BRIGHTON_FLOAT; event.value = value; brightonParamChange(synth->win, 0, index, &event); return(0); } else { brightonEvent event; /* * We were in panel 0, we need to adjust the parameter in the next * layer */ if (calling) return(0); calling = 1; event.type = BRIGHTON_FLOAT; event.value = value; brightonParamChange(synth->win, 4, index, &event); calling = 0; } if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0)) return(0); if (odysseyApp.resources[0].devlocn[index].to == 1.0) sendvalue = value * (CONTROLLER_RANGE - 1); else sendvalue = value; synth->mem.param[index] = value; if ((!global.libtest) || (index >= ACTIVE_DEVS)) synth->dispatch[index].routine(synth, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #ifdef DEBUG else printf("dispatch[%x,%i](%i, %i, %i, %i, %i)\n", synth, index, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #endif return(0); } static void odysseyLFO(guiSynth *synth, int fd, int chan, int c, int o, int v) { if (v == 0) bristolMidiSendMsg(global.controlfd, synth->sid, 0, 1, 10); else bristolMidiSendMsg(global.controlfd, synth->sid, 0, 1, 2); } static void odysseyTranspose(guiSynth *synth, int fd, int chan, int c, int o, int v) { switch (v) { case 0: synth->transpose = 36; break; case 1: synth->transpose = 48; break; case 2: synth->transpose = 60; break; } } static void odysseyFiltOpt(guiSynth *synth, int fd, int chan, int c, int o, int v) { /* * This filter mod is either SH MIX or Keyboard tracking. One causes a * buffer selection, the other is a filter option. */ /*printf("odysseyFiltOpt(%i, %i)\n", o, v); */ if (o == 23) { /* * Continuous. */ if (synth->mem.param[43] == 0) bristolMidiSendMsg(global.controlfd, synth->sid, 126, 23, v); else bristolMidiSendMsg(global.controlfd, synth->sid, 3, 3, v); } else { if (v == 0) { /* * Key tracking switch. */ bristolMidiSendMsg(global.controlfd, synth->sid, 126, 31, 0); bristolMidiSendMsg(global.controlfd, synth->sid, 126, 23, 0); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 3, synth->mem.param[32] * C_RANGE_MIN_1); } else { bristolMidiSendMsg(global.controlfd, synth->sid, 126, 31, 1); bristolMidiSendMsg(global.controlfd, synth->sid, 126, 23, synth->mem.param[32] * C_RANGE_MIN_1); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 3, 0); } } } static void arAutoTrig(guiSynth *synth, int fd, int chan, int c, int o, int v) { /* * This takes the LFO value and sends it to the LFO, and if we have auto * trig configured will also send a value to 126/19 for trigger repeat rate. */ if (o == 55) { /* * Repeat switch */ if (v == 0) { /* * Repeat. Send request and configure AR values */ bristolMidiSendMsg(fd, chan, 126, 55, 1); bristolMidiSendMsg(global.controlfd, synth->sid, 7, 2, 100); } else { bristolMidiSendMsg(fd, chan, 126, 55, 0); bristolMidiSendMsg(global.controlfd, synth->sid, 7, 2, 16383); } return; } if (o == 3) { bristolMidiSendMsg(global.controlfd, synth->sid, 7, 1, (int) (synth->mem.param[52] * C_RANGE_MIN_1)); bristolMidiSendMsg(global.controlfd, synth->sid, 7, 3, (int) (synth->mem.param[52] * C_RANGE_MIN_1)); return; } } /* * Any location initialisation required to run the callbacks. For bristol, this * will connect to the engine, and give it some base parameters. * May need to generate some application specific menus. * Will also then make specific requests to some of the devices to alter their * rendering. */ static int odysseyInit(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); dispatcher *dispatch; int i; if (synth == 0) { synth = findSynth(global.synths, (int) 0); if (synth == 0) { printf("cannot init\n"); return(0); } } if ((initmem = synth->location) == 0) initmem = 11; synth->win = win; printf("Initialise the odyssey link to bristol: %p\n", synth->win); synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float)); bs = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float)); synth->mem.count = DEVICE_COUNT; synth->mem.active = ACTIVE_DEVS; synth->dispatch = (dispatcher *) brightonmalloc(DEVICE_COUNT * sizeof(dispatcher)); dispatch = synth->dispatch; /* * We really want to have three connection mechanisms. These should be * 1. Unix named sockets. * 2. UDP sockets. * 3. MIDI pipe. */ if (!global.libtest) { if ((synth->sid = initConnection(&global, synth)) < 0) return(-1); } for (i = 0; i < DEVICE_COUNT; i++) { synth->dispatch[i].routine = odysseyMidiSendMsg; } /* Glide/Octave */ dispatch[0].controller = 126; dispatch[0].operator = 0; dispatch[1].controller = 126; dispatch[1].operator = 0; dispatch[1].routine = (synthRoutine) odysseyTranspose; /* Osc-1 FM MOD */ dispatch[2].controller = 126; dispatch[2].operator = 2; dispatch[3].controller = 126; dispatch[3].operator = 3; /* Osc-1 PW MOD */ dispatch[4].controller = 0; dispatch[4].operator = 0; dispatch[5].controller = 126; dispatch[5].operator = 4; /* Osc-1 Freq coarse/fine */ dispatch[6].controller = 0; dispatch[6].operator = 2; dispatch[7].controller = 0; dispatch[7].operator = 10; /* Osc1 lfo/sh/etc */ dispatch[8].controller = 126; dispatch[8].operator = 5; dispatch[9].controller = 126; dispatch[9].operator = 6; dispatch[10].controller = 126; dispatch[10].operator = 7; /* Osc-1 key/lfo - not done..... */ dispatch[11].controller = 126; dispatch[11].operator = 100; dispatch[11].routine = (synthRoutine) odysseyLFO; /* Osc-2 FM */ dispatch[12].controller = 126; dispatch[12].operator = 8; dispatch[13].controller = 126; dispatch[13].operator = 9; /* Osc-2 PW */ dispatch[14].controller = 1; dispatch[14].operator = 0; dispatch[15].controller = 126; dispatch[15].operator = 10; /* Osc-2 Freq coarse/fine */ dispatch[16].controller = 1; dispatch[16].operator = 2; dispatch[17].controller = 1; dispatch[17].operator = 10; /* Osc-2 lfo/sh/etc */ dispatch[18].controller = 126; dispatch[18].operator = 11; dispatch[19].controller = 126; dispatch[19].operator = 12; dispatch[20].controller = 126; dispatch[20].operator = 13; /* Osc-2 Sync */ dispatch[21].controller = 1; dispatch[21].operator = 7; /* SH mixer */ dispatch[22].controller = 126; dispatch[22].operator = 14; dispatch[23].controller = 126; dispatch[23].operator = 15; /* SH Output? */ dispatch[24].controller = 126; dispatch[24].operator = 16; /* LFO freq */ dispatch[25].controller = 2; dispatch[25].operator = 0; /* SH Mods */ dispatch[26].controller = 126; dispatch[26].operator = 17; dispatch[27].controller = 126; dispatch[27].operator = 18; dispatch[28].controller = 126; dispatch[28].operator = 19; /* Audio Mixer */ dispatch[29].controller = 126; dispatch[29].operator = 20; dispatch[30].controller = 126; dispatch[30].operator = 21; dispatch[31].controller = 126; dispatch[31].operator = 22; /* VCF Mods */ dispatch[32].controller = 126; dispatch[32].operator = 23; dispatch[32].routine = (synthRoutine) odysseyFiltOpt; dispatch[33].controller = 126; dispatch[33].operator = 24; dispatch[34].controller = 126; dispatch[34].operator = 25; /* VCA Env */ dispatch[35].controller = 126; dispatch[35].operator = 26; /* VCF Cutoff/Req */ dispatch[36].controller = 3; dispatch[36].operator = 0; dispatch[37].controller = 3; dispatch[37].operator = 1; /* HPF Cutoff */ dispatch[38].controller = 9; dispatch[38].operator = 0; /* VCA Gain */ dispatch[39].controller = 126; dispatch[39].operator = 27; /* Diverse Mods */ dispatch[40].controller = 126; dispatch[40].operator = 28; dispatch[41].controller = 126; dispatch[41].operator = 29; dispatch[42].controller = 126; dispatch[42].operator = 30; dispatch[43].controller = 126; dispatch[43].operator = 31; dispatch[43].routine = (synthRoutine) odysseyFiltOpt; dispatch[44].controller = 126; dispatch[44].operator = 32; dispatch[45].controller = 126; dispatch[45].operator = 33; dispatch[46].controller = 126; dispatch[46].operator = 34; /* ADSR */ dispatch[47].controller = 4; dispatch[47].operator = 0; dispatch[48].controller = 4; dispatch[48].operator = 1; dispatch[49].controller = 4; dispatch[49].operator = 2; dispatch[50].controller = 4; dispatch[50].operator = 3; /* AR */ dispatch[51].controller = 7; dispatch[51].operator = 0; dispatch[52].controller = 7; dispatch[52].operator = 3; dispatch[52].routine = (synthRoutine) arAutoTrig; /* Env Mods */ dispatch[53].controller = 126; dispatch[53].operator = 53; dispatch[54].controller = 126; dispatch[54].operator = 49; dispatch[55].controller = 126; dispatch[55].operator = 55; dispatch[55].routine = (synthRoutine) arAutoTrig; /* Noise white/pink */ dispatch[56].controller = 6; dispatch[56].operator = 1; /* PPC */ dispatch[57].controller = 126; dispatch[57].operator = 57; dispatch[58].controller = 126; dispatch[58].operator = 58; dispatch[59].controller = 126; dispatch[59].operator = 59; dispatch[60].controller = 126; dispatch[60].operator = 60; /* * Need to specify env gain fixed, filter mod on, osc waveform. */ bristolMidiSendMsg(global.controlfd, synth->sid, 4, 4, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 2, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 4, 4); bristolMidiSendMsg(global.controlfd, synth->sid, 126, 49, 0); bristolMidiSendMsg(global.controlfd, synth->sid, 2, 1, 0); /* These will change the ringmod osc */ bristolMidiSendMsg(global.controlfd, synth->sid, 8, 3, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 8, 1, 5); bristolMidiSendMsg(global.controlfd, synth->sid, 8, 8, 16383); /* AR envelope fixed parameters. */ bristolMidiSendMsg(global.controlfd, synth->sid, 7, 1, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 7, 2, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 7, 4, 16383); /* Ringmodd parameters. */ bristolMidiSendMsg(global.controlfd, synth->sid, 8, 0, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 8, 1, 128); bristolMidiSendMsg(global.controlfd, synth->sid, 8, 2, 16383); /* * Grooming env for 'gain' to amp. Short but not choppy attack, slightly * larger decay since the main env can shorten that if really desired. */ bristolMidiSendMsg(global.controlfd, synth->sid, 10, 0, 20); bristolMidiSendMsg(global.controlfd, synth->sid, 10, 1, 1000); bristolMidiSendMsg(global.controlfd, synth->sid, 10, 2, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 10, 3, 50); bristolMidiSendMsg(global.controlfd, synth->sid, 10, 4, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 10, 5, 0); /* - velocity */ bristolMidiSendMsg(global.controlfd, synth->sid, 10, 6, 0); /* - rezero */ return(0); } /* * This will be called to make any routine specific parameters available. */ static int odysseyConfigure(brightonWindow* win) { guiSynth *synth = findSynth(global.synths, win); brightonEvent event; if (synth == 0) { printf("problems going operational\n"); return(-1); } if (synth->flags & OPERATIONAL) return(0); printf("going operational\n"); synth->flags |= OPERATIONAL; synth->keypanel = 1; synth->keypanel2 = -1; synth->transpose = 36; if (synth->location == 1) { synth->bank = 10; synth->location = 11; } loadMemory(synth, "odyssey", 0, initmem, synth->mem.active, 0, 0); event.value = 1; brightonParamChange(synth->win, 5, MEM_START + 1, &event); brightonParamChange(synth->win, 5, MEM_START + 9, &event); brightonPut(win, "bitmaps/blueprints/odysseyshade.xpm", 0, 0, win->width, win->height); /* * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only * occurs on first paint, so we suppress the first paint, and then request * an expose here. */ event.type = BRIGHTON_EXPOSE; event.intvalue = 1; brightonParamChange(synth->win, KEY_PANEL, -1, &event); /* * Touch a key on/off */ /* bristolMidiSendMsg(global.controlfd, synth->midichannel, */ /* BRISTOL_EVENT_KEYON, 0, 10 + synth->transpose); */ /* bristolMidiSendMsg(global.controlfd, synth->midichannel, */ /* BRISTOL_EVENT_KEYOFF, 0, 10 + synth->transpose); */ configureGlobals(synth); return(0); } bristol-0.60.11/brighton/brightonGranular.c0000644000175000017500000007506611746476475015611 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* * Variables: * Some LFO * Some ADSR (7 stage?) * Osc: F/V/S, G/V/S, D/V/S, Waveforms. */ #include #include "brighton.h" #include "brightonMini.h" #include "brightoninternals.h" static int granularInit(); static int granularConfigure(); static int granularCallback(brightonWindow *, int, int, float); static int midiCallback(brightonWindow *, int, int, float); extern guimain global; static int dc1, dc2; #include "brightonKeys.h" #define MOD_PANEL 0 #define KEY_PANEL 1 #define MEM_PANEL 2 #define MOD_COUNT 150 #define MEM_COUNT 21 #define MOD_START 0 #define MEM_START (MOD_COUNT - MEM_COUNT) #define ACTIVE_DEVS (MOD_COUNT - MEM_COUNT) #define DEVICE_COUNT MOD_COUNT /* * This structure is for device definition. The structure is defined in * include/brighton.h, further definitions in brighton/brightonDevtable.h and * include/brightoninternals.h * * typedef int (*brightonCallback)(int, float); * typedef struct BrightonLocations { * int device; 0=rotary, 1=scale, etc. * float relx, rely; relative position with regards to 1000 by 1000 window * float relw, relh; relative height. * int from, to; * brightonCallback callback; specific to this dev * char *image; bitmap. If zero take a device default. * int flags; * } brightonLocations; * * This example is for a granularBristol type synth interface. */ #define SBXS 15 #define SBYS 50 #define SBXD 15 #define SBYD 50 #define SELECTBUS(x, y) \ {"", 2, x + 0 * SBXD, y + 0 * SBYD, SBXS, SBYS, 0, 1.01, 0, \ "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, \ {"", 2, x + 0 * SBXD, y + 1 * SBYD, SBXS, SBYS, 0, 4, 0, \ "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, \ {"", 2, x + 0 * SBXD, y + 2 * SBYD, SBXS, SBYS, 0, 7, 0, \ "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, \ {"", 2, x + 1 * SBXD, y + 0 * SBYD, SBXS, SBYS, 0, 2, 0, \ "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, \ {"", 2, x + 1 * SBXD, y + 1 * SBYD, SBXS, SBYS, 0, 5, 0, \ "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, \ {"", 2, x + 1 * SBXD, y + 2 * SBYD, SBXS, SBYS, 0, 8, 0, \ "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, \ {"", 2, x + 2 * SBXD, y + 0 * SBYD, SBXS, SBYS, 0, 3, 0, \ "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, \ {"", 2, x + 2 * SBXD, y + 1 * SBYD, SBXS, SBYS, 0, 6, 0, \ "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, \ {"", 2, x + 2 * SBXD, y + 2 * SBYD, SBXS, SBYS, 0, 9, 0, \ "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0} #define MRXS 15 #define MRYS 50 #define MRXD 15 #define MRYD 54 #define MODROUTING(x, y) \ {"", 2, x + 0 * MRXD, y + 0 * MRYD, MRXS, MRYS, 0, 1.01, 0, \ "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, \ {"", 2, x + 0 * MRXD, y + 1 * MRYD, MRXS, MRYS, 0, 4, 0, \ "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, \ {"", 2, x + 1 * MRXD, y + 0 * MRYD, MRXS, MRYS, 0, 7, 0, \ "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, \ {"", 2, x + 1 * MRXD, y + 1 * MRYD, MRXS, MRYS, 0, 2, 0, \ "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, \ {"", 2, x + 2 * MRXD, y + 0 * MRYD, MRXS, MRYS, 0, 5, 0, \ "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, \ {"", 2, x + 2 * MRXD, y + 1 * MRYD, MRXS, MRYS, 0, 8, 0, \ "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, \ {"", 2, x + 3 * MRXD, y + 0 * MRYD, MRXS, MRYS, 0, 3, 0, \ "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, \ {"", 2, x + 3 * MRXD, y + 1 * MRYD, MRXS, MRYS, 0, 6, 0, \ "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, \ {"", 2, 0 + 2 * MRXD, 0 + 2 * MRYD, MRXS, MRYS, 0, 9, 0, \ "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", \ BRIGHTON_WITHDRAWN} #define S1 200 #define D1 65 #define oW1 120 #define oL1 120 #define oC1 39 #define oC2 180 #define oC3 (oC2 + D1) #define oC4 (oC3 + D1) #define oC5 (oC4 + D1) #define oC6 (oC5 + D1) #define oC62 (oC6 + D1 - 5) #define oC7 600 #define oC8 (oC7 + D1) #define oC9 (oC8 + D1) #define oC10 (oC9 + D1) #define oC15 900 #define oC16 950 #define oR1 350 #define oR2 550 #define oR3 750 #define oR4 400 #define oR6 600 static brightonLocations options[MOD_COUNT] = { /* Env ADSRG 0 */ {"", 0, oC2, oR1, oW1, oL1, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, oC3, oR1, oW1, oL1, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, oC4, oR1, oW1, oL1, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, oC5, oR1, oW1, oL1, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, oC6, oR1, oW1, oL1, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, /* Second env 5 */ {"", 0, oC2, oR2, oW1, oL1, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, oC3, oR2, oW1, oL1, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, oC4, oR2, oW1, oL1, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, oC5, oR2, oW1, oL1, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, oC6, oR2, oW1, oL1, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, /* Third Env 10 */ {"", 0, oC2, oR3, oW1, oL1, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, oC3, oR3, oW1, oL1, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, oC4, oR3, oW1, oL1, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, oC5, oR3, oW1, oL1, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, oC6, oR3, oW1, oL1, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, /* Osc Depth 15 */ {"", 0, oC7, oR1, oW1, oL1, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, oC8, oR1, oW1, oL1, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_NOTCH}, {"", 0, oC9, oR1, oW1, oL1, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, oC10, oR1, oW1, oL1, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, /* Osc Scatter */ {"", 0, oC7, oR2, oW1, oL1, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, oC8, oR2, oW1, oL1, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, oC9, oR2, oW1, oL1, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, oC10, oR2, oW1, oL1, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, /* Osc params, Fine tune, glide 23/24/25 */ {"", 0, oC7, oR3, oW1, oL1, 0, 9, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, oC8, oR3, oW1, oL1, 0, 8, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, oC9, oR3, oW1, oL1, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, MODROUTING(oC62, oR1 + 12), /* 26 - Env */ MODROUTING(oC62, oR2 + 12), /* 35 - Env */ MODROUTING(oC62, oR3 + 12), /* 44 - Env */ SELECTBUS(oC10 - 2, oR3), /* 53 */ /* LFO - 62 */ {"", 0, oC1, oR1, oW1, oL1, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, MODROUTING(85, oR1 + 12), /* Noise 72 */ {"", 0, oC1, oR2, oW1, oL1, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, MODROUTING(85, oR2 + 12), /* Dummies for later implementation */ {"", 0, 0, 0, 25, 25, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, 25, 25, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, 25, 25, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, 25, 25, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, 25, 25, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, 25, 25, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, 25, 25, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, 25, 25, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, 25, 25, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, 25, 25, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, 25, 25, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, 25, 25, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, 25, 25, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, 25, 25, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, 25, 25, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, 25, 25, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, 25, 25, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, 25, 25, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, 25, 25, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, 25, 25, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, 25, 25, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, 25, 25, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, 25, 25, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, 25, 25, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, 25, 25, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, 25, 25, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, 25, 25, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, 25, 25, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, 25, 25, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, 25, 25, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, 25, 25, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, 25, 25, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, 25, 25, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, 25, 25, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, 25, 25, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, 25, 25, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, 25, 25, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, 25, 25, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, 25, 25, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, 25, 25, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, 25, 25, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, 25, 25, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, 25, 25, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, 25, 25, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, 25, 25, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, 25, 25, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, 25, 25, 0, 1, 0, "bitmaps/knobs/grotary.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN}, /* Memories */ SELECTBUS(900, oR1), SELECTBUS(900, oR2), /* Midi up/down, save */ {"", 2, 900, oR3, MRXS, MRYS, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 900 + MRXD, oR3, MRXS, MRYS, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 900 + 2 * MRXD, oR3, MRXS, MRYS, 0, 1, 0, "bitmaps/buttons/pressoffo.xpm", "bitmaps/buttons/pressono.xpm", BRIGHTON_CHECKBUTTON}, }; #define mR1 200 #define mR2 450 #define mR3 700 #define mC1 100 #define mC2 283 #define mC3 466 #define mC4 649 #define mC5 835 #define mC11 100 #define mC12 255 #define mC13 410 #define mC14 565 #define mC15 720 #define mC16 874 #define S3 100 #define S4 80 #define S5 120 #define S6 150 /* * Should try and make this one as generic as possible, and try to use it as * a general memory routine. has Midi u/d, mem u/d, load/save and a display. */ static int memCallback(brightonWindow* win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); if (synth->flags & SUPPRESS) return(0); /* * The first ten buttons are exclusive highlighting, we use the first mem * pointer to handle this. */ if (synth->dispatch[MEM_START].other2) { synth->dispatch[MEM_START].other2 = 0; return(0); } if (synth->dispatch[MEM_START + 1].other2) { synth->dispatch[MEM_START + 1].other2 = 0; return(0); } printf("memCallback(%i, %i, %f) %i, %s\n", panel, index, value, synth->mem.active, synth->resources->name); if (index == (DEVICE_COUNT - 1)) { if (brightonDoubleClick(dc1)) { saveMemory(synth, "granular", 0, synth->bank * 10 + synth->location, 0); } return(0); } /* First bank selections */ if (index < (MEM_START + 9)) { brightonEvent event; event.command = BRIGHTON_PARAMCHANGE; event.type = BRIGHTON_FLOAT; event.value = 0; /* * This is a numeric. We need to force exclusion. */ if (synth->dispatch[MEM_START].other1 != -1) { synth->dispatch[MEM_START].other2 = 1; if (synth->dispatch[MEM_START].other1 != index) event.value = 0; else event.value = 1; brightonParamChange(synth->win, panel, synth->dispatch[MEM_START].other1, &event); } synth->bank = index - MEM_START; if (brightonDoubleClick(dc2)) { printf("bank %i, mem %i\n", synth->bank, synth->location); loadMemory(synth, "granular", 0, synth->bank * 10 + synth->location, synth->mem.active, 0, BRISTOL_FORCE); } synth->dispatch[MEM_START].other1 = index; } else if (index < (MEM_START + 18)) { brightonEvent event; event.command = BRIGHTON_PARAMCHANGE; event.type = BRIGHTON_FLOAT; event.value = 0; /* * This is a numeric. We need to force exclusion. */ if (synth->dispatch[MEM_START + 1].other1 != -1) { synth->dispatch[MEM_START + 1].other2 = 1; if (synth->dispatch[MEM_START + 1].other1 != index) event.value = 0; else event.value = 1; brightonParamChange(synth->win, panel, synth->dispatch[MEM_START + 1].other1, &event); } synth->location = index - MEM_START - 9; if (brightonDoubleClick(dc2)) { printf("bank %i, mem %i\n", synth->bank, synth->location); loadMemory(synth, "granular", 0, synth->bank * 10 + synth->location, synth->mem.active, 0, BRISTOL_FORCE); } synth->dispatch[MEM_START + 1].other1 = index; } else { int newchan; /* * This is a control button. */ switch(index) { case MOD_COUNT - 3: /* * Midi Down */ if ((newchan = synth->midichannel - 1) < 0) { synth->midichannel = 0; return(0); } if (global.libtest) { printf("midi chan %i\n", newchan); synth->midichannel = newchan; return(0); } bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_MIDICHANNEL|newchan); synth->midichannel = newchan; break; case MOD_COUNT - 2: /* * Midi Up */ if ((newchan = synth->midichannel + 1) > 15) { synth->midichannel = 15; return(0); } if (global.libtest) { printf("midi chan %i\n", newchan); synth->midichannel = newchan; return(0); } bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_MIDICHANNEL|newchan); synth->midichannel = newchan; break; } } return(0); } /* * This is a set of globals for the main window rendering. Again taken from * include/brighton.h */ brightonApp granularApp = { "granular", 0, /* no blueprint on wood background. */ "bitmaps/textures/granular.xpm", BRIGHTON_STRETCH, granularInit, granularConfigure, /* 3 callbacks */ midiCallback, destroySynth, {16, 0, 2, 2, 5, 520, 0, 0}, 740, 400, 0, 0, 4, /* panel count */ { { "Mods", 0, 0, /* flags */ 0, 0, 0, granularCallback, //30, 50, 940, 365, 5, 5, 990, 560, MOD_COUNT, options }, { "Keyboard", 0, "bitmaps/newkeys/kbg.xpm", /* flags */ BRIGHTON_STRETCH, 0, 0, keyCallback, 100, 710, 900, 250, KEY_COUNT, keysprofile }, { "Mods", "bitmaps/blueprints/mods.xpm", 0, /* flags */ BRIGHTON_STRETCH, 0, 0, modCallback, 0, 710, 100, 250, 2, mods }, } }; static int midiCallback(brightonWindow *win, int controller, int value, float n) { guiSynth *synth = findSynth(global.synths, win); printf("midi callback: %x, %i\n", controller, value); switch(controller) { case MIDI_PROGRAM: printf("midi program: %x, %i\n", controller, value); synth->location = value; loadMemory(synth, synth->resources->name, 0, synth->bank + synth->location, synth->mem.active, 0, 0); break; case MIDI_BANK_SELECT: printf("midi banksel: %x, %i\n", controller, value); synth->bank = value; break; } return(0); } static int granularMods(guiSynth *synth, int fd, int chan, int c, int o, int v) { unsigned int i, flags = 0; for (i = 0; i < 9; i++) { if (synth->mem.param[o + i] != 0) flags |= (0x01 << i); } if (c == 15) bristolMidiSendMsg(fd, chan, 0, 10, flags); else bristolMidiSendMsg(fd, chan, 126, c, flags); return(0); } /* static int granularOscWaveform(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; if (synth->dispatch[53].other2) { synth->dispatch[53].other2 = 0; return(0); } if (synth->dispatch[53].other1 != -1) { event.command = BRIGHTON_PARAMCHANGE; event.type = BRIGHTON_FLOAT; synth->dispatch[53].other2 = o; if (synth->dispatch[53].other1 != o) event.value = 0; else event.value = 1; brightonParamChange(synth->win, 0, synth->dispatch[53].other1, &event); } if (v != 0) bristolMidiSendMsg(fd, chan, 0, 10, v - 1); synth->dispatch[53].other1 = o; return(0); } */ static int granularMidiSendMsg(void *synth, int fd, int chan, int c, int o, int v) { /* printf("%i, %i, %i\n", c, o, v); */ bristolMidiSendMsg(fd, chan, c, o, v); return(0); } /* * For the sake of ease of use, links have been placed here to be called * by any of the devices created. They would be better in some other file, * perhaps with this as a dispatch. * * Param refers to the device index in the locations table given below. */ static int granularCallback(brightonWindow *win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); int sendvalue; if (synth == 0) return(0); if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0)) return(0); if (granularApp.resources[panel].devlocn[index].to == 1) sendvalue = value * C_RANGE_MIN_1; else sendvalue = value; if (index >= MEM_START) return(memCallback(win, panel, index, value)); synth->mem.param[index] = value; if ((!global.libtest) || (index >= ACTIVE_DEVS)) synth->dispatch[index].routine(synth, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #ifdef DEBUG else printf("dispatch[%p,%i](%i, %i, %i, %i, %i)\n", synth, index, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #endif return(0); } /* * Any location initialisation required to run the callbacks. For bristol, this * will connect to the engine, and give it some base parameters. * May need to generate some application specific menus. * Will also then make specific requests to some of the devices to alter their * rendering. */ static int granularInit(brightonWindow* win) { guiSynth *synth = findSynth(global.synths, win); dispatcher *dispatch; int i; if (synth == 0) { synth = findSynth(global.synths, 0); if (synth == 0) { printf("cannot init\n"); return(0); } } synth->win = win; printf("Initialise the granular link to bristol: %p\n", synth->win); synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float)); synth->mem.count = DEVICE_COUNT; synth->mem.active = ACTIVE_DEVS; synth->dispatch = (dispatcher *) brightonmalloc(DEVICE_COUNT * sizeof(dispatcher)); dispatch = synth->dispatch; /* * We really want to have three connection mechanisms. These should be * 1. Unix named sockets. * 2. UDP sockets. * 3. MIDI pipe. */ if (!global.libtest) if ((synth->sid = initConnection(&global, synth)) < 0) return(-1); for (i = 0; i < DEVICE_COUNT; i++) { synth->dispatch[i].controller = 88; synth->dispatch[i].routine = granularMidiSendMsg; } synth->dispatch[MOD_START + 0].controller = 1; /* Env */ synth->dispatch[MOD_START + 0].operator = 0; synth->dispatch[MOD_START + 1].controller = 1; /* Env */ synth->dispatch[MOD_START + 1].operator = 1; synth->dispatch[MOD_START + 2].controller = 1; /* Env */ synth->dispatch[MOD_START + 2].operator = 2; synth->dispatch[MOD_START + 3].controller = 1; /* Env */ synth->dispatch[MOD_START + 3].operator = 3; synth->dispatch[MOD_START + 4].controller = 1; /* Env */ synth->dispatch[MOD_START + 4].operator = 4; synth->dispatch[MOD_START + 5].controller = 2; /* Env2 */ synth->dispatch[MOD_START + 5].operator = 0; synth->dispatch[MOD_START + 6].controller = 2; /* Env2 */ synth->dispatch[MOD_START + 6].operator = 1; synth->dispatch[MOD_START + 7].controller = 2; /* Env2 */ synth->dispatch[MOD_START + 7].operator = 2; synth->dispatch[MOD_START + 8].controller = 2; /* Env2 */ synth->dispatch[MOD_START + 8].operator = 3; synth->dispatch[MOD_START + 9].controller = 2; /* Env2 */ synth->dispatch[MOD_START + 9].operator = 4; synth->dispatch[MOD_START + 10].controller = 3; /* Env3 */ synth->dispatch[MOD_START + 10].operator = 0; synth->dispatch[MOD_START + 11].controller = 3; /* Env3 */ synth->dispatch[MOD_START + 11].operator = 1; synth->dispatch[MOD_START + 12].controller = 3; /* Env3 */ synth->dispatch[MOD_START + 12].operator = 2; synth->dispatch[MOD_START + 13].controller = 3; /* Env3 */ synth->dispatch[MOD_START + 13].operator = 3; synth->dispatch[MOD_START + 14].controller = 3; /* Env3 */ synth->dispatch[MOD_START + 14].operator = 4; synth->dispatch[MOD_START + 15].controller = 0; /* Gain */ synth->dispatch[MOD_START + 15].operator = 0; synth->dispatch[MOD_START + 16].controller = 0; /* Frequency */ synth->dispatch[MOD_START + 16].operator = 2; synth->dispatch[MOD_START + 17].controller = 0; /* Delay */ synth->dispatch[MOD_START + 17].operator = 4; synth->dispatch[MOD_START + 18].controller = 0; /* Duration */ synth->dispatch[MOD_START + 18].operator = 6; synth->dispatch[MOD_START + 19].controller = 0; /* Gain Scatter */ synth->dispatch[MOD_START + 19].operator = 1; synth->dispatch[MOD_START + 20].controller = 0; /* Frequency scatter */ synth->dispatch[MOD_START + 20].operator = 3; synth->dispatch[MOD_START + 21].controller = 0; /* Delay scatter */ synth->dispatch[MOD_START + 21].operator = 5; synth->dispatch[MOD_START + 22].controller = 0; /* Duration scatter */ synth->dispatch[MOD_START + 22].operator = 7; /* Transpose and graincount */ synth->dispatch[MOD_START + 23].controller = 0; /* Osc */ synth->dispatch[MOD_START + 23].operator = 8; synth->dispatch[MOD_START + 24].controller = 0; /* Osc */ synth->dispatch[MOD_START + 24].operator = 9; /* Glide */ synth->dispatch[MOD_START + 25].controller = 126; /* Osc */ synth->dispatch[MOD_START + 25].operator = 0; /* Env routing */ for (i = 0; i < 9; i++) { synth->dispatch[MOD_START + 26 + i].controller = 10; /* Mod */ synth->dispatch[MOD_START + 26 + i].operator = 26; synth->dispatch[MOD_START + 26 + i].routine = (synthRoutine) granularMods; } for (i = 0; i < 9; i++) { synth->dispatch[MOD_START + 35 + i].controller = 11; /* Mod */ synth->dispatch[MOD_START + 35 + i].operator = 35; synth->dispatch[MOD_START + 35 + i].routine = (synthRoutine) granularMods; } for (i = 0; i < 9; i++) { synth->dispatch[MOD_START + 44 + i].controller = 12; /* Mod */ synth->dispatch[MOD_START + 44 + i].operator = 44; synth->dispatch[MOD_START + 44 + i].routine = (synthRoutine) granularMods; } /* Waveform synth->dispatch[MOD_START + 53].controller = synth->dispatch[MOD_START + 54].controller = synth->dispatch[MOD_START + 55].controller = synth->dispatch[MOD_START + 56].controller = synth->dispatch[MOD_START + 57].controller = synth->dispatch[MOD_START + 58].controller = synth->dispatch[MOD_START + 59].controller = synth->dispatch[MOD_START + 60].controller = synth->dispatch[MOD_START + 61].controller = 0; synth->dispatch[MOD_START + 53].operator = 53; synth->dispatch[MOD_START + 54].operator = 54; synth->dispatch[MOD_START + 55].operator = 55; synth->dispatch[MOD_START + 56].operator = 56; synth->dispatch[MOD_START + 57].operator = 57; synth->dispatch[MOD_START + 58].operator = 58; synth->dispatch[MOD_START + 59].operator = 59; synth->dispatch[MOD_START + 60].operator = 60; synth->dispatch[MOD_START + 61].operator = 61; synth->dispatch[MOD_START + 53].routine = synth->dispatch[MOD_START + 54].routine = synth->dispatch[MOD_START + 55].routine = synth->dispatch[MOD_START + 56].routine = synth->dispatch[MOD_START + 57].routine = synth->dispatch[MOD_START + 58].routine = synth->dispatch[MOD_START + 59].routine = synth->dispatch[MOD_START + 60].routine = synth->dispatch[MOD_START + 61].routine = (synthRoutine) granularOscWaveform; */ for (i = 0; i < 9; i++) { synth->dispatch[MOD_START + 53 + i].controller = 15; /* Mod */ synth->dispatch[MOD_START + 53 + i].operator = 53; synth->dispatch[MOD_START + 53 + i].routine = (synthRoutine) granularMods; } synth->dispatch[MOD_START + 62].controller = 4; /* LFO */ synth->dispatch[MOD_START + 62].operator = 0; for (i = 0; i < 9; i++) { synth->dispatch[MOD_START + 63 + i].controller = 13; /* LFO */ synth->dispatch[MOD_START + 63 + i].operator = 63; synth->dispatch[MOD_START + 63 + i].routine = (synthRoutine) granularMods; } synth->dispatch[MOD_START + 72].controller = 5; /* Noise */ synth->dispatch[MOD_START + 72].operator = 0; for (i = 0; i < 9; i++) { synth->dispatch[MOD_START + 73 + i].controller = 14; /* NOISE */ synth->dispatch[MOD_START + 73 + i].operator = 73; synth->dispatch[MOD_START + 73 + i].routine = (synthRoutine) granularMods; } /* * These will be replaced by some opts controllers. We need to tie the * envelope parameters for decay, sustain. We need to fix a few parameters * of the oscillators too - transpose, tune and gain. bristolMidiSendMsg(global.controlfd, synth->sid, 3, 1, 10); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 2, 16382); */ /* Velocity tracking to zero on second envelope */ bristolMidiSendMsg(global.controlfd, synth->sid, 2, 5, 1); /* Enable key tracking and multi LFO with sync to keyOn */ bristolMidiSendMsg(global.controlfd, synth->sid, 126, 3, 1); bristolMidiSendMsg(global.controlfd, synth->sid, 126, 4, 1); bristolMidiSendMsg(global.controlfd, synth->sid, 4, 1, 1); return(0); } /* * This will be called to make any routine specific parameters available. */ static int granularConfigure(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); brightonEvent event; if (synth == 0) { printf("problems going operational\n"); return(-1); } if (synth->flags & OPERATIONAL) return(0); printf("going operational\n"); synth->flags |= OPERATIONAL; synth->keypanel = KEY_PANEL; synth->keypanel2 = -1; synth->transpose = 36; loadMemory(synth, "granular", 0, synth->location, synth->mem.active, 0, 0); /* * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only * occurs on first paint, so we suppress the first paint, and then request * an expose here. */ brightonPut(win, "bitmaps/blueprints/granular.xpm", 0, 0, win->width, win->height); event.type = BRIGHTON_EXPOSE; event.intvalue = 1; brightonParamChange(synth->win, KEY_PANEL, -1, &event); configureGlobals(synth); event.command = BRIGHTON_PARAMCHANGE; event.type = BRIGHTON_FLOAT; event.value = 1; brightonParamChange(synth->win, 0, MEM_START, &event); brightonParamChange(synth->win, 0, MEM_START + 9, &event); dc1 = brightonGetDCTimer(win->dcTimeout); dc2 = brightonGetDCTimer(win->dcTimeout); return(0); } bristol-0.60.11/brighton/brightonProphet10.c0000644000175000017500000017132311746476475015611 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* * Master controls need to be implemented - vol/balance/tune. Done * Layer balance should be pan. Done * Master balance should be layer. Done * * Seq/Arp/Chord CHORDED * Mode selections Done. * * Confirm all the keyboard modes esp WRT layers. */ #include #include "brighton.h" #include "brightonMini.h" #include "brightoninternals.h" static int initmem; static int exclude = 0; extern void *brightonmalloc(); static int pro10Init(); static int pro10Configure(); static int pro10Callback(brightonWindow * , int, int, float); static int lmCallback(brightonWindow * , int, int, float); static int ummodCallback(brightonWindow * , int, int, float); static int lmmodCallback(brightonWindow * , int, int, float); static int midiCallback(brightonWindow *, int, int, float); #define MODE_DUAL 0 #define MODE_LAYER 1 #define MODE_POLY 2 #define MODE_ALT 3 /* One voice then the other - not supported */ static int keymode = MODE_DUAL; static int seqLearn = 0, chordLearn = 0; extern guimain global; /* * These have to be integrated into the synth private structures, since we may * have multiple invocations of any given synth. */ static guimain manual; #include "brightonKeys.h" #define DEVICE_COUNT 100 #define ACTIVE_DEVS 48 #define DISPLAY_DEV (DEVICE_COUNT - 2) #define DISPLAY_DEV_2 (DEVICE_COUNT - 1) #define RADIOSET_1 70 #define RADIOSET_2 81 #define RADIOSET_3 51 #define RADIOSET_4 (DEVICE_COUNT + 2) #define RADIOSET_5 (DEVICE_COUNT + 5) #define PANEL_SWITCH 95 #define KEY_PANEL 1 #define KEY_PANEL2 3 #define R1 75 #define RB1 95 #define R2 305 #define RB2 330 #define R3 535 #define RB3 560 #define RB4 785 #define RB5 880 #define C1 26 #define C2 76 #define CB1 66 #define CB2 95 #define C3 125 #define C4 155 #define C5 184 #define C6 235 #define CB6 275 #define CB7 305 #define C7 340 #define CB8 390 #define C9 280 #define CB9 330 #define CB10 360 #define CB11 390 #define C10 430 #define CB12 480 #define CB13 510 #define C11 442 #define C12 490 #define C13 538 #define C14 595 #define C15 642 #define C16 688 #define C17 735 #define C18 800 #define C19 850 #define C20 900 #define C21 950 #define C22 265 #define C23 470 #define S1 95 #define B1 14 #define B2 80 #define B3 65 /* * This structure is for device definition. The structure is defined in * include/brighton.h, further definitions in brighton/brightonDevtable.h and * include/brightoninternals.h * * typedef int (*brightonCallback)(int, float); * typedef struct BrightonLocations { * int device; 0=rotary, 1=scale, etc. * float relx, rely; relative position with regards to 1000 by 1000 window * float relw, relh; relative height. * int from, to; * brightonCallback callback; specific to this dev * char *image; bitmap. If zero take a device default. * int flags; * } brightonLocations; * * This example is for a pro10Bristol type synth interface. */ static brightonLocations locations[DEVICE_COUNT] = { /* poly mod */ {"PolyMod-Filt", 0, C1, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"PolyMod-OscB", 0, C2, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"PolyMod-FreqA", 2, C3, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"PolyMod-PW-S", 2, C4, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"PolyMod-Filt", 2, C5, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* lfo */ {"LFO-Freq", 0, C2, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"LFO-Ramp", 2, C3, RB2, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"LFO-Tri", 2, C4, RB2, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"LFO-Square", 2, C5, RB2, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* wheel mod */ {"Wheel-Mix", 0, C1, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"Wheel-FreqA", 2, CB1, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"Wheel-FreqB", 2, CB2, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"Wheel-PW-A", 2, C3, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"Wheel-PW-B", 2, C4, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"Wheel-Filt", 2, C5, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* osc a */ {"OscA-Transpose", 0, C6, R1, S1, S1, 0, 5, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"OscA-Ramp", 2, CB6, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"OscA-Pule", 2, CB7, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"OscA-PW", 0, C7, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"OscA-Sync", 2, CB8, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* osc b */ {"OscB-Transpose", 0, C6, R2, S1, S1, 0, 5, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"OscB-Tune", 0, C9, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, BRIGHTON_NOTCH}, {"OscB-Ramp", 2, CB9, RB2, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"OscB-Tri", 2, CB10, RB2, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"OscB-Pulse", 2, CB11, RB2, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"OscB-PW", 0, C10, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"OscB-LFO", 2, CB12, RB2, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"OscB-KBD", 2, CB13, RB2, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* glide, etc */ {"Glide", 0, C6, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"Unison", 2, CB7, R3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* mixer */ {"Mix-OscA", 0, C11, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"Mix-OscB", 0, C12, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"Mix-Noise", 0, C13, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, /* filter + env */ {"VCF-Cutoff", 0, C14, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"VCF-Resonance", 0, C15, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"VCF-Envelope", 0, C16, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"VCF-KBD", 2, C17 + 6, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"VCF-Attack", 0, C14, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"VCF-Decay", 0, C15, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"VCF-Sustain", 0, C16, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"VCF-Release", 0, C17, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, /* main env */ {"VCA-Attack", 0, C14, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"VCA-Decay", 0, C15, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"VCA-Sustain", 0, C16, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"VCA-Release", 0, C17, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, /* tune + vol + pan */ {"LayerTuning", 0, C20, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, BRIGHTON_NOTCH}, {"LayerVolume", 0, C18, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"LayerPanning", 0, C19, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, BRIGHTON_NOTCH}, {"Release", 2, C19 + 10, RB4, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, /* A440 */ {"A-440", 2, C21 + 5, R2, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"Retune", 2, C21 + 7, RB4, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, /* Dual/Layer/Poly */ {"Mode-Dual", 2, CB12 - 20, R3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"Mode-Layer", 2, CB12 + 15, R3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"Mode-Split", 2, CB12 + 50, R3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* Master Globals */ {"MasterVolume", 0, C17, RB4, S1, S1, 0, 1, 0, "bitmaps/knobs/knob3.xpm", 0, 0}, {"MasterPan", 0, C18, RB4, S1, S1, 0, 1, 0, "bitmaps/knobs/knob3.xpm", 0, BRIGHTON_NOTCH}, {"MasterTune", 0, C20, RB4, S1, S1, 0, 1, 0, "bitmaps/knobs/knob3.xpm", 0, BRIGHTON_NOTCH}, /* Chording */ {"", 2, C19 + 5, R3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, C20 + 5, R3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* dummies */ {"", 0, C17, R3, S1, S1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 0, C17, R3, S1, S1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 0, C17, R3, S1, S1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 0, C17, R3, S1, S1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 0, C17, R3, S1, S1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 0, C17, R3, S1, S1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 0, C17, R3, S1, S1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 0, C17, R3, S1, S1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 0, C17, R3, S1, S1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 0, C17, R3, S1, S1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 0, C17, R3, S1, S1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 0, C17, R3, S1, S1, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, /* memories */ {"", 2, C23 + 10, RB4, B1, B3, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C23 + 31, RB4, B1, B3, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C23 + 52, RB4, B1, B3, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C23 + 73, RB4, B1, B3, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C23 + 94, RB4, B1, B3, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C23 + 115, RB4, B1, B3, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C23 + 136, RB4, B1, B3, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C23 + 157, RB4, B1, B3, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C22, RB4, B1, B3, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, C22 + 30, RB4, B1, B3, 0, 1, 0, "bitmaps/buttons/pressoffo.xpm", "bitmaps/buttons/pressono.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, C22 + 60, RB4, B1, B3, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, C23 + 10, RB5, B1, B3, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C23 + 31, RB5, B1, B3, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C23 + 52, RB5, B1, B3, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C23 + 73, RB5, B1, B3, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C23 + 94, RB5, B1, B3, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C23 + 115, RB5, B1, B3, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C23 + 136, RB5, B1, B3, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C23 + 157, RB5, B1, B3, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C22, RB5, B1, B3, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, C22 + 30, RB5, B1, B3, 0, 1, 0, "bitmaps/buttons/pressoffo.xpm", "bitmaps/buttons/pressono.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, C22 + 60, RB5, B1, B3, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, /* Midi, perhaps eventually file import/export buttons */ {"", 2, C20 + 10, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, C21 + 10, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, /* Synth select */ {"Upper", 2, CB6 - 62, RB4, B1, B3, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, {"Lower", 2, CB6 - 62, RB5, B1, B3, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, /* LOGO */ {"", 4, 30, RB4, 143, 150, 0, 1, 0, "bitmaps/images/pro10.xpm", 0, 0}, /* Display */ {"", 3, C22 + 80, RB4, 130, B3, 0, 1, 0, 0, "bitmaps/images/alphadisplay3.xpm", 0}, {"", 3, C22 + 80, RB5, 130, B3, 0, 1, 0, 0, "bitmaps/images/alphadisplay3.xpm", 0} }; /* * This is for the lower mod panel. It will control the MIDI operational mode * for poly/split/layer stuff and mod routing. It is not totally according to * the original that used the panel for argeggio. This may also control some * of the mod routing for each layer. It will not be saved in the memories. */ #define P10_MOD_COUNT 15 static brightonLocations p10Mods[P10_MOD_COUNT] = { /* lmod umod lpitch upitch */ {"", 2, 60, 122, 90, 140, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, {"", 2, 260, 122, 90, 140, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, {"", 2, 460, 122, 90, 140, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, {"", 2, 660, 122, 90, 140, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, {"", 2, 860, 122, 90, 140, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, {"", 2, 60, 420, 90, 140, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, {"", 2, 60, 625, 90, 140, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, {"", 2, 60, 830, 90, 140, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, {"", 2, 660, 420, 90, 140, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, {"", 2, 860, 420, 90, 140, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, {"", 2, 660, 625, 90, 140, 0, 1, 0, "bitmaps/buttons/pressoffo.xpm", "bitmaps/buttons/pressono.xpm", 0}, {"", 2, 860, 625, 90, 140, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, {"", 2, 660, 830, 90, 140, 0, 1, 0, "bitmaps/buttons/pressoffo.xpm", "bitmaps/buttons/pressono.xpm", 0}, {"", 2, 860, 830, 90, 140, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, /* Rate */ {"", 0, 300, 520, 220, 220, 0, 1, 0, "bitmaps/knobs/knob3.xpm", 0, 0}, }; #define PMOD_COUNT 6 brightonLocations pmods[PMOD_COUNT] = { {"", 1, 150, 170, 70, 620, 0, 1, 0, 0, 0,BRIGHTON_CENTER|BRIGHTON_NOSHADOW}, {"", 1, 350, 170, 70, 620, 0, 1, 0, 0, 0, BRIGHTON_NOSHADOW}, {"", 2, 580, 320, 90, 135, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, {"", 2, 760, 320, 90, 135, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, {"", 2, 580, 560, 90, 135, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, {"", 2, 760, 560, 90, 135, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, }; #define LM_MOD_INDEX DEVICE_COUNT #define UM_MOD_INDEX (LM_MOD_INDEX + P10_MOD_COUNT) static int pro10destroy(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); /*printf("pro10destroy(%i): %i\n", win, synth->midichannel); */ /* * Since we registered two synths, we now need to remove the upper * manual. */ bristolMidiSendMsg(manual.controlfd, synth->sid2, 127, 0, BRISTOL_EXIT_ALGO); bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_EXIT_ALGO); return(0); } /* * This is a set of globals for the main window rendering. Again taken from * include/brighton.h */ brightonApp pro10App = { "prophet10", 0, /* no blueprint on wood background. */ "bitmaps/textures/metal5.xpm", 0, /* BRIGHTON_STRETCH, //flags */ pro10Init, pro10Configure, /* 3 callbacks, unused? */ midiCallback, pro10destroy, {10, 100, 2, 2, 5, 520, 0, 0}, 745, 410, 0, 0, 7, { { "Pro10", "bitmaps/blueprints/prophet10.xpm", "bitmaps/textures/metal5.xpm", 0, /*BRIGHTON_STRETCH, // flags */ 0, 0, pro10Callback, 15, 5, 970, 500, DEVICE_COUNT, locations }, { "Keyboard", 0, "bitmaps/newkeys/kbg.xpm", /* flags */ 0x020|BRIGHTON_STRETCH, 0, 0, lmCallback, 148, 505, 860, 240, KEY_COUNT, keysprofile }, { "Mods", "bitmaps/blueprints/prophet10mod.xpm", "bitmaps/textures/metal5.xpm", /* flags */ 0, 0, 0, ummodCallback, 15, 505, 135, 240, PMOD_COUNT, pmods }, { "Keyboard", 0, "bitmaps/newkeys/kbg.xpm", /* flags */ 0x020|BRIGHTON_STRETCH, 0, 0, lmCallback, 153, 745, 850, 240, KEY_COUNT, keysprofile }, { "Mods", "bitmaps/blueprints/prophetmod2.xpm", "bitmaps/textures/metal5.xpm", /* flags */ 0, 0, 0, lmmodCallback, 18, 745, 136, 240, P10_MOD_COUNT, p10Mods }, { "Pro10", 0, "bitmaps/textures/wood2.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 0, 0, 15, 1000, 0, 0 }, { "Pro10", 0, "bitmaps/textures/wood2.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /*flags */ 0, 0, 0, 985, 0, 15, 1000, 0, 0 } } }; static int midiCallback(brightonWindow *win, int controller, int value, float n) { guiSynth *synth = findSynth(global.synths, win); printf("midi callback: %i, %i\n", controller, value); switch(controller) { case MIDI_PROGRAM: printf("midi program: %x, %i\n", controller, value); synth->location = value; loadMemory(synth, "prophet", 0, synth->bank + synth->location, synth->mem.active, 0, 0); break; case MIDI_BANK_SELECT: printf("midi banksel: %x, %i\n", controller, value); synth->bank = value; break; } return(0); } /* * Default dispatcher */ static int pro10MidiSendMsg(void *synth, int fd, int chan, int c, int o, int v) { bristolMidiSendMsg(fd, chan, c, o, v); return(0); } static void pro10DLP(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; event.type = BRIGHTON_FLOAT; if (synth->dispatch[RADIOSET_3].other2) { synth->dispatch[RADIOSET_3].other2 = 0; return; } if (synth->dispatch[RADIOSET_3].other1 != -1) { synth->dispatch[RADIOSET_3].other2 = 1; if (synth->dispatch[RADIOSET_3].other1 != c) event.value = 0; else event.value = 1; brightonParamChange(synth->win, synth->panel, synth->dispatch[RADIOSET_3].other1 + RADIOSET_3, &event); } synth->dispatch[RADIOSET_3].other1 = c; /* printf("pro10DLP(%i, %i)\n", c, v); */ /* We may have to consider Seq/Arpeg/Chord issues here */ switch (c) { case 0: /* * Dual keyboard: * * Separate the midi channels * Half the key count for primary layer * Max out the split for second layer */ keymode = MODE_DUAL; /* Separate the midi channels */ if (synth->midichannel == 15) { synth->midichannel--; bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_MIDICHANNEL|synth->midichannel); bristolMidiSendMsg(global.controlfd, synth->sid2, 127, 0, (BRISTOL_MIDICHANNEL|synth->midichannel) + 1); } else bristolMidiSendMsg(global.controlfd, synth->sid2, 127, 0, (BRISTOL_MIDICHANNEL|synth->midichannel) + 1); ((guiSynth *) synth->second)->midichannel = synth->midichannel + 1; /* Halve the voicecount */ bristolMidiSendMsg(fd, chan, 126, 35, 1); /* Configure a whole keyboard */ bristolMidiSendMsg(global.controlfd, synth->sid2, 127, 0, BRISTOL_LOWKEY|0); break; case 1: /* * Layered keyboards * * Join up the midi channels * Half the key count for primary layer * Max out the split for second layer */ keymode = MODE_LAYER; /* Join the midi channel */ bristolMidiSendMsg(global.controlfd, synth->sid2, 127, 0, (BRISTOL_MIDICHANNEL|synth->midichannel)); /* Halve the voicecount */ bristolMidiSendMsg(fd, chan, 126, 35, 1); /* Configure a whole keyboard */ bristolMidiSendMsg(global.controlfd, synth->sid2, 127, 0, BRISTOL_LOWKEY|0); ((guiSynth *) synth->second)->midichannel = synth->midichannel; break; case 2: /* * 10 Note Poly keyboards * * Join up the midi channels * Double the key count for primary layer * Zero out the split for second layer */ keymode = MODE_POLY; /* Join the midi channel although this is superfluous */ bristolMidiSendMsg(global.controlfd, synth->sid2, 127, 0, (BRISTOL_MIDICHANNEL|synth->midichannel)); /* Whole the voicecount */ bristolMidiSendMsg(fd, chan, 126, 35, 0); /* Configure no keyboard */ bristolMidiSendMsg(global.controlfd, synth->sid2, 127, 0, BRISTOL_LOWKEY|127); ((guiSynth *) synth->second)->midichannel = synth->midichannel; break; }; } static void multiA440(guiSynth *synth, int fd, int chan, int c, int o, int v) { if (v != 0) { bristolMidiSendMsg(fd, synth->sid, 126, 3, 1); bristolMidiSendMsg(fd, synth->sid2, 126, 3, 1); } else { bristolMidiSendMsg(fd, synth->sid, 126, 3, 0); bristolMidiSendMsg(fd, synth->sid2, 126, 3, 0); } } static void pro10Tune(guiSynth *synth, int fd, int chan, int c, int o, int v) { float t1, t2, tg; int value; /* * We have three different tuning parameters, these are one per layer plus * the global tuning. Here we are going to send the respective tuning values * to both the target synths. */ t1 = synth->mem.param[45]; t2 = ((guiSynth *) synth->second)->mem.param[45]; tg = synth->mem.param[56] - 0.5; if ((value = (t1 + tg) * C_RANGE_MIN_1) < 0) value = 0; if (value > C_RANGE_MIN_1) value = C_RANGE_MIN_1; bristolMidiSendMsg(fd, synth->sid, 126, 2, value); if ((value = (t2 + tg) * C_RANGE_MIN_1) < 0) value = 0; if (value > C_RANGE_MIN_1) value = C_RANGE_MIN_1; bristolMidiSendMsg(fd, synth->sid2, 126, 2, value); } static void multiTune(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; int hold = synth->mem.param[PANEL_SWITCH]; /*printf("multiTune()\n"); */ /* * Configures all the tune settings to zero (ie, 0.5). Do the Osc-A first, * since it is not visible, and then request the GUI to configure Osc-B. */ synth->mem.param[PANEL_SWITCH] = 1; bristolMidiSendMsg(global.controlfd, synth->sid, 0, 2, 8191); event.type = BRIGHTON_FLOAT; event.value = 0.49; brightonParamChange(synth->win, 0, 45, &event); brightonParamChange(synth->win, 0, 21, &event); event.value = 0.50; brightonParamChange(synth->win, 0, 45, &event); brightonParamChange(synth->win, 0, 21, &event); /* * This is global tuning outside of memories and should perhaps be left * alone? brightonParamChange(synth->win, 0, 56, &event); */ synth->mem.param[PANEL_SWITCH] = 0; bristolMidiSendMsg(global.controlfd, synth->sid2, 0, 2, 8191); event.value = 0.49; brightonParamChange(synth->win, 0, 45, &event); brightonParamChange(synth->win, 0, 21, &event); event.value = 0.50; brightonParamChange(synth->win, 0, 45, &event); brightonParamChange(synth->win, 0, 21, &event); synth->mem.param[PANEL_SWITCH] = hold; ((guiSynth *) synth->second)->mem.param[49] = 0.5; synth->mem.param[49] = 0.5; } static void midiRelease(guiSynth *synth, int fd, int chan, int c, int o, int v) { if (!global.libtest) { /* * Midi release is ALL notes, ALL synths. If this behaviour (in the * engine) changes we may need to put in an all_notes_off on the * second manual as well. */ bristolMidiSendMsg(fd, synth->sid, 127, 0, BRISTOL_ALL_NOTES_OFF); } } static int ummodCallback(brightonWindow *win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); synth->mem.param[UM_MOD_INDEX + index] = value; /* * Selector buttonn debugs. printf("ummodCallback(%i, %i, %f) [%f %f %f %f]\n", panel, index, value, synth->mem.param[UM_MOD_INDEX + 2], synth->mem.param[UM_MOD_INDEX + 3], synth->mem.param[UM_MOD_INDEX + 4], synth->mem.param[UM_MOD_INDEX + 5] ); */ /* * If this is controller 0 it is the frequency control, otherwise a * generic controller 1. */ if (index == 0) { if (synth->mem.param[UM_MOD_INDEX + 4] != 0) bristolMidiSendMsg(global.controlfd, synth->midichannel + 1, BRISTOL_EVENT_PITCH, 0, (int) (value * C_RANGE_MIN_1)); if (synth->mem.param[UM_MOD_INDEX + 2] != 0) bristolMidiSendMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_PITCH, 0, (int) (value * C_RANGE_MIN_1)); } else if (index == 1) { if (synth->mem.param[UM_MOD_INDEX + 5] != 0) bristolMidiControl(global.controlfd, synth->midichannel + 1, 0, 1, ((int) (value * C_RANGE_MIN_1)) >> 7); if (synth->mem.param[UM_MOD_INDEX + 3] != 0) bristolMidiControl(global.controlfd, synth->midichannel, 0, 1, ((int) (value * C_RANGE_MIN_1)) >> 7); } return(0); } static int lmmodCallback(brightonWindow * win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); brightonEvent event; int ivalue = (int) (value * C_RANGE_MIN_1); if (synth->dispatch[RADIOSET_4].other2) { synth->dispatch[RADIOSET_4].other2 = 0; return(0); } if (synth->dispatch[RADIOSET_5].other2) { synth->dispatch[RADIOSET_5].other2 = 0; return(0); } if (exclude) return(0); event.type = BRIGHTON_FLOAT; /* printf("lmmodCallback(%i, %i, %f)\n", panel, index, value); */ synth->mem.param[DEVICE_COUNT + index] = value; switch (index) { case 0: /* Lower Arpeg */ bristolMidiSendMsg(global.controlfd, synth->sid2, BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_ENABLE, ivalue); break; case 1: /* Upper Arpeg */ bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_ENABLE, ivalue); break; case 2: case 3: case 4: /* Arpeg direction Up/UpDown/Down */ if (synth->dispatch[RADIOSET_4].other1 != -1) { synth->dispatch[RADIOSET_4].other2 = 1; if (synth->dispatch[RADIOSET_4].other1 != index) event.value = 0; else event.value = 1; brightonParamChange(synth->win, 4, synth->dispatch[RADIOSET_4].other1, &event); } synth->dispatch[RADIOSET_4].other1 = index; bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_DIR, index - 2); bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_DIR, index - 2); bristolMidiSendMsg(global.controlfd, synth->sid2, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_DIR, index - 2); bristolMidiSendMsg(global.controlfd, synth->sid2, BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_DIR, index - 2); break; case 5: case 6: case 7: /* Range 3 octaves */ /* Range 2 octaves */ /* Range 1 octaves */ /* * We first need to ensure exclusion, then send the octave value. */ if (synth->dispatch[RADIOSET_5].other1 != -1) { synth->dispatch[RADIOSET_5].other2 = 1; if (synth->dispatch[RADIOSET_5].other1 != index) event.value = 0; else event.value = 1; brightonParamChange(synth->win, 4, synth->dispatch[RADIOSET_5].other1, &event); } synth->dispatch[RADIOSET_5].other1 = index; bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RANGE, 7 - index); bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_RANGE, 7 - index); bristolMidiSendMsg(global.controlfd, synth->sid2, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RANGE, 7 - index); bristolMidiSendMsg(global.controlfd, synth->sid2, BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_RANGE, 7 - index); break; case 8: /* Lower Env Trigger */ bristolMidiSendMsg(global.controlfd, synth->sid2, BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_TRIGGER, ivalue); break; case 9: /* Upper Env Trigger */ bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_TRIGGER, ivalue); break; case 10: /* Upper manual Seq Rec */ event.value = 0; exclude = 1; brightonParamChange(synth->win, 4, 11, &event); exclude = 0; bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_ENABLE, 0); bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RESEQ, ivalue); seqLearn = ivalue; break; case 11: /* Upper manual Seq Play */ event.value = 0; exclude = 1; brightonParamChange(synth->win, 4, 10, &event); exclude = 0; bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RESEQ, 0); bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_ENABLE, ivalue); seqLearn = 0; break; case 12: /* Lower manual Seq Rec */ event.value = 0; exclude = 1; brightonParamChange(synth->win, 4, 13, &event); exclude = 0; bristolMidiSendMsg(global.controlfd, synth->sid2, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_ENABLE, 0); bristolMidiSendMsg(global.controlfd, synth->sid2, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RESEQ, ivalue); seqLearn = ivalue; break; case 13: /* Lower manual Seq Play */ event.value = 0; exclude = 1; brightonParamChange(synth->win, 4, 12, &event); exclude = 0; bristolMidiSendMsg(global.controlfd, synth->sid2, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RESEQ, 0); bristolMidiSendMsg(global.controlfd, synth->sid2, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_ENABLE, ivalue); seqLearn = 0; break; case 14: /* Seq/Arp rate */ bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RATE, ivalue); bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_RATE, ivalue); bristolMidiSendMsg(global.controlfd, synth->sid2, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RATE, ivalue); bristolMidiSendMsg(global.controlfd, synth->sid2, BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_RATE, ivalue); break; } return(0); } static void pro10ChordInsert(guiSynth *synth, int note, int layer) { arpeggiatorMemory *seq = (arpeggiatorMemory *) synth->seq1.param; if (layer != KEY_PANEL) seq = (arpeggiatorMemory *) synth->seq2.param; if (seq->c_count == 0) seq->c_dif = note + synth->transpose; seq->chord[(int) (seq->c_count)] = (float) (note + synth->transpose - seq->c_dif); // if (jupiterDebug(synth, 0)) printf("Chord put %i into %i\n", (int) seq->chord[(int) (seq->c_count)], (int) (seq->c_count)); if ((seq->c_count += 1) >= BRISTOL_CHORD_MAX) seq->c_count = BRISTOL_CHORD_MAX; } static void pro10SeqInsert(guiSynth *synth, int note, int layer) { arpeggiatorMemory *seq = (arpeggiatorMemory *) synth->seq1.param; if (layer != KEY_PANEL) { printf(" Learning on second layer\n"); seq = (arpeggiatorMemory *) synth->seq2.param; } if (seq->s_max == 0) seq->s_dif = note + synth->transpose; seq->sequence[(int) (seq->s_max)] = // (float) (note + synth->transpose - seq->s_dif); (float) (note + synth->transpose); // if (pro10Debug(synth, 0)) printf("Seq put %i into %i\n", (int) seq->sequence[(int) (seq->s_max)], (int) (seq->s_max)); if ((seq->s_max += 1) >= BRISTOL_SEQ_MAX) seq->s_max = BRISTOL_SEQ_MAX; } /* * This used to send key events on one or two channels depending on the config. * Nothing really wrong with that however it would be better to actually tell * the emmulator what midi channels to use so that other master keyboards work * as expected. * * For 10 vs 5 layered voices (layer versus poly) we also need to add some * tweaks to the voicecounts. * * The code for all this is in the Jupiter, Bit* and OBXa. */ static int lmCallback(brightonWindow * win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); int mchan; /* printf("lmCallback(%i, %i, %f)\n", panel, index, value); */ if (global.libtest) return(0); if (panel == KEY_PANEL) mchan = synth->midichannel; else mchan = ((guiSynth *) synth->second)->midichannel; if ((chordLearn) && (value != 0)) pro10ChordInsert(synth, index, panel); if ((seqLearn) && (value != 0)) pro10SeqInsert(synth, index, panel); /* * Want to send a note event, on or off, for this index + transpose. */ if (value) bristolMidiSendMsg(global.controlfd, mchan, BRISTOL_EVENT_KEYON, 0, index + synth->transpose); else bristolMidiSendMsg(global.controlfd, mchan, BRISTOL_EVENT_KEYOFF, 0, index + synth->transpose); return(0); } static void pro10PanelSwitch2(guiSynth *synth, int fd, int chan, int c, int o, int v) { if (synth->flags & SUPPRESS) return; if (v != 0) { brightonEvent event; event.type = BRIGHTON_FLOAT; event.value = 0.0; brightonParamChange(synth->win, 0, PANEL_SWITCH, &event); } } static void pro10PanelSwitch(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; int i; /* printf("pro10PanelSwitch(%x, %i, %i, %i, %i, %1.0f)\n", */ /* synth, fd, chan, c, o, global.synths->mem.param[PANEL_SWITCH]); */ /* * Prevent param changes when we are switching panels. */ synth->flags |= SUPPRESS; /* * Go through all the active devices, and force the GUI to represent * the new value. */ if (synth->mem.param[PANEL_SWITCH] == 0) { /* * Go through all the params, and request an update to the GUI */ for (i = 0; i < ACTIVE_DEVS; i++) { event.type = BRIGHTON_FLOAT; event.value = ((guiSynth *) synth->second)->mem.param[i] + 1; brightonParamChange(synth->win, 0, i, &event); event.value = ((guiSynth *) synth->second)->mem.param[i]; brightonParamChange(synth->win, 0, i, &event); } } else { for (i = 0; i < ACTIVE_DEVS; i++) { event.type = BRIGHTON_FLOAT; event.value = synth->mem.param[i] + 1; brightonParamChange(synth->win, 0, i, &event); event.value = synth->mem.param[i]; brightonParamChange(synth->win, 0, i, &event); } } event.type = BRIGHTON_FLOAT; event.value = 1.0 - synth->mem.param[PANEL_SWITCH]; brightonParamChange(synth->win, 0, PANEL_SWITCH + 1, &event); synth->flags &= ~SUPPRESS; } /* pro10MemoryShim(synth, "prophet", 0, synth->bank + synth->location, synth->mem.active, 0, 0) < 0) */ static int pro10MemoryShim(guiSynth *synth, char *algo, char *name, int location, int active, int skip, int flags) { if ((synth->flags & REQ_DEBUG_MASK) >= REQ_MIDI_DEBUG2) printf("Shim %i\n", location); /* * Decide which manual is operational, load it */ if (synth->mem.param[PANEL_SWITCH] == 0) synth = ((guiSynth *) synth->second); loadMemory(synth, "prophet", 0, location, synth->mem.active, 0, 0); loadSequence(&synth->seq1, "prophet", location, 0); fillSequencer(synth, (arpeggiatorMemory *) synth->seq1.param, 0); return(0); } static void pro10MemoryLower(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; event.type = BRIGHTON_FLOAT; event.value = 1.0; /* printf("pro10MemoryLower(%i, %i)\n", c, o); */ if (synth->flags & MEM_LOADING) return; if ((synth->flags & OPERATIONAL) == 0) return; if (synth->flags & SUPPRESS) return; if (synth->dispatch[RADIOSET_2].other2) { synth->dispatch[RADIOSET_2].other2 = 0; return; } if (synth->mem.param[PANEL_SWITCH] != 0) brightonParamChange(synth->win, 0, PANEL_SWITCH + 1, &event); synth = ((guiSynth *) synth->second); switch (c) { default: case 0: /* * We want to make these into memory buttons. To do so we need to * know what the last active button was, and deactivate its * display, then send any message which represents the most * recently configured value. Since this is a memory button we do * not have much issue with the message, but we are concerned with * the display. */ if (synth->dispatch[RADIOSET_2].other1 != -1) { synth->dispatch[RADIOSET_2].other2 = 1; if (synth->dispatch[RADIOSET_2].other1 != o) event.value = 0; else event.value = 1; brightonParamChange(synth->win, synth->panel, synth->dispatch[RADIOSET_2].other1 + RADIOSET_2, &event); } synth->dispatch[RADIOSET_2].other1 = o; if (synth->flags & BANK_SELECT) { if ((synth->bank * 10 + o * 10) >= 1000) { synth->location = o; synth->flags &= ~BANK_SELECT; if (loadMemory(synth, "prophet", 0, synth->bank + synth->location, synth->mem.active, 0, BRISTOL_STAT) < 0) displayText(synth, "FRE", synth->bank + synth->location, DISPLAY_DEV_2); else displayText(synth, "PRG", synth->bank + synth->location, DISPLAY_DEV_2); } else { synth->bank = synth->bank * 10 + o * 10; if (loadMemory(synth, "prophet", 0, synth->bank + synth->location, synth->mem.active, 0, BRISTOL_STAT) < 0) displayText(synth, "FRE", synth->bank + synth->location, DISPLAY_DEV_2); else displayText(synth, "BANK", synth->bank + synth->location, DISPLAY_DEV_2); } } else { if (synth->bank < 10) synth->bank = 10; synth->location = o; if (loadMemory(synth, "prophet", 0, synth->bank + synth->location, synth->mem.active, 0, BRISTOL_STAT) < 0) displayText(synth, "FRE", synth->bank + synth->location, DISPLAY_DEV_2); else displayText(synth, "PRG", synth->bank + synth->location, DISPLAY_DEV_2); } break; case 1: if (synth->bank < 10) synth->bank = 10; if (synth->location == 0) synth->location = 1; if (loadMemory(synth, "prophet", 0, synth->bank + synth->location, synth->mem.active, 0, 0) < 0) displayText(synth, "FRE", synth->bank + synth->location, DISPLAY_DEV_2); else { displayText(synth, "PRG", synth->bank + synth->location, DISPLAY_DEV_2); loadSequence(&synth->seq1, "prophet", synth->bank + synth->location, 0); fillSequencer(synth, (arpeggiatorMemory *) synth->seq1.param, 0); } synth->flags &= ~BANK_SELECT; break; case 2: if (synth->bank < 10) synth->bank = 10; if (synth->location == 0) synth->location = 1; saveMemory(synth, "prophet", 0, synth->bank + synth->location, 0); saveSequence(synth, "prophet", synth->bank + synth->location, 0); displayText(synth, "PRG", synth->bank + synth->location, DISPLAY_DEV_2); synth->flags &= ~BANK_SELECT; break; case 3: if (synth->flags & BANK_SELECT) { synth->flags &= ~BANK_SELECT; if (loadMemory(synth, "prophet", 0, synth->bank + synth->location, synth->mem.active, 0, BRISTOL_STAT) < 0) displayText(synth, "FRE", synth->bank + synth->location, DISPLAY_DEV_2); else displayText(synth, "PRG", synth->bank + synth->location, DISPLAY_DEV_2); } else { synth->bank = 0; displayText(synth, "BANK", synth->bank, DISPLAY_DEV_2); synth->flags |= BANK_SELECT; } break; } /* printf(" pro10Memory(B: %i L %i: %i)\n", */ /* synth->bank, synth->location, o); */ } static void pro10Memory(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; event.type = BRIGHTON_FLOAT; event.value = 1.0; /* printf("pro10Memory(%i, %i)\n", c, o); */ if (synth->flags & MEM_LOADING) return; if ((synth->flags & OPERATIONAL) == 0) return; if (synth->flags & SUPPRESS) return; if (synth->dispatch[RADIOSET_1].other2) { synth->dispatch[RADIOSET_1].other2 = 0; return; } if (synth->mem.param[PANEL_SWITCH] == 0) brightonParamChange(synth->win, 0, PANEL_SWITCH, &event); switch (c) { default: case 0: /* * We want to make these into memory buttons. To do so we need to * know what the last active button was, and deactivate its * display, then send any message which represents the most * recently configured value. Since this is a memory button we do * not have much issue with the message, but we are concerned with * the display. */ if (synth->dispatch[RADIOSET_1].other1 != -1) { synth->dispatch[RADIOSET_1].other2 = 1; if (synth->dispatch[RADIOSET_1].other1 != o) event.value = 0; else event.value = 1; brightonParamChange(synth->win, synth->panel, synth->dispatch[RADIOSET_1].other1 + RADIOSET_1, &event); } synth->dispatch[RADIOSET_1].other1 = o; if (synth->flags & BANK_SELECT) { if ((synth->bank * 10 + o * 10) >= 1000) { synth->location = o; synth->flags &= ~BANK_SELECT; if (loadMemory(synth, "prophet", 0, synth->bank + synth->location, synth->mem.active, 0, BRISTOL_STAT) < 0) displayText(synth, "FRE", synth->bank + synth->location, DISPLAY_DEV); else displayText(synth, "PRG", synth->bank + synth->location, DISPLAY_DEV); } else { synth->bank = synth->bank * 10 + o * 10; if (loadMemory(synth, "prophet", 0, synth->bank + synth->location, synth->mem.active, 0, BRISTOL_STAT) < 0) displayText(synth, "FRE", synth->bank + synth->location, DISPLAY_DEV); else displayText(synth, "BANK", synth->bank + synth->location, DISPLAY_DEV); } } else { if (synth->bank < 10) synth->bank = 10; synth->location = o; if (loadMemory(synth, "prophet", 0, synth->bank + synth->location, synth->mem.active, 0, BRISTOL_STAT) < 0) displayText(synth, "FRE", synth->bank + synth->location, DISPLAY_DEV); else displayText(synth, "PRG", synth->bank + synth->location, DISPLAY_DEV); } break; case 1: if (synth->bank < 10) synth->bank = 10; if (synth->location == 0) synth->location = 1; if (loadMemory(synth, "prophet", 0, synth->bank + synth->location, synth->mem.active, 0, 0) < 0) displayText(synth, "FRE", synth->bank + synth->location, DISPLAY_DEV); else { displayText(synth, "PRG", synth->bank + synth->location, DISPLAY_DEV); loadSequence(&synth->seq1, "prophet", synth->bank + synth->location, 0); fillSequencer(synth, (arpeggiatorMemory *) synth->seq1.param, 0); } synth->flags &= ~BANK_SELECT; break; case 2: if (synth->bank < 10) synth->bank = 10; if (synth->location == 0) synth->location = 1; saveMemory(synth, "prophet", 0, synth->bank + synth->location, 0); saveSequence(synth, "prophet", synth->bank + synth->location, 0); displayText(synth, "PRG", synth->bank + synth->location, DISPLAY_DEV); synth->flags &= ~BANK_SELECT; break; case 3: if (synth->flags & BANK_SELECT) { synth->flags &= ~BANK_SELECT; if (loadMemory(synth, "prophet", 0, synth->bank + synth->location, synth->mem.active, 0, BRISTOL_STAT) < 0) displayText(synth, "FRE", synth->bank + synth->location, DISPLAY_DEV); else displayText(synth, "PRG", synth->bank + synth->location, DISPLAY_DEV); } else { synth->bank = 0; displayText(synth, "BANK", synth->bank, DISPLAY_DEV); synth->flags |= BANK_SELECT; } break; } /* printf(" pro10Memory(B: %i L %i: %i)\n", */ /* synth->bank, synth->location, o); */ } static void pro10Midi(guiSynth *synth, int fd, int chan, int c, int o, int v) { int newchan; if ((synth->flags & OPERATIONAL) == 0) return; if (c == 1) { if ((newchan = synth->midichannel - 1) < 0) { synth->midichannel = 0; return; } } else { if ((newchan = synth->midichannel + 1) > 14) { synth->midichannel = 14; return; } } if (global.libtest == 0) { /* * Do second manual, then upper. */ bristolMidiSendMsg(global.controlfd, synth->sid2, 127, 0, (BRISTOL_MIDICHANNEL|newchan) + 1); bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_MIDICHANNEL|newchan); } synth->midichannel = newchan; /*printf("P: going to display: %x, %x\n", synth, synth->win); */ displayText(synth, "MIDI", synth->midichannel + 1, DISPLAY_DEV); } /* * For the sake of ease of use, links have been placed here to be called * by any of the devices created. They would be better in some other file, * perhaps with this as a dispatch. * * Param refers to the device index in the locations table given below. */ static int pro10Callback(brightonWindow * win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); int sendvalue, sid; /* printf("pro10Callback(%i, %f): %1.0f\n", index, value, global.synths->mem.param[PANEL_SWITCH]); */ if (synth->flags & SUPPRESS) return(0); if (synth == 0) return(0); if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0)) return(0); if (pro10App.resources[0].devlocn[index].to == 1.0) sendvalue = value * (CONTROLLER_RANGE - 1); else sendvalue = value; if (synth->mem.param[PANEL_SWITCH] != 0) { synth->mem.param[index] = value; sid = synth->sid; } else { ((guiSynth *) synth->second)->mem.param[index] = value; if (index >= ACTIVE_DEVS) synth->mem.param[index] = value; sid = synth->sid2; } if ((!global.libtest) || (index >= ACTIVE_DEVS)) synth->dispatch[index].routine(synth, global.controlfd, sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #ifdef DEBUG else printf("dispatch[%p,%i](%i, %i, %i, %i, %i)\n", synth, index, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #endif return(0); } static void pro10Balance(guiSynth *synth, int fd, int chan, int c, int o, int v) { float vol, bal; vol = synth->mem.param[54]; bal = synth->mem.param[55]; bristolMidiSendMsg(global.controlfd, synth->sid2, 126, 36, (int) (vol * (1.0 - bal) * C_RANGE_MIN_1)); bristolMidiSendMsg(global.controlfd, synth->sid, 126, 36, (int) (vol * bal * C_RANGE_MIN_1)); } static void pro10Chord(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; int sid = synth->sid; if ((synth->flags & OPERATIONAL) == 0) return; if (synth->flags & MEM_LOADING) return; if (exclude) return; event.type = BRIGHTON_FLOAT; // if (jupiterDebug(synth, 1)) printf("Chord request: %i %i %i (p=%f)\n", c, o, v, synth->mem.param[PANEL_SWITCH]); if (synth->mem.param[PANEL_SWITCH] == 0) sid = synth->sid2; /* * We can be called from Record or Play with values of on or off. The first * step is always to stop any peer processing such as stopping recording if * Play is selected, etc. * * After that we decide what to do, it may be start/stop recording or * start/stop playing a chord. */ if (c == 0) { /* Record */ if (v != 0) { if (synth->seq1.param == NULL) loadSequence(&synth->seq1, "prophet", 0, 0); if (synth->seq2.param == NULL) loadSequence(&synth->seq2, "prophet", 0, BRISTOL_SID2); chordLearn = 1; // if (jupiterDebug(synth, 0)) printf("Chord learn requested %x\n", synth->flags); if (synth->mem.param[PANEL_SWITCH] == 0) synth->seq2.param[1] = 0; else synth->seq1.param[1] = 0; /* * This is to start a re-seq of the chord. Disable play if it was * selected then request resequence. */ bristolMidiSendMsg(global.controlfd, sid, BRISTOL_ARPEGGIATOR, BRISTOL_CHORD_ENABLE, 0); event.value = 0; exclude = 1; brightonParamChange(synth->win, 0, 58, &event); exclude = 0; bristolMidiSendMsg(global.controlfd, sid, BRISTOL_ARPEGGIATOR, BRISTOL_CHORD_RESEQ, 1); } else { chordLearn = 0; bristolMidiSendMsg(global.controlfd, sid, BRISTOL_ARPEGGIATOR, BRISTOL_CHORD_RESEQ, 0); } return; } if (chordLearn == 1) { /* * This is a button press during the learning sequence, in which case * it needs to be terminated. */ chordLearn = 0; bristolMidiSendMsg(global.controlfd, sid, BRISTOL_ARPEGGIATOR, BRISTOL_CHORD_RESEQ, 0); event.value = 0; exclude = 1; brightonParamChange(synth->win, 0, 57, &event); exclude = 0; } bristolMidiSendMsg(global.controlfd, sid, BRISTOL_ARPEGGIATOR, BRISTOL_CHORD_ENABLE, v); return; } static void keyTracking(guiSynth *synth, int fd, int chan, int c, int o, int v) { if (synth->mem.param[PANEL_SWITCH] -= 0) bristolMidiSendMsg(fd, synth->sid, 4, 3, v / 2); else bristolMidiSendMsg(fd, synth->sid2, 4, 3, v / 2); } /* * Any location initialisation required to run the callbacks. For bristol, this * will connect to the engine, and give it some base parameters. * May need to generate some application specific menus. * Will also then make specific requests to some of the devices to alter their * rendering. */ static int pro10Init(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); dispatcher *dispatch; int i; if (synth == 0) { synth = findSynth(global.synths, 0); if (synth == 0) { printf("cannot init\n"); return(0); } } if ((initmem = synth->location) == 0) initmem = 11; synth->win = win; printf("Initialise the pro10 link to bristol: %p %p\n", synth, synth->win); synth->mem.param = (float *) brightonmalloc( (DEVICE_COUNT + P10_MOD_COUNT + PMOD_COUNT) * sizeof(float)); synth->mem.count = DEVICE_COUNT; synth->mem.active = ACTIVE_DEVS; synth->dispatch = (dispatcher *) brightonmalloc( (DEVICE_COUNT + P10_MOD_COUNT + PMOD_COUNT) * sizeof(dispatcher)); dispatch = synth->dispatch; synth->second = brightonmalloc(sizeof(guiSynth)); bcopy(synth, ((guiSynth *) synth->second), sizeof(guiSynth)); ((guiSynth *) synth->second)->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float)); ((guiSynth *) synth->second)->mem.count = DEVICE_COUNT; ((guiSynth *) synth->second)->mem.active = ACTIVE_DEVS; ((guiSynth *) synth->second)->dispatch = synth->dispatch; /* If we have a default voice count then limit it */ if (synth->voices == BRISTOL_VOICECOUNT) { ((guiSynth *) synth->second)->voices = 5; synth->voices = 10; } else ((guiSynth *) synth->second)->voices = synth->voices >> 1; /* * We really want to have three connection mechanisms. These should be * 1. Unix named sockets. * 2. UDP sockets. * 3. MIDI pipe. */ if (!global.libtest) { int v = synth->voices; synth->synthtype = BRISTOL_PROPHET; bcopy(&global, &manual, sizeof(guimain)); if ((synth->sid = initConnection(&global, synth)) < 0) return(-1); manual.flags |= BRISTOL_CONN_FORCE|BRIGHTON_NOENGINE; manual.host = global.host; manual.port = global.port; synth->voices = ((guiSynth *) synth->second)->voices; /* * This looks a bit evil now but whatever happens it gets fixed later * when the dual/split/layer is configured - that will 'retweak' the * midi channels. */ if (++synth->midichannel > 15) synth->midichannel = 15; if ((synth->sid2 = initConnection(&manual, synth)) < 0) return(-1); global.manualfd = manual.controlfd; global.manual = &manual; manual.manual = &global; synth->midichannel--; synth->voices = v; } else { synth->sid = 5; synth->sid2 = 10; } for (i = 0; i < DEVICE_COUNT; i++) synth->dispatch[i].routine = pro10MidiSendMsg; dispatch[0].controller = 126; dispatch[0].operator = 6; dispatch[1].controller = 126; dispatch[1].operator = 7; dispatch[2].controller = 126; dispatch[2].operator = 8; dispatch[3].controller = 126; dispatch[3].operator = 9; dispatch[4].controller = 126; dispatch[4].operator = 10; dispatch[5].controller = 2; dispatch[5].operator = 0; dispatch[6].controller = 126; dispatch[6].operator = 24; dispatch[7].controller = 126; dispatch[7].operator = 25; dispatch[8].controller = 126; dispatch[8].operator = 26; dispatch[9].controller = 126; dispatch[9].operator = 11; dispatch[10].controller = 126; dispatch[10].operator = 12; dispatch[11].controller = 126; dispatch[11].operator = 13; dispatch[12].controller = 126; dispatch[12].operator = 14; dispatch[13].controller = 126; dispatch[13].operator = 15; dispatch[14].controller = 126; dispatch[14].operator = 16; dispatch[15].controller = 0; dispatch[15].operator = 1; dispatch[16].controller = 0; dispatch[16].operator = 4; dispatch[17].controller = 0; dispatch[17].operator = 6; dispatch[18].controller = 0; dispatch[18].operator = 0; dispatch[19].controller = 0; dispatch[19].operator = 7; dispatch[20].controller = 1; dispatch[20].operator = 1; dispatch[21].controller = 1; dispatch[21].operator = 2; dispatch[22].controller = 1; dispatch[22].operator = 4; dispatch[23].controller = 1; dispatch[23].operator = 5; dispatch[24].controller = 1; dispatch[24].operator = 6; dispatch[25].controller = 1; dispatch[25].operator = 0; dispatch[26].controller = 126; dispatch[26].operator = 18; dispatch[27].controller = 126; dispatch[27].operator = 19; dispatch[28].controller = 126; dispatch[28].operator = 0; dispatch[29].controller = 126; dispatch[29].operator = 1; dispatch[30].controller = 126; dispatch[30].operator = 20; dispatch[31].controller = 126; dispatch[31].operator = 21; dispatch[32].controller = 126; dispatch[32].operator = 22; dispatch[33].controller = 4; dispatch[33].operator = 0; dispatch[34].controller = 4; dispatch[34].operator = 1; dispatch[35].controller = 126; dispatch[35].operator = 23; dispatch[36].controller = 4; dispatch[36].routine = (synthRoutine) keyTracking; dispatch[36].operator = 3; dispatch[37].controller = 3; dispatch[37].operator = 0; dispatch[38].controller = 3; dispatch[38].operator = 1; dispatch[39].controller = 3; dispatch[39].operator = 2; dispatch[40].controller = 3; dispatch[40].operator = 3; dispatch[41].controller = 5; dispatch[41].operator = 0; dispatch[42].controller = 5; dispatch[42].operator = 1; dispatch[43].controller = 5; dispatch[43].operator = 2; dispatch[44].controller = 5; dispatch[44].operator = 3; dispatch[45].controller = 126; dispatch[45].operator = 2; dispatch[45].routine = (synthRoutine) pro10Tune; /* Volume */ dispatch[46].controller = 5; dispatch[46].operator = 4; dispatch[47].controller = 126; dispatch[47].operator = 34; dispatch[48].controller = 1; dispatch[48].operator = 1; dispatch[48].routine = (synthRoutine) midiRelease; dispatch[49].controller = 126; dispatch[49].operator = 3; dispatch[49].routine = (synthRoutine) multiA440; dispatch[50].controller = 1; dispatch[50].operator = 1; dispatch[50].routine = (synthRoutine) multiTune; /* D/L/P */ dispatch[51].controller = 0; dispatch[51].routine = (synthRoutine) pro10DLP; dispatch[52].controller = 1; dispatch[52].routine = (synthRoutine) pro10DLP; dispatch[53].controller = 2; dispatch[53].routine = (synthRoutine) pro10DLP; /* Master gain */ dispatch[54].controller = 126; dispatch[54].operator = 36; dispatch[54].routine = (synthRoutine) pro10Balance; /* Master balance */ dispatch[55].controller = 126; dispatch[55].operator = 35; dispatch[55].routine = (synthRoutine) pro10Balance; dispatch[56].routine = (synthRoutine) pro10Tune; /* Hold/Chord */ dispatch[57].controller = 0; dispatch[57].operator = BRISTOL_CHORD_ENABLE; dispatch[57].routine = (synthRoutine) pro10Chord; dispatch[58].controller = 1; dispatch[58].operator = BRISTOL_CHORD_ENABLE; dispatch[58].routine = (synthRoutine) pro10Chord; dispatch[71].operator = 1; dispatch[72].operator = 2; dispatch[73].operator = 3; dispatch[74].operator = 4; dispatch[75].operator = 5; dispatch[76].operator = 6; dispatch[77].operator = 7; dispatch[78].operator = 8; dispatch[79].controller = 1; dispatch[80].controller = 2; dispatch[81].controller = 3; dispatch[71].routine = dispatch[72].routine = dispatch[73].routine = dispatch[74].routine = dispatch[75].routine = dispatch[76].routine = dispatch[77].routine = dispatch[78].routine = dispatch[79].routine = dispatch[80].routine = dispatch[81].routine = (synthRoutine) pro10Memory; dispatch[82].operator = 1; dispatch[83].operator = 2; dispatch[84].operator = 3; dispatch[85].operator = 4; dispatch[86].operator = 5; dispatch[87].operator = 6; dispatch[88].operator = 7; dispatch[89].operator = 8; dispatch[90].controller = 1; dispatch[91].controller = 2; dispatch[92].controller = 3; dispatch[82].routine = dispatch[83].routine = dispatch[84].routine = dispatch[85].routine = dispatch[86].routine = dispatch[87].routine = dispatch[88].routine = dispatch[89].routine = dispatch[90].routine = dispatch[91].routine = dispatch[92].routine = (synthRoutine) pro10MemoryLower; dispatch[93].routine = dispatch[94].routine = (synthRoutine) pro10Midi; dispatch[93].controller = 1; dispatch[94].controller = 2; dispatch[95].routine = (synthRoutine) pro10PanelSwitch; dispatch[96].routine = (synthRoutine) pro10PanelSwitch2; dispatch[RADIOSET_1].other1 = -1; dispatch[RADIOSET_2].other1 = -1; dispatch[RADIOSET_3].other1 = -1; dispatch[RADIOSET_4].other1 = -1; dispatch[RADIOSET_5].other1 = -1; dispatch[DEVICE_COUNT].other1 = -1; /* Tune osc-1 */ bristolMidiSendMsg(global.controlfd, synth->sid, 0, 2, 8192); bristolMidiSendMsg(global.controlfd, synth->sid2, 0, 2, 8192); /* Gain on filter contour */ bristolMidiSendMsg(global.controlfd, synth->sid, 3, 4, CONTROLLER_RANGE - 1); bristolMidiSendMsg(global.controlfd, synth->sid2, 3, 4, CONTROLLER_RANGE - 1); bristolMidiSendMsg(global.controlfd, synth->sid, 4, 4, 4); bristolMidiSendMsg(global.controlfd, synth->sid2, 4, 4, 4); return(0); } static void memForce(guiSynth *synth) { brightonEvent event; int i; synth->flags |= SUPPRESS; event.type = BRIGHTON_FLOAT; event.value = 1; for (i = 0; i < ACTIVE_DEVS; i++) { brightonParamChange(synth->win, 0, i, &event); } event.value = 0; for (i = 0; i < ACTIVE_DEVS; i++) { brightonParamChange(synth->win, 0, i, &event); } synth->flags &= ~SUPPRESS; } /* * This will be called to make any routine specific parameters available. */ static int pro10Configure(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); brightonEvent event; if (synth == 0) { printf("problems going operational\n"); return(-1); } if (synth->flags & OPERATIONAL) return(0); printf("going operational: %p, %p\n", synth, win); synth->flags |= OPERATIONAL; synth->keypanel = 1; synth->keypanel2 = 3; synth->transpose = 12; synth->mem.param[PANEL_SWITCH] = 1; synth->bank = 10; synth->location = 1; memForce(synth); loadMemory(synth, "prophet", 0, initmem, synth->mem.active, 0, 0); loadSequence(&synth->seq1, "prophet", initmem, 0); fillSequencer(synth, (arpeggiatorMemory *) synth->seq1.param, 0); synth->mem.param[PANEL_SWITCH] = 0; ((guiSynth *) synth->second)->resources = synth->resources; ((guiSynth *) synth->second)->win = synth->win; ((guiSynth *) synth->second)->bank = 10; ((guiSynth *) synth->second)->location = 2; ((guiSynth *) synth->second)->panel = 0; ((guiSynth *) synth->second)->mem.active = ACTIVE_DEVS; ((guiSynth *) synth->second)->transpose = 12; memForce(((guiSynth *) synth->second)); loadMemory(((guiSynth *) synth->second), "prophet", 0, initmem + 1, synth->mem.active, 0, 0); synth->mem.param[PANEL_SWITCH] = 0; /* * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only * occurs on first paint, so we suppress the first paint, and then request * an expose here. */ brightonPut(win, "bitmaps/blueprints/prophet10shade.xpm", 0, 0, win->width, win->height); event.type = BRIGHTON_EXPOSE; event.intvalue = 1; brightonParamChange(synth->win, KEY_PANEL, -1, &event); event.type = BRIGHTON_EXPOSE; event.intvalue = 1; brightonParamChange(synth->win, KEY_PANEL + 2, -1, &event); event.type = BRIGHTON_FLOAT; event.value = 1.0f; brightonParamChange(synth->win, 2, 2, &event); brightonParamChange(synth->win, 2, 3, &event); brightonParamChange(synth->win, 2, 4, &event); brightonParamChange(synth->win, 2, 5, &event); brightonParamChange(synth->win, 4, 2, &event); brightonParamChange(synth->win, 4, 6, &event); brightonParamChange(synth->win, 4, 8, &event); brightonParamChange(synth->win, 4, 9, &event); brightonParamChange(synth->win, 0, RADIOSET_1 + 1, &event); brightonParamChange(synth->win, 0, RADIOSET_2 + 2, &event); configureGlobals(synth); brightonParamChange(synth->win, 0, 51, &event); /* Master controls */ event.value = 0.8f; brightonParamChange(synth->win, 0, 54, &event); event.value = 0.5f; brightonParamChange(synth->win, 0, 55, &event); event.value = 0.5f; brightonParamChange(synth->win, 0, 56, &event); event.value = 1.0; brightonParamChange(synth->win, 0, PANEL_SWITCH, &event); synth->loadMemory = (loadRoutine) pro10MemoryShim; return(0); } bristol-0.60.11/brighton/brightonPoly.c0000644000175000017500000007405411746476475014755 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* Korg MonoPoly */ #include #include "brighton.h" #include "brightonMini.h" #include "brightoninternals.h" static int initmem, width; static int polyInit(); static int polyConfigure(); static int polyCallback(brightonWindow *, int, int, float); /*static int keyCallback(void *, int, int, float); */ static int polyModCallback(brightonWindow *, int, int, float); static int pmidiCallback(brightonWindow *, int, int, float); extern guimain global; #include "brightonKeys.h" #define FIRST_DEV 0 #define DEVICE_COUNT 74 #define ACTIVE_DEVS 56 #define MEM_START ACTIVE_DEVS #define RADIOSET_1 MEM_START #define RADIOSET_2 (MEM_START + 1) #define RADIOSET_3 53 #define KEY_PANEL 1 #define KEY_HOLD 52 #define CDIFF 56 #define CDIFF2 12 #define C0 25 #define C1 (C0 + CDIFF) #define C2 (C1 + CDIFF + CDIFF2) #define C3 (C2 + CDIFF + CDIFF2) #define C4 (C3 + CDIFF) #define C5 (C4 + CDIFF) #define C6 (C5 + CDIFF) #define C7 (C6 + CDIFF + CDIFF2) #define C8 (C7 + CDIFF + CDIFF2) #define C9 (C8 + CDIFF + CDIFF2) #define C10 (C9 + CDIFF) #define C11 (C10 + CDIFF) #define C12 (C11 + CDIFF + CDIFF2) #define C13 (C12 + CDIFF) #define C14 (C13 + CDIFF) #define C15 (C14 + CDIFF) #define R0 115 #define R1 (R0 + 205) #define R2 (R1 + 205) #define R3 (R2 + 205) #define R3u (R2 + 200) #define R3d (R2 + 310) #define S1 60 #define S2 100 #define S3 90 #define B1 15 #define B2 60 #define BOFF 11 /* * This structure is for device definition. The structure is defined in * include/brighton.h, further definitions in brighton/brightonDevtable.h and * include/brightoninternals.h * * typedef int (*brightonCallback)(int, float); * typedef struct BrightonLocations { * int device; 0=rotary, 1=scale, etc. * float relx, rely; relative position with regards to 1000 by 1000 window * float relw, relh; relative height. * int from, to; * brightonCallback callback; specific to this dev * char *image; bitmap. If zero take a device default. * int flags; * } brightonLocations; * * This example is for a polyBristol type synth interface. */ static brightonLocations locations[DEVICE_COUNT] = { /* Osc-1 - 0 */ {"Osc-1 Wave", 0, C9, R0, S3, S3, 0, 3, 0, "bitmaps/knobs/knob6.xpm", 0, BRIGHTON_STEPPED}, {"Osc-1 Transpose", 0, C10, R0, S3, S3, 0, 3, 0, "bitmaps/knobs/knob6.xpm", 0, BRIGHTON_STEPPED}, {"Osc-1 Gain", 0, C11, R0, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, /* Osc-2 - 3 */ {"Osc-2 Tune", 0, C8, R1, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, BRIGHTON_NOTCH}, {"Osc-2 Wave", 0, C9, R1, S3, S3, 0, 3, 0, "bitmaps/knobs/knob6.xpm", 0, BRIGHTON_STEPPED}, {"Osc-2 Transpose", 0, C10, R1, S3, S3, 0, 3, 0, "bitmaps/knobs/knob6.xpm", 0, BRIGHTON_STEPPED}, {"Osc-2 Gain", 0, C11, R1, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, /* Osc-3 - 7 */ {"Osc-3 Tune", 0, C8, R2, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, BRIGHTON_NOTCH}, {"Osc-3 Wave", 0, C9, R2, S3, S3, 0, 3, 0, "bitmaps/knobs/knob6.xpm", 0, BRIGHTON_STEPPED}, {"Osc-3 Transpose", 0, C10, R2, S3, S3, 0, 3, 0, "bitmaps/knobs/knob6.xpm", 0, BRIGHTON_STEPPED}, {"Osc-3 Gain", 0, C11, R2, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, /* Osc-4 - 11 */ {"Osc-3 Wave", 0, C8, R3, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, BRIGHTON_NOTCH}, {"Osc-4 Tune", 0, C9, R3, S3, S3, 0, 3, 0, "bitmaps/knobs/knob6.xpm", 0, BRIGHTON_STEPPED}, {"Osc-4 Transpose", 0, C10, R3, S3, S3, 0, 3, 0, "bitmaps/knobs/knob6.xpm", 0, BRIGHTON_STEPPED}, {"Osc-4 Gain", 0, C11, R3, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, /* Filter - 15 */ {"VCF-Cutoff", 0, C12, R0, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"VCF-Resonance", 0, C13, R0, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"VCF-Env", 0, C14, R0, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"VCF-KBD", 0, C15, R0, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, /* Filter Env - 19 */ {"VCF-Attack", 0, C12, R1, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"VCF-Decay", 0, C13, R1, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"VCF-Sustain", 0, C14, R1, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"VCF-Release", 0, C15, R1, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, /* Env - 23 */ {"VCA-Attack", 0, C12, R2, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"VCA-Decay", 0, C13, R2, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"VCA-Sustain", 0, C14, R2, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"VCA-Release", 0, C15, R2, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, /* Volume - 27 env gain and TO BE REASSIGNED */ {"Volume", 0, C0, R1, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"Arpeg Mode", 2, C1, R1, B1, S2, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW}, /* Three LFO MG modes - 29 */ {"MG-1 Gain", 0, C2, R1, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"MG-1 Wave", 0, C2, R2, S3, S3, 0, 3, 0, "bitmaps/knobs/knob6.xpm", 0, BRIGHTON_STEPPED}, {"MG-2 Gain", 0, C3, R1, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, /* 3 PW and PWM - 32 */ {"PW-Source", 2, C4, R1, B1, S2, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW}, {"PWM", 0, C5, R1, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"PW", 0, C6, R1, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, /* 4, actually 5 mods. - 35 */ {"Mod-X-Mod", 0, C3, R2, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"Mod-Freq", 0, C4, R2, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"Mod-Source", 2, C5 - 20, R2 + 20, B1, S1, 0, 1, 0, "bitmaps/buttons/sw1.xpm", "bitmaps/buttons/sw2.xpm", BRIGHTON_NOSHADOW}, {"Mod-Mode", 2, C5 + BOFF * 2, R2, B1, S2, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW}, {"Mod-Sng/Dbl", 2, C5 + BOFF * 5 + 10, R2 + 20, B1, S1, 0, 1, 0, "bitmaps/buttons/sw1.xpm", "bitmaps/buttons/sw2.xpm", BRIGHTON_NOSHADOW}, /* Glide, detune - 40 */ {"Glide", 0, C7, R0, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"Detune", 0, C7, R1, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, /* Transpose - 42 */ {"Transpose", 2, C7 - BOFF, R2, B1, S2, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW}, /* Noise - 43 */ {"Noise", 0, C12, R3, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, /* Trig, Damp - 44 */ {"Trigger", 2, C13, R3 + 20, B1, S1, 0, 1, 0, "bitmaps/buttons/sw1.xpm", "bitmaps/buttons/sw2.xpm", BRIGHTON_NOSHADOW}, {"Damp", 2, C14, R3 + 20, B1, S1, 0, 1, 0, "bitmaps/buttons/sw1.xpm", "bitmaps/buttons/sw2.xpm", BRIGHTON_NOSHADOW}, /* Effects - 46 */ {"FX on/off", 2, C4 + BOFF, R3 + 20, B1, S1, 0, 1, 0, "bitmaps/buttons/pressoffw.xpm", "bitmaps/buttons/pressonw.xpm", 0}, /* Master Tune - 47 */ {"MasterTuning", 0, C8, R0, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, BRIGHTON_NOTCH}, /* Wheel gain */ {"Bend-Depth", 0, C0, R2, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"Bend-Dest", 2, C0, R3, B1, S2, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW}, {"ModWheel-Depth", 0, C1, R2, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"ModWheel-Dest", 2, C1, R3, B1, S2, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW}, /* Modes */ {"Mode-Hold", 2, C2, R3, B1, S1, 0, 1, 0, "bitmaps/buttons/pressoffw.xpm", "bitmaps/buttons/pressonw.xpm", 0}, {"Mode-Mono", 2, C2 + BOFF * 2 + 9, R3, B1, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, {"Mode-Poly", 2, C3 - 9, R3, B1, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, {"Mode-Share", 2, C3 + BOFF * 2, R3, B1, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, /* Memories - Save */ {"", 2, C5, R3u, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffo.xpm", "bitmaps/buttons/pressono.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, C5 + BOFF* 2, R3u, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, C5 + BOFF* 4, R3u, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, C5 + BOFF* 6, R3u, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, C5 + BOFF* 8, R3u, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, C5 + BOFF* 10, R3u, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, C5 + BOFF* 12, R3u, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, C5 + BOFF* 14, R3u, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, C5 + BOFF* 2, R3d, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, C5 + BOFF* 4, R3d, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, C5 + BOFF* 6, R3d, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, C5 + BOFF* 8, R3d, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, C5 + BOFF* 10, R3d, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, C5 + BOFF* 12, R3d, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, C5 + BOFF* 14, R3d, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* Load */ {"", 2, C5, R3d, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffw.xpm", "bitmaps/buttons/pressonw.xpm", BRIGHTON_CHECKBUTTON}, /* Midi */ {"", 2, C15, R3, B1, S1, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, C15 + BOFF * 2, R3, B1, S1, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, }; /* */ /* * This is a set of globals for the main window rendering. Again taken from * include/brighton.h */ brightonApp polyApp = { "monopoly", 0, /* no blueprint on wood background. */ "bitmaps/textures/wood4.xpm", 0, /* BRIGHTON_STRETCH, //flags */ polyInit, polyConfigure, /* 3 callbacks, unused? */ pmidiCallback, destroySynth, {1, 100, 2, 2, 5, 520, 0, 0}, 750, 400, 0, 0, 7, { { "Poly", "bitmaps/blueprints/poly.xpm", "bitmaps/textures/metal4.xpm", BRIGHTON_STRETCH, /* flags */ 0, 0, polyCallback, 15, 0, 970, 620, DEVICE_COUNT, locations }, { "Keyboard", 0, "bitmaps/newkeys/tkbg.xpm", /* flags */ 0x020|BRIGHTON_STRETCH, 0, 0, keyCallback, 150, 620, 845, 350, KEY_COUNT_3OCTAVE, keys3octave2 }, { "Mods", "bitmaps/blueprints/polymods.xpm", "bitmaps/textures/metal4.xpm", /* flags */ BRIGHTON_REVERSE, 0, 0, polyModCallback, 15, 620, 135, 350, 2, mods }, { "Side wood", 0, "bitmaps/textures/wood4.xpm", BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 0, 0, 15, 1000, 0, 0 }, { "Side wood", 0, "bitmaps/textures/wood.xpm", BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 2, 5, 12, 985, 0, 0 }, { "Side wood", 0, "bitmaps/textures/wood4.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /*flags */ 0, 0, 0, 985, 0, 15, 1000, 0, 0 }, { "Side wood", 0, "bitmaps/textures/wood.xpm", BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 986, 5, 14, 985, 0, 0 } } }; static void fixModes(guiSynth *synth) { brightonEvent event; int mode = 53; event.value = 1; /* * Operating modes are not configured when a memory is loaded, as that * does not work correctly. After the memory is loaded, this routine is * called to configure them. */ if (synth->mem.param[54] != 0) mode = 54; else if (synth->mem.param[55] != 0) mode = 55; brightonParamChange(synth->win, synth->panel, mode, &event); } int ploadMemory(guiSynth *synth, char *algo, char *name, int location, int active, int skip, int flags) { loadMemory(synth, "mono", 0, location, synth->mem.active, FIRST_DEV, 0); fixModes(synth); return(0); } static int pmidiCallback(brightonWindow *win, int controller, int value, float n) { guiSynth *synth = findSynth(global.synths, win); printf("midi callback: %x, %i\n", controller, value); switch(controller) { case MIDI_PROGRAM: printf("midi program: %x, %i\n", controller, value); synth->location = value; loadMemory(synth, "mono", 0, synth->bank + synth->location, synth->mem.active, FIRST_DEV, 0); fixModes(synth); break; case MIDI_BANK_SELECT: printf("midi banksel: %x, %i\n", controller, value); synth->bank = value; break; } return(0); } static int polyModCallback(brightonWindow *win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); /* printf("polyModCallback(%x, %i, %i, %f)\n", synth, panel, index, value); */ /* * If this is controller 0 it is the frequency control, otherwise a * generic controller 1. */ if (index == 0) bristolMidiControl(global.controlfd, synth->midichannel, 0, 2, ((int) (value * C_RANGE_MIN_1)) >> 7); else { bristolMidiControl(global.controlfd, synth->midichannel, 0, 1, ((int) (value * C_RANGE_MIN_1)) >> 7); } return(0); } static void polyMG2(void *synth, int fd, int chan, int c, int o, int v) { bristolMidiSendMsg(fd, chan, c, o, v); bristolMidiSendMsg(fd, chan, 126, 26, v); } static int polyMidiSendMsg(void *synth, int fd, int chan, int c, int o, int v) { bristolMidiSendMsg(fd, chan, c, o, v); return(0); } static void polyTranspose(guiSynth *synth, int fd, int chan, int c, int o, int v) { switch (v) { case 0: synth->transpose = 36; break; case 1: synth->transpose = 48; break; case 2: synth->transpose = 60; break; } } static void polyWaveform(guiSynth *synth, int fd, int chan, int c, int o, int v) { int offset; /* * 0 = tri, 1 = ramp, 2 and 3 are PW */ if (c == 34) { /* * Pulse width of all osc. */ bristolMidiSendMsg(fd, chan, 0, 0, v); bristolMidiSendMsg(fd, chan, 1, 0, v); bristolMidiSendMsg(fd, chan, 2, 0, v); bristolMidiSendMsg(fd, chan, 8, 0, v); return; } if ((offset = 22 + c) > 24) offset = 25; switch(v) { case 0: /* * Ramp off, square off, tri on */ bristolMidiSendMsg(fd, chan, c, 4, 0); bristolMidiSendMsg(fd, chan, c, 6, 0); bristolMidiSendMsg(fd, chan, c, 5, 1); bristolMidiSendMsg(fd, chan, 126, offset, 0); break; case 1: bristolMidiSendMsg(fd, chan, c, 5, 0); bristolMidiSendMsg(fd, chan, c, 6, 0); bristolMidiSendMsg(fd, chan, c, 4, 1); bristolMidiSendMsg(fd, chan, 126, offset, 0); break; case 2: bristolMidiSendMsg(fd, chan, c, 4, 0); bristolMidiSendMsg(fd, chan, c, 5, 0); bristolMidiSendMsg(fd, chan, c, 6, 1); bristolMidiSendMsg(fd, chan, 126, offset, 1); break; case 3: bristolMidiSendMsg(fd, chan, c, 4, 0); bristolMidiSendMsg(fd, chan, c, 5, 0); bristolMidiSendMsg(fd, chan, c, 6, 1); bristolMidiSendMsg(fd, chan, 126, offset, 0); break; } } static int polyMode(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; if (c == 52) { bristolMidiSendMsg(global.controlfd, synth->sid, 126, o, v); return(0); } if (synth->flags & MEM_LOADING) return(0); if (synth->dispatch[RADIOSET_3].other2) return(synth->dispatch[RADIOSET_3].other2 = 0); if (synth->dispatch[RADIOSET_3].other1 != -1) { synth->dispatch[RADIOSET_3].other2 = 1; if (synth->dispatch[RADIOSET_3].other1 != c) event.value = 0; else event.value = 1; brightonParamChange(synth->win, synth->panel, synth->dispatch[RADIOSET_3].other1, &event); } synth->dispatch[RADIOSET_3].other1 = c; bristolMidiSendMsg(global.controlfd, synth->sid, 126, o, v); return(0); } static void polyMemory(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; /* printf(" polyMemory(B: %i L %i: %i, %i)\n", */ /* synth->bank, synth->location, c, o); */ switch(c) { case 0: saveMemory(synth, "mono", 0, synth->bank + synth->location, FIRST_DEV); return; break; case 15: loadMemory(synth, "mono", 0, synth->bank + synth->location, synth->mem.active, FIRST_DEV, 0); fixModes(synth); return; break; case 1: case 2: case 3: case 4: case 5: case 6: case 7: if (synth->dispatch[RADIOSET_1].other2) { synth->dispatch[RADIOSET_1].other2 = 0; return; } if (synth->dispatch[RADIOSET_1].other1 != -1) { synth->dispatch[RADIOSET_1].other2 = 1; if (synth->dispatch[RADIOSET_1].other1 != c) event.value = 0; else event.value = 1; brightonParamChange(synth->win, synth->panel, synth->dispatch[RADIOSET_1].other1 + MEM_START, &event); } synth->dispatch[RADIOSET_1].other1 = c; synth->bank = c * 10; break; case 8: case 9: case 10: case 11: case 12: case 13: case 14: if (synth->dispatch[RADIOSET_2].other2) { synth->dispatch[RADIOSET_2].other2 = 0; return; } if (synth->dispatch[RADIOSET_2].other1 != -1) { synth->dispatch[RADIOSET_2].other2 = 1; if (synth->dispatch[RADIOSET_2].other1 != c) event.value = 0; else event.value = 1; brightonParamChange(synth->win, synth->panel, synth->dispatch[RADIOSET_2].other1 + MEM_START, &event); } synth->dispatch[RADIOSET_2].other1 = c; /* Do radio buttons */ synth->location = c - 7; break; } } static void polyEffect(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; /* * If we are turning this on the the original would also force MONO mode * so we should do the same. */ if (v != 0) { event.value = 1; brightonParamChange(synth->win, synth->panel, 53, &event); } bristolMidiSendMsg(fd, chan, c, o, v); } static void polyMidi(guiSynth *synth, int fd, int chan, int c, int o, int v) { int newchan; if ((synth->flags & OPERATIONAL) == 0) return; if (c == 1) { if ((newchan = synth->midichannel - 1) < 0) { synth->midichannel = 0; return; } } else { if ((newchan = synth->midichannel + 1) >= 16) { synth->midichannel = 15; return; } } if (global.libtest == 0) { /* #warning if we do not check for ack then socket might hang on exit * To overcome that we should consider checking a sequence number in * the message library? That is non trivial since it requires that * our midi messges have a 'ack' flag included - we cannot check for * ack here (actually, we could, and in the app is probably the right * place to do it rather than the lib however both would have to be * changed to suppor this - nc). */ bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_MIDICHANNEL|newchan); } synth->midichannel = newchan; } /* * For the sake of ease of use, links have been placed here to be called * by any of the devices created. They would be better in some other file, * perhaps with this as a dispatch. * * Param refers to the device index in the locations table given below. */ static int polyCallback(brightonWindow * win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); int sendvalue; /*printf("polyCallback(%i, %f): %x\n", index, value, synth); */ if (synth == 0) return(0); if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0)) return(0); if (polyApp.resources[0].devlocn[index].to == 1.0) sendvalue = value * (CONTROLLER_RANGE - 1); else sendvalue = value; synth->mem.param[index] = value; if ((!global.libtest) || (index >= ACTIVE_DEVS)) synth->dispatch[index].routine(synth, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #ifdef DEBUG else printf("dispatch[%x,%i](%i, %i, %i, %i, %i)\n", synth, index, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #endif return(0); } /* * Any location initialisation required to run the callbacks. For bristol, this * will connect to the engine, and give it some base parameters. * May need to generate some application specific menus. * Will also then make specific requests to some of the devices to alter their * rendering. */ static int polyInit(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); dispatcher *dispatch; int i; if (synth == 0) { synth = findSynth(global.synths, (int) 0); if (synth == 0) { printf("cannot init\n"); return(0); } } synth->win = win; if ((initmem = synth->location) == 0) initmem = 11; printf("Initialise the poly link to bristol: %p\n", synth->win); synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float)); synth->mem.count = DEVICE_COUNT; synth->mem.active = ACTIVE_DEVS; synth->dispatch = (dispatcher *) brightonmalloc(DEVICE_COUNT * sizeof(dispatcher)); dispatch = synth->dispatch; /* * We really want to have three connection mechanisms. These should be * 1. Unix named sockets. * 2. UDP sockets. * 3. MIDI pipe. */ if (!global.libtest) { synth->voices = 1; if ((synth->sid = initConnection(&global, synth)) < 0) return(-1); } for (i = 0; i < DEVICE_COUNT; i++) { synth->dispatch[i].routine = polyMidiSendMsg; } /* Osc-1 Waveform is a compound operator */ dispatch[0].controller = 0; dispatch[0].operator = 0; dispatch[0].routine = (synthRoutine) polyWaveform; dispatch[1].controller = 0; dispatch[1].operator = 1; dispatch[2].controller = 126; dispatch[2].operator = 30; /* Osc-2 Waveform is a compound operator */ dispatch[3].controller = 1; dispatch[3].operator = 10; dispatch[4].controller = 1; dispatch[4].operator = 0; dispatch[4].routine = (synthRoutine) polyWaveform; dispatch[5].controller = 1; dispatch[5].operator = 1; dispatch[6].controller = 126; dispatch[6].operator = 31; /* Osc-3 Waveform is a compound operator */ dispatch[7].controller = 2; dispatch[7].operator = 10; dispatch[8].controller = 2; dispatch[8].operator = 0; dispatch[8].routine = (synthRoutine) polyWaveform; dispatch[9].controller = 2; dispatch[9].operator = 1; dispatch[10].controller = 126; dispatch[10].operator = 32; /* Osc-4 Waveform is a compound operator and different operator.... */ dispatch[11].controller = 8; dispatch[11].operator = 10; dispatch[12].controller = 8; dispatch[12].operator = 0; dispatch[12].routine = (synthRoutine) polyWaveform; dispatch[13].controller = 8; dispatch[13].operator = 1; dispatch[14].controller = 126; dispatch[14].operator = 33; /* Filter */ dispatch[15].controller = 4; dispatch[15].operator = 0; dispatch[16].controller = 4; dispatch[16].operator = 1; dispatch[17].controller = 4; dispatch[17].operator = 2; dispatch[18].controller = 4; dispatch[18].operator = 3; /* Filter Env */ dispatch[19].controller = 3; dispatch[19].operator = 0; dispatch[20].controller = 3; dispatch[20].operator = 1; dispatch[21].controller = 3; dispatch[21].operator = 2; dispatch[22].controller = 3; dispatch[22].operator = 3; /* Env */ dispatch[23].controller = 5; dispatch[23].operator = 0; dispatch[24].controller = 5; dispatch[24].operator = 1; dispatch[25].controller = 5; dispatch[25].operator = 2; dispatch[26].controller = 5; dispatch[26].operator = 3; /* Env gain */ dispatch[27].controller = 5; dispatch[27].operator = 4; /* This switch reassigned to arpeggiator direction, was for headphone output */ dispatch[28].controller = 126; dispatch[28].operator = 28; /* LFO frequencies */ dispatch[29].controller = 9; dispatch[29].operator = 0; dispatch[30].controller = 126; dispatch[30].operator = 3; dispatch[31].controller = 10; dispatch[31].operator = 0; /* Needs a dispatcher since it has dual operation - arpeg and LFO2 */ dispatch[31].routine = (synthRoutine) polyMG2; /* PWM */ dispatch[32].controller = 126; dispatch[32].operator = 4; dispatch[33].controller = 126; dispatch[33].operator = 5; /* PW */ dispatch[34].controller = 34; dispatch[34].operator = 34; dispatch[34].routine = (synthRoutine) polyWaveform; /* Modulators 35 though 39 NOT DONE */ dispatch[35].controller = 126; dispatch[35].operator = 6; dispatch[36].controller = 126; dispatch[36].operator = 7; dispatch[37].controller = 126; dispatch[37].operator = 8; dispatch[38].controller = 126; dispatch[38].operator = 9; dispatch[39].controller = 126; dispatch[39].operator = 10; /* dispatch[35].routine = dispatch[36].routine = dispatch[37].routine = */ /* dispatch[38].routine = dispatch[39].routine = (synthRoutine) polyEffect; */ /* Glide */ dispatch[40].controller = 126; dispatch[40].operator = 0; /* Detune. */ dispatch[41].controller = 126; dispatch[41].operator = 11; /* Transpose */ dispatch[42].controller = 0; dispatch[42].operator = 0; dispatch[42].routine = (synthRoutine) polyTranspose; /* Noise level */ dispatch[43].controller = 7; dispatch[43].operator = 0; /* Trigger */ dispatch[44].controller = 126; dispatch[44].operator = 12; /* Damp */ dispatch[45].controller = 126; dispatch[45].operator = 13; /* Effects NOT DONE */ dispatch[46].controller = 126; dispatch[46].operator = 14; dispatch[46].routine = (synthRoutine) polyEffect; /* Global tune */ dispatch[47].controller = 126; dispatch[47].operator = 2; /* MG1 */ dispatch[48].controller = 126; dispatch[48].operator = 15; dispatch[49].controller = 126; dispatch[49].operator = 16; /* MG2 */ dispatch[50].controller = 126; dispatch[50].operator = 17; dispatch[51].controller = 126; dispatch[51].operator = 18; /* * Hold * * Mono - two button * * Poly - two buttons * * Propose * Mono - fat synth = UNISON * Poly - 4 voice thin synth * Share: * One key all voices (fat synth) * Key keys two notes each (2VCO synth) * Three or more, one note each (thin synth). */ dispatch[52].controller = 52; dispatch[52].operator = 27; dispatch[53].controller = 53; dispatch[53].operator = 19; dispatch[54].controller = 54; /* Does not do anything = Unison off */ dispatch[54].operator = 20; dispatch[55].controller = 55; dispatch[55].operator = 21; dispatch[52].routine = dispatch[53].routine = dispatch[54].routine = dispatch[55].routine = (synthRoutine) polyMode; dispatch[56].controller = 0; dispatch[57].controller = 1; dispatch[58].controller = 2; dispatch[59].controller = 3; dispatch[60].controller = 4; dispatch[61].controller = 5; dispatch[62].controller = 6; dispatch[63].controller = 7; dispatch[64].controller = 8; dispatch[65].controller = 9; dispatch[66].controller = 10; dispatch[67].controller = 11; dispatch[68].controller = 12; dispatch[69].controller = 13; dispatch[70].controller = 14; dispatch[71].controller = 15; dispatch[56].routine = dispatch[57].routine = dispatch[58].routine = dispatch[59].routine = dispatch[60].routine = dispatch[61].routine = dispatch[62].routine = dispatch[63].routine = dispatch[64].routine = dispatch[65].routine = dispatch[66].routine = dispatch[67].routine = dispatch[68].routine = dispatch[69].routine = dispatch[70].routine = dispatch[71].routine = (synthRoutine) polyMemory; dispatch[RADIOSET_1].other1 = -1; dispatch[RADIOSET_2].other1 = -1; dispatch[RADIOSET_3].other1 = -1; dispatch[72].controller = 1; dispatch[73].controller = 2; dispatch[72].routine = dispatch[73].routine = (synthRoutine) polyMidi; /* Tune osc-1 bristolMidiSendMsg(global.controlfd, synth->sid, 0, 10, 8192); */ /* * We put all the osc on SYNC/MAXgain, but manipulate the sync buffer in the * engine. */ bristolMidiSendMsg(global.controlfd, synth->sid, 0, 7, 8192); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 7, 8192); bristolMidiSendMsg(global.controlfd, synth->sid, 2, 7, 8192); bristolMidiSendMsg(global.controlfd, synth->sid, 8, 7, 8192); bristolMidiSendMsg(global.controlfd, synth->sid, 4, 4, 4); bristolMidiSendMsg(global.controlfd, synth->sid, 0, 3, C_RANGE_MIN_1); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 3, C_RANGE_MIN_1); bristolMidiSendMsg(global.controlfd, synth->sid, 2, 3, C_RANGE_MIN_1); bristolMidiSendMsg(global.controlfd, synth->sid, 8, 3, C_RANGE_MIN_1); /* Gain on filter contour */ bristolMidiSendMsg(global.controlfd, synth->sid, 3, 4, C_RANGE_MIN_1); /* LFO Options */ bristolMidiSendMsg(global.controlfd, synth->sid, 10, 2, 8192); return(0); } /* * This will be called to make any routine specific parameters available. */ static int polyConfigure(brightonWindow* win) { guiSynth *synth = findSynth(global.synths, win); brightonEvent event; if (synth == 0) { printf("problems going operational\n"); return(-1); } if (synth->flags & OPERATIONAL) return(0); printf("going operational\n"); synth->flags |= OPERATIONAL; synth->keypanel = 1; synth->keypanel2 = -1; synth->transpose = 36; if (synth->location == 0) { synth->bank = 1; synth->location = 1; } event.value = 1; brightonParamChange(synth->win, synth->panel, MEM_START + 1, &event); brightonParamChange(synth->win, synth->panel, MEM_START + 8, &event); loadMemory(synth, "mono", 0, initmem, synth->mem.active, FIRST_DEV, 0); fixModes(synth); brightonPut(win, "bitmaps/blueprints/monoshade.xpm", 0, 0, win->width, win->height); width = win->width; /* * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only * occurs on first paint, so we suppress the first paint, and then request * an expose here. */ event.type = BRIGHTON_EXPOSE; event.intvalue = 1; brightonParamChange(synth->win, KEY_PANEL, -1, &event); /* * Touch a key on/off */ bristolMidiSendMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_KEYON, 0, 10 + synth->transpose); bristolMidiSendMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_KEYOFF, 0, 10 + synth->transpose); configureGlobals(synth); synth->loadMemory = (loadRoutine) ploadMemory; return(0); } bristol-0.60.11/brighton/brightonreadme.h0000644000175000017500000057341211746476475015276 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ char *readmeheader = "Bristol Emulations\n\ ------------------\n\ \n\ This is a write-up of each of the emulated synthesisers. The algorithms\n\ employed were 'gleaned' from a variety of sources including the original\n\ owners manuals, so they may be a better source of information. The author\n\ has owned and used a selection but far from all of the originals. Some of them\n\ were built just from descriptions of their operation, or from understanding\n\ how synths work - most of them were based on the Mini Moog anyway. Many of\n\ the synths share components: the filter covers most of them, the Prophets and\n\ Oberheims share a common oscillator and the same LFO is used in many of them.\n\ Having said that each one differs considerably in the resulting sound that is\n\ generated, more so than initially expected. Each release refines each of the\n\ components and the result is that all emulations benefit from the improvements.\n\ All the emulations have distinctive sounds, not least due to that the original\n\ instruments used different modulations and mod routing.\n\ The filter, which is a large defining factor in the tonal qualities of any\n\ synth, is common to all the emulations. The filter implements a few different \n\ algorithms and these do separate each of the synths: the Explorer layering\n\ two low pass filters on top of each other: the OB-Xa using different types\n\ depending on 'Pole' selection. Since release 0.20.8 the emulator has had a\n\ Houvillainen non-linear ladder filter integrated which massively improves \n\ the quality at considerable expense to the CPU.\n\ There is one further filter algorithm used solely for the Leslie rotary \n\ emulator crossover, this is a butterworth type filter.\n\ \n\ Bristol is in no way related to any of the original manufacturers whose \n\ products are emulated by the engine and represented by the user interface,\n\ bristol does not suggest that the emulation is a like representation of the\n\ original instrument, and the author maintains that if you want the original\n\ sound then you are advised to seek out the original product. Alternatively a\n\ number of the original manufacturers now provide their own vintage collections\n\ which are anticipated to be more authentic. All names and trademarks used by\n\ Bristol are ownership of the respective companies and it is not inteded to \n\ misappropriate their use here. If you have concerns you are kindly requested\n\ to contact the author.\n\ \n\ The write-up includes the parameter operations, modulations, a description of\n\ the original instrument and a brief list of the kind of sounds you can expect\n\ by describing a few of the well known users of the synth.\n\ \n\ Several emulations have not been written up. Since the APR 2600 was implemented\n\ it became a rather large job to actually describe what was going on. If you \n\ really want to know about the synths that are not in this document then you\n\ might want to search for their owners manuals.\n\ \n\ All emulations are available from the same engine, just launch multiple GUIs\n\ and adjust the midi channels for multi timbrality and layering.\n\ \n\ It is noted here that the engine is relatively 'dumb'. Ok, it generates a very\n\ broad range of sounds, currently about 25 different synthesisers and organs,\n\ but it is not really intelligent. Memories are a part of the GUI specification\n\ - it tells the engine which algorithm to use on which MIDI channel, then it\n\ calls a memory routine that configures all the GUI controllers and a side effect\n\ of setting the controllers is that their values are sent to the engine. This is\n\ arguably the correct model but it can affect the use of MIDI master keyboards.\n\ The reason is that the GUI is really just a master keyboard for the engine and\n\ drives it with MIDI SYSEX messages over TCP sessions. If you were to alter the\n\ keyboard transpose, for example, this would result in the GUI sending different\n\ 'key' numbers to the engine when you press a note. If you were already driving\n\ the synth from a master keyboard then the transpose button in the Brighton GUI\n\ would have no effect - the master keyboard would have to be transposed instead.\n\ This apparent anomaly is exacerbated by the fact that some parameters still are\n\ in the engine, for example master tuning is in the engine for the pure fact that\n\ MIDI does not have a very good concept of master tuning (only autotuning).\n\ Irrespective of this, bristol is a synthesiser so it needs to be played, \n\ tweaked, driven. If you think that any of the behaviour is anomalous then let\n\ me know. One known issue in this area is that if you press a key, transpose\n\ the GUI, then release the key - it will not go off in the engine since the GUI\n\ sends a different key code for the note off event - the transposed key. This\n\ cannot be related to the original keypress. This could be fixed with a MIDI all\n\ notes off event on 'transpose', but I don't like them. Also, since the 0.20\n\ stream the problem only affects a few of the emulations, the rest now sending\n\ a transpose message to the engine and letting it do the work.\n\ \n\ Since release 0.30.6 the engine correctly implements monophonic note logic.\n\ Prior to this the whole engine was polyphonic and playing with one voice only\n\ gave last note preference which dramatically affects playing styles - none of\n\ the cool legato effects of the early monophonics. The quoted release fix this\n\ limitation where the engine will keep a keymap of all played keys (one per\n\ emulation) when started with a single voice and uses this map to provide\n\ consistent note precedence, high note logic, low note logic or just using the\n\ previously implemented last note logic. In this release the keymap was only\n\ maintained with monophonic emulations, this is a potential extension as even\n\ in polyphonic mode it would be useful for arpeggiation (which is currently\n\ implemented using a FIFO rather than an ordered keymap).\n\ \n"; char *readmetrailer = "For the sake of being complete, given below is the verbose help output\n\n"; char *readme[BRISTOL_SYNTHCOUNT] = { " Moog Mini\n\ ---------\n\ \n\ It is perhaps not possible to write up who used this synth, the list is endless.\n\ Popular as it was about the first non-modular synthesiser, built as a fixed\n\ configuration of the racked or modular predecessors.\n\ \n\ Best known at the time on Pink Floyd 'Dark Side of the Moon' and other albums.\n\ Rick Wakefield used it as did Jean Michel Jarre. Wakefield could actually\n\ predict the sound it would make by just looking at the settings, nice to be\n\ able to do if a little unproductive but it went to show how this was treated\n\ as an instrument in its own right. It takes a bit of work to get the same sweet,\n\ rich sounds out of the emulation, but it can be done with suitable tweaking.\n\ \n\ The original was monophonic, although a polyphonic version was eventually made\n\ after Moog sold the company - the MultiMoog. This emulation is more comparable\n\ to that model as the sound is a bit thinner and can be polyphonic. The design\n\ of this synth became the pole bearer for the following generations: it had \n\ three oscillators, one of which could become a low frequency modulator. They\n\ were fed into a mixer with a noise source, and were then fed into a filter\n\ with 2 envelope generators to contour the wave. Modulation capabilities were\n\ not extensive, but interestingly enough it did have a frequency modulation (FM)\n\ capability, eventually used by Yamaha to revolutionise the synthesiser market\n\ starting the downfall of analogue synthesis twenty years later.\n\ \n\ All the analogue synths were temperature sensitive. It was not unusual for the\n\ synths to 'detune' between sound test and performance as the evening set in.\n\ To overcome this they could optionally produce a stable A-440Hz signal for \n\ tuning the oscillators manually - eventually being an automated option in the\n\ newer synths. Whilst this digital version has stable frequency generation the\n\ A-440 is still employed here for the sake of it.\n\ \n\ Modifiers and mod routing are relatively simple, Osc-3 and noise can be mixed,\n\ and this signal routed to the oscillator 1 and 2 frequency or filter cutoff.\n\ \n\ The synth had 5 main stages as follows:\n\ \n\ Control:\n\ \n\ Master tuning: up/down one note.\n\ \n\ Glide: (glissando, portamento). The rate at which one key will change its\n\ frequency to the next played key, 0 to 30 seconds.\n\ \n\ Mod: source changes between Osc-3 and noise.\n\ \n\ Release: The envelope generators had only 3 parameters. This governed whether\n\ a key would release immediately or would use Decay to die out.\n\ \n\ Multi: Controls whether the envelope will retrigger for each new keypress.\n\ \n\ Oscillators:\n\ \n\ There are three oscillators. One and two are keyboard tracking, the third\n\ can be decoupled and used as an LFO modulation source.\n\ \n\ Oscillator 1:\n\ Octave step from 32' to 1'.\n\ Waveform selection: sine/square/pulse/ramp/tri/splitramp\n\ Mod: controls whether Osc-3/noise modulates frequency\n\ \n\ Oscillator 2:\n\ Octave step from 32' to 1'.\n\ Fine tune up/down 7 half notes.\n\ Waveform selection: sine/square/pulse/ramp/tri/splitramp\n\ Mod: controls whether Osc-3/noise modulates frequency\n\ \n\ Oscillator 3:\n\ Octave step from 32' to 1'.\n\ Fine tune up/down 7 half notes.\n\ Waveform selection: sine/square/pulse/ramp/tri/splitramp\n\ LFO switch to decouple from keytracking.\n\ \n\ Mixer:\n\ \n\ Gain levels for Oscillator 1/2/3\n\ Mixing of the external input source into filter\n\ Noise source with white/pink switch.\n\ \n\ Note: The level at which Osc-3 and noise modulates sound depends on its\n\ gain here, similarly the noise. The modulator mix also affects this, but\n\ allows Osc-3 to mod as well as sound. The modwheel also affect depth.\n\ \n\ Filter:\n\ \n\ Cutoff frequency\n\ \n\ Emphasis (affects Q and resonance of filter).\n\ \n\ Contour: defines how much the filter envelope affects cutoff.\n\ \n\ Mod - Keyboard tracking of cutoff frequency.\n\ \n\ Mod - Osc-3/noise modulation of cutoff frequency.\n\ \n\ Contour:\n\ \n\ The synth had two envelope generators, one for the filter and one for the\n\ amplifier. Release is affected by the release switch. If off the the sound\n\ will release at the rate of the decay control.\n\ \n\ Attack: initial ramp up of gain.\n\ \n\ Decay: fall off of maximum signal down to:\n\ \n\ Sustain: gain level for constant key-on level.\n\ \n\ Key: Touch sensitivity of amplifier envelope.\n\ \n\ Improvements to the Mini would be some better oscillator waveforms, plus an\n\ alternative filter as this is a relatively simple synthesiser and could do\n\ with a warmer filter (this was fixed with integration of the houvillanen filters\n\ although the do consume a lot of CPU to do it).\n\ \n\ The Output selection has a Midi channel up/down selector and memory selector.\n\ To read a memory either use the up/down arrows to go to the next available\n\ memory, or type in a 3 digit number on the telephone keypad and press 'L' for\n\ load or 'S' for save.\n\ \n\ As of release 0.20.5 Vasiliy Basic contributed his Mini memory banks and they\n\ are now a part of the distribution:\n\ \n\ Programs for Bristol's \"Mini\" (from 50 to 86 PRG)\n\ \n\ List of programs:\n\ \n\ -Melodic-\n\ 50 - Trumpet\n\ 51 - Cello\n\ 52 - Guitar 1\n\ 53 - Guitar 2\n\ 54 - Fingered Bass\n\ 55 - Picked Bass\n\ 56 - Harmonica\n\ 57 - Accordion\n\ 58 - Tango Accordion\n\ 59 - Super Accordion\n\ 60 - Piano\n\ 61 - Dark Organ\n\ 62 - Flute\n\ 63 - Music Box\n\ 64 - Glass Xylo\n\ 65 - Glass Pad\n\ 66 - Acid Bass\n\ \n\ -Drums-\n\ 67 - Bass Drum 1 \n\ 68 - Bass Drum 2\n\ 69 - Bass Drum 3\n\ 70 - Bass Drum 4\n\ 71 - Tom\n\ 72 - Snare 1\n\ 73 - Snare 2\n\ 74 - Snare 3\n\ 75 - Snare 4\n\ 76 - Cl HH 1\n\ 77 - Op HH 1\n\ 78 - Crash Cym 1\n\ 79 - Crash Cym 2\n\ 80 - Cl HH 2\n\ 81 - Op HH 2\n\ \n\ -FX-\n\ 82 - Sea Shore\n\ 83 - Helicopter 1\n\ 84 - Helicopter 2\n\ 85 - Bird Tweet\n\ 86 - Birds Tweet\n\n", NULL, " Sequential Circuits Prophet-5\n\ Sequential Circuits Prophet-52 (the '5' with chorus)\n\ ----------------------------------------------------\n\ \n\ Sequential circuits released amongst the first truly polyphonic synthesisers\n\ where a group of voice circuits (5 in this case) were linked to an onboard\n\ computer that gave the same parameters to each voice and drove the notes to\n\ each voice from the keyboard. The device had some limited memories to allow \n\ for real live stage work. The synth was amazingly flexible regaring the\n\ oscillator options and modulation routing, producing some of the fattest \n\ sounds around. They also had some of the fattest pricing as well, putting it\n\ out of reach of all but the select few, something that maintained its mythical\n\ status. David Sylvian of Duran Duran used the synth to wide acclaim in the\n\ early 80's as did many of the new wave of bands.\n\ \n\ The -52 is the same as the -5 with the addition of a chorus as it was easy, it\n\ turns the synth stereo for more width to the sound, and others have done it on\n\ the Win platform.\n\ \n\ The design of the Prophet synthesisers follows that of the Mini Moog. It has\n\ three oscillators one of them as a dedicated LFO. The second audio oscillator\n\ can also function as a second LFO, and can cross modulate oscillator A for FM \n\ type effects. The audible oscillators have fixed waveforms with pulse width\n\ modulation of the square wave. These are then mixed and sent to the filter with\n\ two envelopes, for the filter and amplifier.\n\ \n\ Modulation bussing is quite rich. There is the wheel modulation which is global,\n\ taking the LFO and Noise as a mixed source, and send it under wheel control to\n\ any of the oscillator frequency and pulse width, plus the filter cutoff. Poly\n\ mods take two sources, the filter envelope and Osc-B output (which are fully\n\ polyphonic, or rather, independent per voice), and can route them through to\n\ Osc-A frequency and Pulse Width, or through to the filter. To get the filter\n\ envelope to actually affect the filter it needs to go through the PolyMod\n\ section. Directing the filter envelope to the PW of Osc-A can make wide, breathy\n\ scanning effects, and when applied to the frequency can give portamento effects.\n\ \n\ LFO:\n\ \n\ Frequency: 0.1 to 50 Hz\n\ Shape: Ramp/Triangle/Square. All can be selected, none selected should\n\ give a sine wave (*)\n\ \n\ (*) Not yet implemented.\n\ \n\ Wheel Mod:\n\ \n\ Mix: LFO/Noise\n\ Dest: Osc-A Freq/Osc-B Freq/Osc-A PW/Osc-B PW/Filter Cutoff\n\ \n\ Poly Mod: These are affected by key velocity.\n\ \n\ Filter Env: Amount of filter envelope applied\n\ Osc-B: Amount of Osc-B applied:\n\ Dest: Osc-A Freq/Osc-A PW/Filter Cutoff\n\ \n\ Osc-A:\n\ \n\ Freq: 32' to 1' in octave steps\n\ Shape: Ramp or Square\n\ Pulse Width: only when Square is active.\n\ Sync: synchronise to Osc-B\n\ \n\ Osc-B:\n\ \n\ Freq: 32' to 1' in octave steps\n\ Fine: +/- 7 semitones\n\ Shape: Ramp/Triangle/Square\n\ Pulse Width: only when Square is active.\n\ LFO: Lowers frequency by 'several' octaves.\n\ KBD: enable/disable keyboard tracking.\n\ \n\ Mixer:\n\ \n\ Gain for Osc-A, Osc-B, Noise\n\ \n\ Filter:\n\ \n\ Cutoff: cuttof frequency\n\ Res: Resonance/Q/Emphasis\n\ Env: amount of PolyMod affecting to cutoff.\n\ \n\ Envelopes: One each for PolyMod (filter) and amplifier.\n\ \n\ Attack\n\ Decay\n\ Sustain\n\ Release\n\ \n\ Global:\n\ \n\ Master Volume\n\ A440 - stable sine wave at A440 Hz for tuning.\n\ Midi: channel up/down\n\ Release: release all notes\n\ Tune: autotune oscillators.\n\ Glide: amount of portamento\n\ \n\ Unison: gang all voices to a single 'fat' monophonic synthesiser.\n\ \n\ This is one of the fatter of the Bristol synths and the design of the mods\n\ is impressive (not my design, this is as per sequential circuits spec). Some\n\ of the cross modulations are noisy, notably 'Osc-B->Freq Osc-A' for square\n\ waves as dest and worse as source.\n\ \n\ The chorus used by the Prophet-52 is a stereo 'Dimension-D' type effect. The\n\ signal is panned from left to right at one rate, and the phasing and depth at\n\ a separate rate to generate subtle chorus through to helicopter flanging.\n\ \n\ Memories are loaded by selecting the 'Bank' button and typing in a two digit\n\ bank number followed by load. Once the bank has been selected then 8 memories\n\ from the bank can be loaded by pressing another memory select and pressing\n\ load. The display will show free memories (FRE) or programmed (PRG).\n\ \n", " Yamaha DX-7\n\ -----------\n\ \n\ Released in the '80s this synth quickly became the most popular of all time.\n\ It was the first fully digital synth, employed a revolutionary frequency \n\ modulated algorithm and was priced much lower than the analogue monsters\n\ that preceded it. Philip Glass used it to wide effect for Miami Vice, Prince\n\ had it on many of his albums, Howard Jones produced albums filled with its\n\ library sounds. The whole of the 80's were loaded with this synth, almost to\n\ the point of saturation. There was generally wide use of its library sounds\n\ due to the fact that it was nigh on impossible to programme, only having entry\n\ buttons and the algorithm itself was not exactly intuitive, but also because\n\ the library was exceptional and the voices very playable. The emulation is a\n\ 6 operator per voice, and all the parameters are directly accessible to ease\n\ programming.\n\ \n\ The original DX had six operators although cheaper models were release with\n\ just 4 operators and a consequently thinner sound. Each operator is a sine\n\ wave oscillator with its own envelope generator for amplification and a few \n\ parameters that adjusted its modulators. It used a number of different \n\ algorithms where operators were mixed together and then used to adjust the\n\ frequency of the next set of operators. The sequence of the operators affected\n\ the net harmonics of the overall sound. Each operator has a seven stage \n\ envelope - 'ramp' to 'level 1', 'ramp' to 'level 2', 'decay' to 'sustain',\n\ and finally 'release' when a key is released. The input gain to the frequency\n\ modulation is controllable, the output gain is also adjustable, and the final\n\ stage operators can be panned left and right.\n\ \n\ Each operator has:\n\ \n\ Envelope:\n\ \n\ Attack: Ramp rate to L1\n\ L1: First target gain level\n\ Attack: Ramp rate from L2 to L2\n\ L2: Second target gain level\n\ Decay: Ramp rate to sustain level\n\ Sustain: Continuous gain level\n\ Release: Key release ramp rate\n\ \n\ Tuning:\n\ \n\ Tune: +/- 7 semitones\n\ Transpose: 32' to 1' in octave increments\n\ \n\ LFO: Low frequency oscillation with no keyboard control\n\ \n\ Gain controls:\n\ \n\ Touch: Velocity sensitivity of operator.\n\ \n\ In gain: Amount of frequency modulation from input\n\ Out gain: Output signal level\n\ \n\ IGC: Input gain under Mod control\n\ OGC: Output gain under Mod control\n\ \n\ Pan: L/R pan of final stage operators.\n\ \n\ Global and Algorithms:\n\ \n\ 24 different operator staging algorithms\n\ Pitchwheel: Depth of pitch modifier\n\ Glide: Polyphonic portamento\n\ Volume\n\ Tune: Autotune all operators\n\ \n\ Memories can be selected with either submitting a 3 digit number on the keypad,\n\ or selecting the orange up/down buttons.\n\ \n\ An improvement could be more preset memories with different sounds that can\n\ then be modified, ie, more library sounds. There are some improvements that\n\ could be made to polyphonic mods from key velocity and channel/poly pressure\n\ that would not be difficult to implement.\n\ \n\ The addition of triangle of other complex waveforms could be a fun development\n\ effort (if anyone were to want to do it).\n\ \n\ The DX still has a prependancy to seg fault, especially when large gains are\n\ applied to input signals. This is due to loose bounds checking that will be\n\ extended in a present release.\n\ \n", " Roland Juno-60\n\ --------------\n\ \n\ Roland was one of the main pacemakers in analogue synthesis, also competing\n\ with the Sequential and Oberheim products. They did anticipate the moving\n\ market and produced the Juno-6 relatively early. This was one of the first\n\ accessible synths, having a reasonably fat analogue sound without the price\n\ card of the monster predecessors. It brought synthesis to the mass market that\n\ marked the decline of Sequential Circuits and Oberheim who continued to make\n\ their products bigger and fatter. The reduced price tag meant it had a slightly\n\ thinner sound, and a chorus was added to extend this, to be a little more\n\ comparable.\n\ \n\ The synth again follows the Mini Moog design of oscillators into filter into\n\ amp. The single oscillator is fattened out with harmonics and pulse width\n\ modulation. There is only one envelope generator that can apply to both the\n\ filter and amplifier.\n\ \n\ Control:\n\ \n\ DCO: Amount of pitch wheel that is applied to the oscillators frequency.\n\ VCF: Amount of pitch wheel that is applied to the filter frequency.\n\ \n\ Tune: Master tuning of instrument\n\ \n\ Glide: length of portamento\n\ \n\ LFO: Manual control for start of LFO operation.\n\ \n\ Hold: (*)\n\ \n\ Transpose: Up/Down one octave\n\ Hold: prevent key off events\n\ \n\ LFO:\n\ \n\ Rate: Frequency of LFO\n\ Delay: Period before LFO is activated\n\ Man/Auto: Manual or Automatic cut in of LFO\n\ \n\ DCO:\n\ \n\ LFO: Amount of LFO affecting frequency. Affected by mod wheel.\n\ PWM: Amount of LFO affecting PWM. Affected by mod wheel.\n\ \n\ ENV/LFO/MANUAL: Modulator for PWM\n\ \n\ Waveform:\n\ Pulse or Ramp wave. Pulse has PWM capabily.\n\ \n\ Sub oscillator:\n\ On/Off first fundamental square wave.\n\ \n\ Sub:\n\ Mixer for fundamental\n\ \n\ Noise:\n\ Mixer of white noise source.\n\ \n\ HPF: High Pass Filter\n\ \n\ Freq:\n\ Frequency of cutoff.\n\ \n\ VCF:\n\ \n\ Freq:\n\ Cutoff frequency\n\ \n\ Res:\n\ Resonance/emphasis.\n\ \n\ Envelope:\n\ +ve/-ve application\n\ \n\ Env:\n\ Amount of contour applied to cutoff\n\ \n\ LFO:\n\ Depth of LFO modulation applied.\n\ \n\ KBD:\n\ Amount of key tracking applied.\n\ \n\ VCA:\n\ \n\ Env/Gate:\n\ Contour is either gated or modulated by ADSR\n\ \n\ Level:\n\ Overall volume\n\ \n\ ADSR:\n\ \n\ Attack\n\ Decay\n\ Sustain\n\ Release\n\ \n\ Chorus:\n\ \n\ 8 Selectable levels of Dimension-D type helicopter flanger.\n\ \n\ * The original instrument had a basic sequencer on board for arpeggio effects\n\ on each key. In fact, so did the Prophet-10 and Oberheims. This was only \n\ implemented in 0.10.11.\n\ \n\ The LFO cut in and gain is adjusted by a timer and envelope that it triggers.\n\ \n\ The Juno would improve from the use of the prophet DCO rather than its own one.\n\ It would require a second oscillator for the sub frequency, but the prophet DCO\n\ can do all the Juno does with better resampling and PWM generation.\n\ \n", " Moog Voyager (Bristol \"Explorer\")\n\ ---------------------------------\n\ \n\ This was Robert Moog's last synth, similar in build to the Mini but created\n\ over a quarter of a century later and having far, far more flexibility. It \n\ was still monophonic, a flashback to a legendary synth but also a bit like\n\ Bjorn Borg taking his wooden tennis racket back to Wimbledon long after having\n\ retired and carbon fibre having come to pass. I have no idea who uses it and\n\ Bjorn also crashed out in the first round. The modulation routing is exceptional\n\ if not exactly clear.\n\ \n\ The Voyager, or Bristol Explorer, is definitely a child of the Mini. It has\n\ the same fold up control panel, three and half octave keyboard and very much\n\ that same look and feel. It follows the same rough design of three oscillators\n\ mixed with noise into a filter with envelopes for the filter and amplifier.\n\ In contrast there is an extra 4th oscillator, a dedicated LFO bus also Osc-3\n\ can still function as a second LFO here. The waveforms are continuously \n\ selected, changing gradually to each form: bristol uses a form of morphing\n\ get get similar results. The envelopes are 4 stage rather than the 3 stage\n\ Mini, and the effects routing bears no comparison at all, being far more\n\ flexible here.\n\ \n\ Just because its funny to know, Robert Moog once stated that the most difficult\n\ part of building and releasing the Voyager was giving it the title 'Moog'. He\n\ had sold his company in the seventies and had to buy back the right to use his\n\ own name to release this synthesiser as a Moog, knowing that without that title\n\ it probably would not sell quite as well as it didn't.\n\ \n\ Control:\n\ \n\ LFO:\n\ Frequency\n\ Sync: LFO restarted with each keypress.\n\ \n\ Fine tune +/- one note\n\ Glide 0 to 30 seconds.\n\ \n\ Modulation Busses:\n\ \n\ Two busses are implemented. Both have similar capabilities but one is\n\ controlled by the mod wheel and the other is constantly on. Each bus has\n\ a selection of sources, shaping, destination selection and amount.\n\ \n\ Wheel Modulation: Depth is controller by mod wheel.\n\ \n\ Source: Triwave/Ramp/Sample&Hold/Osc-3/External\n\ Shape: Off/Key control/Envelope/On\n\ Dest: All Osc Frequency/Osc-2/Osc-3/Filter/FilterSpace/Waveform (*)\n\ Amount: 0 to 1.\n\ \n\ Constant Modulation: Can use Osc-3 as second LFO to fatten sound.\n\ \n\ Source: Triwave/Ramp/Sample&Hold/Osc-3/External\n\ Shape: Off/Key control/Envelope/On\n\ Dest: All Osc Frequency/Osc-2/Osc-3/Filter/FilterSpace/Waveform (*)\n\ Amount: 0 to 1.\n\ \n\ * Destination of filter is the cutoff frequency. Filter space is the \n\ difference in cutoff of the two layered filters. Waveform destination \n\ affects the continuously variable oscillator waveforms and allows for \n\ Pulse Width Modulation type effects with considerably more power since\n\ it can affect ramp to triangle for example, not just pulse width.\n\ \n\ Oscillators:\n\ \n\ Oscillator 1:\n\ Octave: 32' to 1' in octave steps\n\ Waveform: Continuous between Triangle/Ramp/Square/Pulse\n\ \n\ Oscillator 2:\n\ Tune: Continuous up/down 7 semitones.\n\ Octave: 32' to 1' in octave steps\n\ Waveform: Continuous between Triangle/Ramp/Square/Pulse\n\ \n\ Oscillator 3:\n\ Tune: Continuous up/down 7 semitones.\n\ Octave: 32' to 1' in octave steps\n\ Waveform: Continuous between Triangle/Ramp/Square/Pulse\n\ \n\ Sync: Synchronise Osc-2 to Osc-1\n\ FM: Osc-3 frequency modulates Osc-1\n\ KBD: Keyboard tracking Osc-3\n\ Freq: Osc-3 as second LFO\n\ \n\ Mixer:\n\ \n\ Gain levels for each source: Osc-1/2/3, noise and external input.\n\ \n\ Filters:\n\ \n\ There are two filters with different configuration modes:\n\ \n\ 1. Two parallel resonant lowpass filters.\n\ 2. Serialised HPF and resonant LPF\n\ \n\ Cutoff: Frequency of cutoff\n\ Space: Distance between the cutoff of the two filters.\n\ Resonance: emphasis/Q.\n\ KBD tracking amount\n\ Mode: Select between the two operating modes.\n\ \n\ Envelopes:\n\ \n\ Attack\n\ Decay\n\ Sustain\n\ Release\n\ \n\ Amount to filter (positive and negative control)\n\ \n\ Velocity sensitivity of amplifier envelope.\n\ \n\ Master:\n\ \n\ Volume\n\ LFO: Single LFO or one per voice (polyphonic operation).\n\ Glide: On/Off portamento\n\ Release: On/Off envelope release.\n\ \n\ The Explorer has a control wheel and a control pad. The central section has\n\ the memory section plus a panel that can modify any of the synth parameters as\n\ a real time control. Press the first mouse key here and move the mouse around\n\ to adjust the controls. Default values are LFO frequency and filter cutoff \n\ but values can be changed with the 'panel' button. This is done by selecting\n\ 'panel' rather than 'midi', and then using the up/down keys to select parameter\n\ that will be affected by the x and y motion of the mouse. At the moment the\n\ mod routing from the pad controller is not saved to the memories, and it will\n\ remain so since the pad controller is not exactly omnipresent on MIDI master\n\ keyboards - the capabilities was put into the GIU to be 'exact' to the design.\n\ \n\ This synth is amazingly flexible and difficult to advise on its best use. Try\n\ starting by mixing just oscillator 1 through to the filter, working on mod \n\ and filter options to enrich the sound, playing with the oscillator switches\n\ for different effects and then slowly mix in oscillator 2 and 3 as desired.\n\ \n\ Memories are available via two grey up/down selector buttons, or a three digit\n\ number can be entered. There are two rows of black buttons where the top row\n\ is 0 to 4 and the second is 5 to 9. When a memory is selected the LCD display\n\ will show whether it is is free (FRE) or programmed already (PRG).\n\ \n" , " Hammond B3 (dual manual)\n\ ------------------------\n\ \n\ The author first implemented the Hammond module, then extended it to the B3\n\ emulation. Users of this are too numerous to mention and the organ is still\n\ popular. Jimmy Smith, Screaming Jay Hawkins, Kieth Emerson, Doors and \n\ almost all american gospel blues. Smith was profuse, using the instrument for\n\ a jazz audience, even using its defects (key noise) to great effect. Emerson\n\ had two on stage, one to play and another to kick around, even including\n\ stabbing the keyboard with a knife to force keylock during performances\n\ (Emerson was also a Moog fan with some of the first live performances). He\n\ also used the defects of the system to great effect, giving life to the over-\n\ driven Hammond sound.\n\ \n\ The Hammond was historically a mechanical instrument although later cheaper\n\ models used electronics. The unit had a master motor that rotated at\n\ the speed of the mains supply. It drove a spindle of cog wheels and next to \n\ each cog was a pickup. The pickup output went into the matrix of the harmonic\n\ drawbars. It was originally devised to replace the massive pipe organs in\n\ churches - Hammond marketed their instruments with claims that they could not be\n\ differentiated from the mechanical pipe equivalent. He was taken to court by\n\ the US government for misrepresentation, finally winning his case using a double\n\ blind competitive test against a pipe organ, in a cathedral, with speakers\n\ mounted behind the organ pipes and an array of music scholars, students and \n\ professionals listening. The results spoke for themselves - students would\n\ have scored better by simply guessing which was which, the professionals\n\ fared only a little better than that. The age of the Hammond organ had arrived.\n\ \n\ The company had a love/hate relationship with the Leslie speaker company - the\n\ latter making money by selling their rotary speakers along with the organ to\n\ wide acceptance. The fat hammond 'chorus' was a failed attempt to distance\n\ themselves from Leslie. That was never achieved due to the acceptance of the\n\ Leslie, but the chorus did add another unique sound to the already awesome\n\ instrument. The rotary speaker itself still added an extra something to the\n\ unique sound that is difficult imagine one without the other. It has a wide\n\ range of operating modes most of which are included in this emulator.\n\ \n\ The chorus emulation is an 8 stage phase shifting filter algorithm with a \n\ linear rotor between the taps.\n\ \n\ Parameterisation of the first B3 window follows the original design:\n\ \n\ Leslie: Rotary speaker on/off\n\ Reverb: Reverb on/off\n\ VibraChorus: 3 levels of vibrato, 3 of chorus.\n\ Bright: Added upper harmonics to waveforms.\n\ \n\ Lower and Upper Manual Drawbars: The drawbars are colour coded into white for\n\ even harmonics and black for odd harmonics. There are two subfrequencies in \n\ brown. The number given here are the length of organ pipe that would \n\ correspond to the given desired frequency.\n\ \n\ 16 - Lower fundamental\n\ 5 1/3 - Lower 3rd fundamental\n\ 8 - Fundamental\n\ 4 - First even harmonic\n\ 2 2/3 - First odd harmonic\n\ 2 - Second even harmonic\n\ 1 3/5 - Second odd harmonic\n\ 1 1/3 - Third odd harmonic\n\ 1 - Third even harmonic\n\ \n\ The drawbars are effectively mixed for each note played. The method by which\n\ the mixing is done is controlled in the options section below. There were \n\ numerous anomalies shown by the instrument and most of them are emulated.\n\ \n\ The Hammond could provide percussives effect the first even and odd harmonics.\n\ This gave a piano like effect and is emulated with Attack/Decay envelope.\n\ \n\ Perc 4' - Apply percussive to the first even harmonic\n\ Perc 2 2/3' - Apply percussive to the first odd harmonic\n\ Slow - Adjust rate of decay from about 1/2 second to 4 seconds.\n\ \n\ Soft - Provide a soft attack to each note.\n\ \n\ The soft attack is an attempt to reduce the level of undesired key noise. The\n\ keyboard consisted of a metal bar under each key that made physical contact \n\ with 9 sprung teeth to tap off the harmonics. The initial contact would generate\n\ noise that did not really accord to the pipe organ comparison. This was \n\ reduced by adding a slow start to each key, but the jazz musicians had used\n\ this defect to great effect, terming it 'key click' and it became a part of\n\ the Hammond characteristics. Some musicians would even brag about how noisy\n\ there organ was.\n\ \n\ On the left had side are three more controls:\n\ \n\ Volume potentiometer\n\ \n\ Options switch discussed below.\n\ \n\ Rotary Speed: low/high speed Leslie rotation. Shifts between the speeds\n\ are suppressed to emulate the spin up and down periods of the leslie motors.\n\ \n\ The options section, under control of the options button, has the parameters\n\ used to control the emulation. These are broken into sections and discussed\n\ individually.\n\ \n\ Leslie:\n\ \n\ The Leslie rotary speaker consisted of a large cabinet with a bass speaker and\n\ a pair of high frequency air horns. Each were mounted on its own rotating table\n\ and driven around inside the cabinet by motors. A crossover filter was used to\n\ separate the frequencies driven to either speaker. Each pair was typically \n\ isolated physically from the other. As the speaker rotated it would generate\n\ chorus type effects, but far richer in quality. Depending on where the speaker\n\ was with respect to the listener the sound would also appear to rotate. There\n\ would be different phasing effects based on signal reflections, different\n\ filtering effects depending on where the speaker was in respect to the cabinet\n\ producing differences resonances with respect to the internal baffling.\n\ \n\ Separate:\n\ Sync:\n\ No Bass:\n\ The Leslie had two motors, one for the horns and one for the voice coil\n\ speaker. These rotated at different speeds. Some players preferred to \n\ have both rotate at the same speed, would remove the second motor and\n\ bind the spindles of each speaker table, this had the added effect\n\ that both would also spin up at the same rate, not true of the \n\ separated motors since each table had a very different rotary moment.\n\ The 'No Bass' option does not rotate the voice coil speaker. This was\n\ typically done since it would respond only slowly to speed changes,\n\ this left just the horns rotating but able to spin up and down faster.\n\ \n\ Brake:\n\ Some cabinets had a brake applied to the tables such that when the\n\ motor stopped the speakers slowed down faster.\n\ \n\ X-Over:\n\ This is the cross over frequency between the voice coil and air horns.\n\ Uses a butterworth filter design.\n\ \n\ Inertia:\n\ Rate at which speaker rotational speed will respond to changes.\n\ \n\ Overdrive:\n\ Amount by which the amplifier is overdriven into distortion.\n\ \n\ H-Depth/Frequency/Phase\n\ L-Depth/Frequency/Phase\n\ These parameters control the rotary phasing effect. The algorithm used\n\ has three differently phased rotations used for filtering, phasing and\n\ reverberation of the sound. These parameters are used to control the\n\ depth and general phasing of each of them, giving different parameters\n\ for the high and low speed rotations. There are no separate parameters\n\ for the voice coil or air horns, these parameters are for the two\n\ different speeds only, although in 'Separate' mode the two motors will\n\ rotate at slightly different speeds.\n\ \n\ Chorus\n\ \n\ V1/C1 - Lowest chorus speed\n\ V2/C2 - Medium chorus speed\n\ V3/C3 - High chorus speed\n\ \n\ Percussion:\n\ \n\ Decay Fast/Slow - controls the percussive delay rates.\n\ Attack Slow Fast - Controls the per note envelope attack time.\n\ \n\ The percussives are emulated as per the original design where there was a\n\ single envelope for the whole keyboard and not per note. The envelope will only\n\ restrike for a cleanly pressed note.\n\ \n\ Finally there are several parameters affecting the sine wave generation code.\n\ The Hammond used cogged wheels and coil pickups to generate all the harmonics,\n\ but the output was not a pure sine wave. This section primarily adjusts the\n\ waveform generation:\n\ \n\ Preacher:\n\ The emulator has two modes of operation, one is to generate the \n\ harmonics only for each keyed note and another to generate all of\n\ them and tap of those required for whatever keys have been pressed.\n\ Both work and have different net results. Firstly, generating each\n\ note independently is far more efficient than generating all 90 odd\n\ teeth, as only a few are typically required. This does not have totally\n\ linked phases between notes and cannot provide for signal damping (see\n\ below).\n\ The Preacher algorithm generates all harmonics continuously as per the\n\ original instrument. It is a better rendition at the expense of large\n\ chunks of CPU activity. This is discussed further below.\n\ \n\ Compress:\n\ Time compress the sine wave to produce a slightly sharper leading edge.\n\ \n\ Bright:\n\ Add additional high frequency harmonics to the sine.\n\ \n\ Click:\n\ Level of key click noise\n\ \n\ Reverb:\n\ Amount of reverb added by the Leslie\n\ \n\ Damping:\n\ If the same harmonic was reused by different pressed keys then its net\n\ volume would not be a complete sum, the output gain would decay as the\n\ pickups would become overloaded. This would dampen the signal strength.\n\ This is only available with the Preacher algorithm.\n\ \n\ The two reverse octaves are presets as per the original, however here they can\n\ just be used to recall the first 23 memories of the current bank. The lower\n\ manual 12 key is the 'save' key for the current settings and must be double\n\ clicked. It should be possible to drive these keys via MIDI, not currently \n\ tested though. The default presets are a mixture of settings, the lower \n\ manual being typical 'standard' recital settings, the upper manual being a\n\ mixture of Smith, Argent, Emerson, Winwood and other settings from the well\n\ known Hammond Leslie FAQ. You can overwrite them. As a slight anomaly, which\n\ was intentional, loading a memory from the these keys only adjusts the visible\n\ parameters - the drawbars, leslie, etc. The unseen ones in the options panel\n\ do not change. When you save a memory with a double click on the lower manual\n\ last reverse key then in contrast it saves all the parameters. This will not\n\ change.\n\ \n\ The Preacher algorithm supports a diverse set of options for its tonewheel\n\ emulation. These are configured in the file $BRISTOL/memory/profiles/tonewheel\n\ and there is only one copy. The file is a text file and will remain that way,\n\ it is reasonably documented in the file itself. Most settings have two ranges,\n\ one representing the normal setting and the other the bright setting for when\n\ the 'bright' button is pressed. The following settings are currently available:\n\ \n\ ToneNormal: each wheel can be given a waveform setting from 0 (square)\n\ through to 1.0 (pure sine) to X (sharpening ramp).\n\ \n\ EQNormal: each wheel can be given a gain level across the whole generator.\n\ \n\ DampNormal: each wheel has a damping factor (level robbing/damping/stealing)\n\ \n\ BusNormal: each drawbar can be equalised globally.\n\ \n\ \n\ ToneBright: each wheel can be given a waveform setting from 0 (square)\n\ through to 1.0 (pure sine) to X (sharpening ramp) for the bright button.\n\ \n\ EQBright: each wheel can be given a gain level across the whole generator.\n\ \n\ DampBright: each wheel has a damping factor (level robbing/damping/stealing)\n\ \n\ BusBright: each drawbar can be equalised globally.\n\ \n\ \n\ stops: default settings for the eight drawbar gain levels.\n\ \n\ The default is 8 linear stages.\n\ \n\ wheel: enables redefining the frequency and phase of any given tonewheel\n\ \n\ The defaults are the slightly non Even Tempered frequencies of the\n\ Hammond tonewheels. The tonewheel file redefines the top 6 frequencies\n\ that were slightly more out of tune due to the 192-teeth wheels and\n\ a different gear ratio.\n\ \n\ crosstalk: between wheels in a compartment and adjacent drawbar busses.\n\ \n\ This is one area that may need extensions for crosstalk in the wiring\n\ loom. Currently the level of crosstalk between each of the wheels in\n\ the compartment can be individually defined, and drawbar bus crosstalk\n\ also.\n\ \n\ compartment: table of the 24 tonewheel compartments and associated wheels.\n\ \n\ resistors: tapering resister definitions for equalisation of gains per\n\ wheel by note by drawbar.\n\ \n\ taper: definition of the drawbar taper damping resistor values.\n\ \n\ Improvements would come with some other alterations to the sine waveforms and\n\ some more EQ put into the leslie speaker. The speaker has three speeds, two of\n\ which are configurable and the third is 'stopped'. Changes between the different\n\ rates is controlled to emulate inertia.\n\ \n\ The net emulation, at least of the preacher algorithm, is reasonable, it is\n\ distinctively a Hammond sound although it does not have quite as much motor\n\ or spindle noise. The Bright button gives a somewhat rawer gearbox. It could do\n\ with a better amplifier emulation for overdrive.\n\ \n\ The damping algorithms is not quite correct, it has dependencies on which keys\n\ are pressed (upper/lower manual). Options drop shadow is taken from the wrong\n\ background bitmap so appears in an inconsistent grey.\n\ \n", " Vox Continental\n\ ---------------\n\ \n\ This emulates the original mark-1 Continental, popular in its time with the\n\ Animals on 'House of the Rising Sun', Doors on 'Light my Fire' and most of\n\ their other tracks. Manzarek did use Gibson later, and even played with the\n\ Hammond on their final album, 'LA Woman' but this organ in part defined\n\ the 60's sound and is still used by retro bands for that fact. The Damned\n\ used it in an early revival where Captain Sensible punched the keyboard\n\ wearing gloves to quite good effect. After that The Specials began the Mod/Ska\n\ revival using one. The sharp and strong harmonic content has the ability to\n\ cut into a mix and make its presence known.\n\ \n\ The organ was a british design, eventually sold (to Crumar?) and made into a\n\ number of plastic alternatives. Compared to the Hammond this was a fully \n\ electronic instrument, no moving parts, and much simpler. It had a very\n\ characteristic sound though, sharper and perhaps thinner but was far cheaper\n\ than its larger cousin. It used a master oscillator that was divided down to\n\ each harmonic for each key (as did the later Hammonds for price reasons). This\n\ oscillator division design was used in the first of the polyphonic synthesisers\n\ where the divided note was fead through individual envelope generators and\n\ a shared or individual filter (Polymoog et al).\n\ \n\ The Vox is also a drawbar instrument, but far simplified compared to the\n\ Hammond. It has 4 harmonic mixes, 16', 8' and 4' drawbars each with eight\n\ positions. The fourth gave a mix of 2 2/3, 2, 1 1/3 and 1 foot pipes.\n\ An additional two drawbars controlled the overall volume and waveforms, one\n\ for the flute or sine waves and another for the reed or ramp waves. The\n\ resulting sound could be soft and warm (flute) or sharp and rich (reed).\n\ \n\ There are two switches on the modulator panel, one for vibrato effect and one\n\ for memories and options. Options give access to an chorus effect rather \n\ than the simple vibrato, but this actually detracts from the qualities of the\n\ sound which are otherwise very true to the original.\n\ \n\ Vox is a trade name owned by Korg Inc. of Japan, and Continental is one of \n\ their registered trademarks. Bristol does not intend to infringe upon these\n\ registered names and Korg have their own remarkable range of vintage emulations\n\ available. You are directed to their website for further information of true\n\ Korg products.\n\ \n", " Fender Rhodes\n\ -------------\n\ \n\ Again not an instrument that requires much introduction. This emulation is\n\ the DX-7 voiced synth providing a few electric piano effects. The design is \n\ a Mark-1 Stage-73 that the author has, and the emulation is reasonable if not\n\ exceptional. The Rhodes has always been widely used, Pink Floyd on 'Money',\n\ The Doors on 'Riders on the Storm', Carlos Santana on 'She's not There',\n\ everybody else in the 60's.\n\ \n\ The Rhodes piano generated its sound using a full piano action keyboard where\n\ each hammer would hit a 'tine', or metal rod. Next to each rod was a pickup\n\ coil as found on a guitar, and these would be linked together into the output.\n\ The length of each tine defined its frequency and it was tunable using a tight\n\ coiled spring that could be moved along the length of the tine to adjust its\n\ moment. The first one was built mostly out of aircraft parts to amuse injured\n\ pilots during the second world war. The Rhodes company was eventually sold to\n\ Fender and lead to several different versions, the Mark-2 probably being the\n\ most widely acclaimed for its slightly warmer sound.\n\ \n\ There is not much to explain regarding functionality. The emulator has a volume\n\ and bass control, and one switch that reveals the memory buttons and algorithm\n\ selector.\n\ \n\ The Rhodes would improve with the addition of small amounts of either reverb\n\ or chorus, potentially to be implemented in a future release.\n\ \n\ The Rhodes Bass was cobbled together largely for a presentation on Bristol.\n\ It existed and was used be Manzarek when playing with The Doors in\n\ Whiskey-a-GoGo; the owner specified that whilst the music was great they\n\ needed somebody playing the bass. Rather than audition for the part Manzarek\n\ went out and bought a Rhodes Bass and used it for the next couple of years.\n\ \n", " Sequential Circuits Prophet-10\n\ ------------------------------\n\ \n\ The prophet 10 was the troublesome brother of the Pro-5. It is almost two\n\ Prophet-5 in one box, two keyboards and a layering capability. Early models\n\ were not big sellers, they were temperamental and liable to be temperature \n\ sensitive due to the amount of electronics hidden away inside. The original\n\ layering and 'unison' allowed the original to function as two independent\n\ synths, a pair of layered synths (both keyboards then played the same sound),\n\ as a monophonic synth in 'unison' mode on one keybaord with a second polyphonic\n\ unit on the other, or even all 10 voices on a single keyed note for a humongous\n\ 20 oscillator monophonic monster.\n\ \n\ Phil Collins used this synth, and plenty of others who might not admit to it.\n\ \n\ The emulator uses the same memories as the Prophet-5, shares the same algorithm,\n\ but starts two synths. Each of the two synths can be seen by selecting the U/D\n\ (Up/Down) button in the programmer section. Each of the two synthesisers loads\n\ one of the Pro-5 memories.\n\ \n\ There was an added parameter - the Pan or balance of the selected layer, used\n\ to build stereo synths. The lower control panel was extended to select the\n\ playing modes:\n\ \n\ Dual: Two independent keyboards\n\ Poly: Play note from each layer alternatively\n\ Layer: Play each layer simultaneously.\n\ \n\ In Poly and Layer mode, each keyboard plays the same sounds.\n\ \n\ Mods: Select which of the Mod and Freq wheels control which layers.\n\ \n", NULL, /* Mixer */ NULL, /* Sampler */ NULL, /* Bristol */ NULL, /* DDD */ NULL, /* Pro-52 - stuff later */ " Oberheim OB-X\n\ -------------\n\ \n\ Oberheim was the biggest competitor of Sequential Circuits, having their OB\n\ range neck and neck with each SC Prophet. The sound is as fat, the OB-X \n\ similar to the Prophet-5 as the OB-Xa to the Prophet-10. The synths were widely\n\ used in rock music in the late seventies and early 80s. Their early polyphonic\n\ synthesisers had multiple independent voices linked to the keyboard and were\n\ beast to program as each voice was configured independently, something that\n\ prevented much live usage. The OB-X configured all of the voices with the same\n\ parameters and had non-volatile memories for instant recall.\n\ \n\ Priced at $6000 upwards, this beast was also sold in limited quantities and\n\ as with its competition gained and maintained a massive reputation for rich,\n\ fat sounds. Considering that it only had 21 continuous controllers they were\n\ used wisely to build its distinctive and flexible sound.\n\ \n\ The general design again follows that of the Mini Moog, three oscillators with\n\ one dedicated as an LFO the other two audible. Here there is no mixer though,\n\ the two audible oscillators feed directly into the filter and then the amplifier.\n\ \n\ The richness of the sound came from the oscillator options and filter, the \n\ latter of which is not done justice in the emulator.\n\ \n\ Manual:\n\ \n\ Volume\n\ Auto: autotune the oscillators\n\ Hold: disable note off events\n\ Reset: fast decay to zero for envelopes, disregards release parameter.\n\ Master Tune: up/down one semitone both oscillators.\n\ \n\ Control:\n\ \n\ Glide: up to 30 seconds\n\ Oscillator 2 detune: Up/down one semitone\n\ \n\ Unison: gang all voices to a single 'fat' monophonic synthesiser.\n\ \n\ Modulation:\n\ \n\ LFO: rate of oscillation\n\ Waveform: Sine/Square/Sample&Hold of noise src. Triangle if none selected.\n\ \n\ Depth: Amount of LFO going to:\n\ Freq Osc-1\n\ Freq Osc-2\n\ Filter Cutoff\n\ \n\ PWM: Amount of LFO going to:\n\ PWM Osc-1\n\ PWM Osc-2\n\ \n\ Oscillators:\n\ \n\ Freq1: 32' to 1' in octave increments.\n\ PulseWidth: Width of pulse wave (*).\n\ Freq2: 16' to 1' in semitone increments.\n\ \n\ Saw: sawtooth waveform Osc-1 (**)\n\ Puls: Pulse waveform Osc-1\n\ \n\ XMod: Osc-1 FW to Osc-2 (***)\n\ Sync: Osc-2 sync to Osc-1\n\ \n\ Saw: sawtooth waveform Osc-2\n\ Puls: Pulse waveform Osc-2\n\ \n\ * Although this is a single controller it acts independently on each of the\n\ oscillators - the most recent to have its square wave selected will be\n\ affected by this parameter allowing each oscillator to have a different\n\ pulse width as per the original design.\n\ \n\ ** If no waveform is selected then a triangle is generated.\n\ \n\ *** The original synth had Osc-2 crossmodifying Osc-1, this is not totally\n\ feasible with the sync options as they are not mutually exclusive here.\n\ Cross modulation is noisy if the source or dest wave is pulse, something\n\ that may be fixed in a future release.\n\ \n\ Filter:\n\ \n\ Freq: cutoff frequency\n\ Resonance: emphasis (*)\n\ Mod: Amount of modulation to filter cutoff (**)\n\ \n\ Osc-1: Osc-1 to cutoff at full swing.\n\ KDB: Keyboard tracking of cutoff.\n\ \n\ Half/Full: Oscillator 2 to Cutoff at defined levels (***)\n\ Half/Full: Noise to Cutoff at defined levels (***)\n\ \n\ * In contrast to the original, this filter can self oscillate.\n\ \n\ ** The original had this parameter for the envelope level only, not the\n\ other modifiers. Due to the filter implementation here it affects total\n\ depth of the sum of the mods.\n\ \n\ *** These are not mutually exclusive. The 'Half' button gives about 1/4,\n\ the 'Full' button full, and both on gives 1/2. They could be made mutually\n\ exclusive, but the same effect can be generated with a little more flexibility\n\ here.\n\ \n\ Envelopes: One each for filter and amplifier.\n\ \n\ Attack\n\ Decay\n\ Sustain\n\ Release\n\ \n\ The oscillators appear rather restricted at first sight, but the parametrics\n\ allow for a very rich and cutting sound.\n\ \n\ Improvements would be a fatter filter, but this can be argued of all the \n\ Bristol synthesisers as they all share the same design. It will be altered in\n\ a future release.\n\ \n\ The OB-X has its own mod panel (most of the rest share the same frequency and\n\ mod controls). Narrow affects the depth of the two controllers, Osc-2 will \n\ make frequency only affect Osc-2 rather than both leading to beating, or phasing\n\ effects if the oscillators are in sync. Transpose will raise the keyboard by\n\ one octave.\n\ \n\ Memories are quite simple, the first group of 8 buttons is a bank, the second\n\ is for 8 memories in that bank. This is rather restricted for a digital synth\n\ but is reasonably true to the original. If you want more than 64 memories let\n\ me know.\n\ \n", " Oberheim OB-Xa\n\ --------------\n\ \n\ This is almost two OB-X in a single unit. With one keyboard they could provide\n\ the same sounds but with added voicing for split/layers/poly options. The OB-Xa\n\ did at least work with all 10 voices, had a single keyboard, and is renound for\n\ the sounds of van Halen 'Jump' and Stranglers 'Strange Little Girl'. The sound\n\ had the capability to cut through a mix to upstage even guitar solo's. Oberheim\n\ went on to make the most over the top analogue synths before the cut price\n\ alternatives and the age of the DX overcame them.\n\ \n\ Parameters are much the same as the OB-X as the algorithm shares the same code,\n\ with a few changes to the mod routing. The main changes will be in the use of\n\ Poly/Split/Layer controllers for splitting the keyboard and layering the sounds\n\ of the two integrated synthesisers and the choice of filter algorithm.\n\ \n\ The voice controls apply to the layer being viewed, selected from the D/U\n\ button.\n\ \n\ Manual:\n\ \n\ Volume\n\ Balance\n\ Auto: autotune the oscillators\n\ Hold: disable note off\n\ Reset: fast decay to zero for envelopes, disregards release parameter.\n\ Master Tune: up/down one semitone both oscillators.\n\ \n\ Control:\n\ \n\ Glide: up to 30 seconds\n\ Oscillator 2 detune: Up/down one semitone\n\ \n\ Unison: gang all voices to a single 'fat' monophonic synthesiser.\n\ \n\ Modulation:\n\ \n\ LFO: rate of oscillation\n\ Waveform: Sine/Square/Sample&Hold of noise src. Triangle if none selected.\n\ \n\ Depth: Amount of LFO going to:\n\ Freq Osc-1\n\ Freq Osc-2\n\ Filter Cutoff\n\ \n\ PWM: Amount of LFO going to:\n\ PWM Osc-1\n\ PWM Osc-2\n\ Tremelo\n\ \n\ Oscillators:\n\ \n\ Freq1: 32' to 1' in octave increments.\n\ PulseWidth: Width of pulse wave (*).\n\ Freq2: 16' to 1' in semitone increments.\n\ \n\ Saw: sawtooth waveform Osc-1 (**)\n\ Puls: Pulse waveform Osc-1\n\ \n\ Env: Application of Filter env to frequency\n\ Sync: Osc-2 sync to Osc-1\n\ \n\ Saw: sawtooth waveform Osc-2\n\ Puls: Pulse waveform Osc-2\n\ \n\ * Although this is a single controller it acts independently on each of the\n\ oscillators - the most recent to have its square wave selected will be\n\ affected by this parameter allowing each oscillator to have a different\n\ pulse width, as per the original design.\n\ \n\ ** If no waveform is selected then a triangle is generated.\n\ \n\ Filter:\n\ \n\ Freq: cutoff frequency\n\ Resonance: emphasis (*)\n\ Mod: Amount of modulation to filter cutoff (**)\n\ \n\ Osc-1: Osc-1 to cutoff at full swing.\n\ KDB: Keyboard tracking of cutoff.\n\ \n\ Half/Full: Oscillator 2 to Cutoff at defined levels (***)\n\ \n\ Noise: to Cutoff at defined levels\n\ 4 Pole: Select 2 pole or 4 pole filter\n\ \n\ * In contrast to the original, this filter will self oscillate.\n\ \n\ ** The original had this parameter for the envelope level only, not the\n\ other modifiers. Due to the filter implementation here it affects total\n\ depth of the sum of the mods.\n\ \n\ *** These are not mutually exclusive. The 'Half' button gives about 1/4,\n\ the 'Full' button full, and both on gives 1/2. They could be made mutually\n\ exclusive, but the same effect can be generated with a little more flexibility\n\ here.\n\ \n\ Envelopes: One each for filter and amplifier.\n\ \n\ Attack\n\ Decay\n\ Sustain\n\ Release\n\ \n\ Mode selection:\n\ \n\ Poly: play one key from each layer alternatively for 10 voices\n\ Split: Split the keyboard. The next keypress specifies split point\n\ Layer: Layer each voice on top each other.\n\ \n\ D/U: Select upper and lower layers for editing.\n\ \n\ Modifier Panel:\n\ \n\ Rate: Second LFO frequency or Arpeggiator rate (*)\n\ Depth: Second LFO gain\n\ Low: Modifiers will affect the lower layer\n\ Up: Modifiers will affect the upper layer\n\ Multi: Each voice will implement its own LFO\n\ Copy: Copy lower layer to upper layer\n\ \n\ Mod 01: Modify Osc-1 in given layer\n\ Mod 02: Modify Osc-2 in given layer\n\ PW: Modify Pulse Width\n\ AMT: Amount (ie, depth) of mods and freq wheels\n\ \n\ Transpose: Up or Down one octave.\n\ \n\ The Arpeggiator code integrated into release 0.20.4 has three main parts, the\n\ arpeggiator itself, the arpeggiating sequencer and the chording. All are \n\ configured from the left of the main panel.\n\ \n\ The arpeggiator is governed by the rate control that governs how the code\n\ steps through the available keys, an octave selector for 1, 2 or 3 octaves\n\ of arpeggiation, and finally the Up/Down/Up+Down keys - the last ones start\n\ the arpeggiator. Arpeggiation will only affect the lower layer.\n\ \n\ When it has been started you press keys on the keyboard (master controller\n\ or GUI) and the code will step through each note and octaves of each note \n\ in the order they were pressed and according to the direction buttons. The\n\ key settings are currently reset when you change the direction and you will\n\ have to press the notes again.\n\ \n\ The sequencer is a modification of the code. Select the Seq button and then \n\ a direction. The GUI will program the engine with a series of notes (that can\n\ be redefined) and the GUI will sequence them, also only into the lower layer.\n\ The sequence will only start when you press a key on the keyboard, this is \n\ the starting point for the sequence. You can press multiple notes to have \n\ them sequence in unison. Once started you can tweak parameters to control\n\ the sound and memory 88 when loaded has the filter envelope closed down, a\n\ bit of glide and some heavy mods to give you a starting point for some serious\n\ fun.\n\ \n\ To reprogram the sequence steps you should stop the sequencer, press the PRG\n\ button, then the Sequence button: enter the notes you want to use one by one\n\ on the keyboard. When finished press the sequence button again, it goes out.\n\ Now enable it again - select Seq and a direction and press a note. Press two\n\ notes.\n\ \n\ When you save the memory the OBXa will also save the sequence however there\n\ is only one sequence memory - that can be changed if you want to have a sequence\n\ memory per voice memory (implemented in 0.20.4).\n\ \n\ The chord memory is similar to the Unison mode except that Unison plays all\n\ voices with the same note. Chording will assign one voice to each notes in\n\ the chord for a richer sound. To enable Chording press the 'Hold' button. This\n\ is not the same as the original since it used the hold button as a sustain\n\ option however that does not function well with a Gui and so it was reused.\n\ \n\ To reprogram the Chord memory do the following: press the PRG button then the\n\ Hold button. You can then press the keys, up to 8, that you want in the chord,\n\ and finally hit the Hold button again. The default chord is just two notes, \n\ the one you press plus its octave higher. This results in multiple voices\n\ per keypress (a total of 3 in Layered mode) and with suitable detune will \n\ give a very rich sound.\n\ \n\ There is only one arpeggiator saved for all the memories, not one per memory\n\ as with some of the other implementations. Mail me if you want that changed.\n\ \n\ \n\ \n\ The oscillators appear rather restricted at first sight, but the parametrics\n\ allow for a very rich and cutting sound.\n\ \n\ The Copy function on the Mod Panel is to make Poly programming easier - generate the desired sound and then copy the complete parameter set for poly operation. \n\ It can also be used more subtly, as the copy operation does not affect balance\n\ or detune, so sounds can be copied and immediately panned slightly out of tune to generate natural width in a patch. This is not per the original instrument\n\ that had an arpeggiator on the mod panel.\n\ \n\ The Arpeggiator was first integrated into the OBXa in release 0.20.4 but not\n\ widely tested.\n\ \n", NULL, /* Rhodes Bass */ " KORG MONOPOLY\n\ -------------\n\ \n\ A synth suite would not be complete without some example of a Korg instrument,\n\ the company was also pivotal in the early synthesiser developments. This is\n\ an implementation of their early attempts at polyphonic synthesis, it was\n\ either this one or the Poly-6 (which may be implemented later). Other choices\n\ would have been the MS series, MS-20, but there are other synth packages that\n\ do a better job of emulating the patching flexibility of that synth - Bristol\n\ is more for fixed configurations.\n\ \n\ As with many of the Korg synths (the 800 worked similarly) this is not really\n\ true polyphony, and it is the quirks that make it interesting. The synth had\n\ four audio oscillators, each independently configurable but which are bussed\n\ into a common filter and envelope pair - these are not per voice but rather\n\ per instrument. The unit had different operating modes such that the four\n\ oscillators can be driven together for a phat synth, independently for a form\n\ of polyphony where each is allocated to a different keypress, and a shared\n\ mode where they are assigned in groups depending on the number of keys pressed.\n\ For example, if only 2 notes are held then each key is sounded on two different\n\ oscillators, one key is sounded on all 4 oscillators, and 3 or more have one\n\ each. In addition there are two LFOs for modulation and a basic effects option\n\ for beefing up the sounds. To be honest to the original synth, this emulation\n\ will only request 1 voice from the engine. Korg is one of the few original\n\ manufacturers to have survived the transition to digital synthesis and are\n\ still popular.\n\ \n\ One thing that is immediately visible with this synth is that there are a lot\n\ of controllers since each oscillator is configured independently. This is in\n\ contrast to the true polyphonic synths where one set of controls are given to\n\ configure all the oscillators/filters/envelopes. The synth stages do follow the\n\ typical synth design, there are modulation controllers and an FX section\n\ feeding into the oscillators and filter. The effects section is a set of\n\ controllers that can be configured and then enabled/disabled with a button\n\ press. The overall layout is rather kludgy, with some controllers that are\n\ typically grouped being dispersed over the control panel.\n\ \n\ Control:\n\ \n\ Volume\n\ \n\ Arpeg:\n\ Whether arpegiator steps up, down, or down then up. This works in\n\ conjunction with the 'Hold' mode described later.\n\ \n\ Glide: glissando note to note. Does not operate in all modes\n\ \n\ Octave: Up/Normal/Down one octave transpose of keyboard\n\ \n\ Tune: Global tuning of all oscillators +/- 50 cents (*)\n\ Detune: Overall detuning of all oscillators +/- 50 cents (*)\n\ \n\ * There is an abundance of 'Tune' controllers. Global Tuning affects all\n\ the oscillators together, then oscillators 2, 3 and 4 have an independent\n\ tune controller, and finally there is 'Detune'. The target was to tune all\n\ the oscillators to Osc-1 using the independent Tune for each, and then use\n\ the global Tune here to have the synth tuned to other instruments. The\n\ Detune control can then be applied to introduce some beating between the\n\ oscillators to fatten the sound without necessarily losing overall tune of\n\ the instrument.\n\ \n\ Modulation wheels:\n\ \n\ Bend:\n\ Intensity: Depth of modulation\n\ Destination:\n\ VCF - Filter cutoff\n\ Pitch - Frequency of all oscillators\n\ VCO - Frequency of selected oscillators (FX selection below).\n\ \n\ MG1: Mod Group 1 (LFO)\n\ Intensity: Depth of modulation\n\ Destination:\n\ VCF - Filter cutoff\n\ Pitch - Frequency of all oscillators\n\ VCO - Frequency of selected oscillators (FX selection below).\n\ \n\ LFO:\n\ \n\ MG-1:\n\ Frequency\n\ Waveform - Tri, +ve ramp, -ve ramp, square.\n\ \n\ MG-2:\n\ Frequency (Triangle wave only).\n\ \n\ Pulse Width Control:\n\ \n\ Pulse Width Modulation:\n\ Source - Env/MG-1/MG-2\n\ Depth\n\ \n\ Pule Width\n\ Width control\n\ \n\ These controllers affect Osc-1 though 4 with they are selected for either\n\ square of pulse waveforms.\n\ \n\ Mode:\n\ \n\ The Mono/Poly had 3 operating modes, plus a 'Hold' option that affects \n\ each mode:\n\ \n\ Mono: All oscillators sound same key in unison\n\ Poly: Each oscillator is assigned independent key - 4 note poly.\n\ Share: Dynamic assignment:\n\ 1 key - 4 oscillators = Mono mode\n\ 2 key - 2 oscillators per key\n\ 3/4 - 1 oscillator per key = Poly mode\n\ \n\ The Hold function operates in 3 different modes:\n\ \n\ Mono: First 4 keypresses are memorised, further notes are then chorded\n\ together monophonically.\n\ Poly:\n\ Notes are argeggiated in sequence, new note presses are appended\n\ to the chain. Arpeggiation is up, down or up/down.\n\ Share:\n\ First 4 notes are memorised and are then argeggiated in sequence,\n\ new note presses will transpose the arpeggiation. Stepping is up,\n\ down or up/down.\n\ \n\ There are several controllers that affect arpeggation:\n\ \n\ Arpeg - direction of stepping\n\ MG-2 - Frequency of steps from about 10 seconds down to 50 bps.\n\ Trigger - Multiple will trigger envelopes on each step.\n\ \n\ Effects:\n\ \n\ There are three main effects, or perhaps rather modulations, that are\n\ controlled in this section. These are vibrato, crossmodulated frequency\n\ and oscillator synchronisation. The application of each mod is configured\n\ with the controllers and then all of them can be enabled/disabled with\n\ the 'Effects' button. This allows for big differences in sound to be \n\ applied quickly and simply as a typical effect would be. Since these mods\n\ apply between oscillators it was envisaged they would be applied in Mono\n\ mode to further fatten the sound, and the Mono mode is actually enabled when\n\ the Effects key is selected (as per the original instrument). The Mode can\n\ be changed afterwards for Effects/Poly for example, and they work with the\n\ arpeggiation function.\n\ \n\ X-Mod: frequency crossmodulation between oscillators\n\ Freq: frequency modulation by MG-1 (vibrato) or Envlope (sweep)\n\ \n\ Mode:\n\ Syn: Oscillators are synchronised\n\ X-M: Oscillators are crossmodulated\n\ S-X: Oscillators are crossmodulated and synchronised\n\ \n\ SNG:\n\ Single mode: synth had a master oscillator (1) and three slaves (2/3/4)\n\ DBL:\n\ Double mode: synth had two master (1/3) and two slaves (2/4)\n\ \n\ The overall FX routing depends on the SNG/DBL mode and the selection of\n\ Effects enabled or not according to the table below. This table affects \n\ the FX routing and the modulation wheels discussed in the LFO section above:\n\ \n\ --------------------------------------------------\n\ | FX OFF | FX ON |\n\ | |----------------------------------\n\ | | Single | Double |\n\ ---------------+--------------+-----------------+---------------|\n\ | VCO-1/Slave | VCO-1 | VCO 2/3/4 | VCO 2/4 |\n\ | | | | |\n\ | Pitch | VCO 1-4 | VCO 1-4 | VCO 1-4 |\n\ | | | | |\n\ | VCF | VCF | VCF | VCF |\n\ -----------------------------------------------------------------\n\ \n\ So, glad that is clear. Application of the modulation wheels to Pitch and\n\ VCF is invariable when they are selected. In contrast, VCO/Slave will have\n\ different destinations depending on the Effects, ie, when effects are on\n\ the modwheels will affect different 'slave' oscillators.\n\ \n\ \n\ Oscillators:\n\ \n\ Each oscillator had the following controllers:\n\ \n\ Tune (*)\n\ Waveform: Triangle, ramp, pulse, square (**)\n\ Octave: Transpose 16' to 2'\n\ Level: output gain/mix of oscillators.\n\ \n\ * Osc-1 tuning is global\n\ ** width of pulse and square wave is governed by PW controller. The\n\ modulation of the pulse waveform is then also controlled by PWM.\n\ \n\ Noise:\n\ \n\ Level: white noise output gain, mixed with oscillators into filter.\n\ \n\ VCF:\n\ \n\ Freq:\n\ Cutoff frequency\n\ \n\ Res:\n\ Resonance/emphasis.\n\ \n\ Env:\n\ Amount of contour applied to cutoff\n\ \n\ KBD:\n\ Amount of key tracking applied.\n\ \n\ ADSR: Two: filter/PWM/FX, amplifier\n\ \n\ Attack\n\ Decay\n\ Sustain\n\ Release\n\ \n\ Trigger:\n\ Single: Trigger once until last key release\n\ Multi: Trigger for each key or arpeggiator step.\n\ \n\ Damp:\n\ Off: Notes are held in Poly/Share mode until last key is released.\n\ On: Oscillators are released as keys are released.\n\ \n\ This is more a synth to play with than describe. It never managed to be a true\n\ blue synth perhaps largely due to its unusual design: the quasi-poly mode was\n\ never widely accepted, and the effects routing is very strange. This does make\n\ it a synth to be tweaked though.\n\ \n\ Some of the mod routings do not conform to the original specification for the\n\ different Slave modes. This is the first and probably the only bristol synth that\n\ will have an inbuilt arpeggiator. The feature was possible here due to the mono\n\ synth specification, and whilst it could be built into the MIDI library for\n\ general use it is left up to the MIDI sequencers (that largely came along to \n\ replace the 1980s arpeggiators anyway) that are generally availlable on Linux.\n\ [Other instruments emulated by bristol that also included arpeggiation but do\n\ not have in the emulation were the Juno-6, Prophet-10, Oberheim OB-Xa, Poly6].\n\ \n\ As of May 06 this synth was in its final stages of development. There are a few\n\ issues with Tune and Detune that need to be fixed, and some of the poly key\n\ assignment may be wrong.\n\ \n", " KORG POLY 6\n\ -----------\n\ \n\ Korg in no way endorses this emulation of their classic synthesiser and have\n\ their own emulation product that gives the features offered here. Korg,\n\ Mono/Poly, Poly-6, MS-20, Vox and Continental are all registered names or\n\ trademarks of Korg Inc of Japan.\n\ \n\ Quite a few liberties were taken with this synth. There were extremely few \n\ differences between the original and the Roland Juno 6, they both had one osc \n\ with PWM and a suboscillator, one filter and envelope, a chorus effect, and \n\ inevitably both competed for the same market space for their given price. To \n\ differentiate this algorithm some alterations were made. There are two separate\n\ envelopes rather than just one, but the option to have a gated amplifier is \n\ still there. In addition glide and noise were added, both of which were not in \n\ the original instrument. With respect to the original instrument this was \n\ perhaps not a wise move, but there seemed little point in making another Juno \n\ with a different layout. The net results is that the two synths do sound quite \n\ different. The emulation does not have an arpeggiator. \n\ \n\ Volume: Master volume of the instrument \n\ \n\ Glide: length of portamento \n\ \n\ Tune: Master tuning of instrument \n\ \n\ Bend: Amount of pitch wheel that is applied to the oscillators frequency. \n\ \n\ \n\ VCO section: \n\ \n\ Octave: What octave the instrument's keyboard is in. \n\ \n\ Wave: Waveform selection: Triangle, Saw, Pulse and Pulsewidth \n\ \n\ PW PWM: Amount of Pulsewidth (when Pulse is selected) and Pulsewidth\n\ Modulation (When Pulsewidth is selected). \n\ \n\ Freq: Frequency of PW/PWM \n\ \n\ OFF/SUB1/SUB2; Adds a square sub-oscillator either off, 1 or 2 octaves\n\ down from a note. \n\ \n\ MG (Modulation Group): \n\ \n\ Freq: Frequency of LFO \n\ \n\ Delay: Amount of time before the LFO affects the destination when a key\n\ is pressed. \n\ Level: How strongly the LFO affects the destination \n\ \n\ VCO/VCF/VCA: Destinations that the LFO can go to: \n\ \n\ VCO: The Voltage Controlled Oscillator:\n\ Affects oscillator pitch, producing vibrato \n\ \n\ VCF: The Voltage Controlled Filter:\n\ Affects Filter, producing a wah effect \n\ \n\ VCA: The Voltage Controlled Amplifier:\n\ Affects the Amplifier, producing tremolo \n\ \n\ VCF section: \n\ \n\ Freq: Cut off frequency of the filter \n\ \n\ Res: Resonance of the filter \n\ \n\ Env: By how much the filter is affected by the envelope. \n\ \n\ Kbd: How much Keyboard tracking is applied to the envelope. note:\n\ \n\ A low setting doesn't allow the filter to open, making the notes\n\ seem darker the further you go up the keyboard. \n\ \n\ Hold: prevent key off events \n\ \n\ Mono Mode: Gang all voices to a single 'fat' monophonic synthesiser. \n\ \n\ Poly: One voice per note. \n\ \n\ Envelope Section: \n\ \n\ Top: \n\ \n\ Filter envelope: \n\ \n\ Attack: Amount of time it takes the filter to fully open.\n\ A high value can produce a 'sweeping filter' effect. \n\ Decay: Amount of time it takes for the filter to close to\n\ the sustain level \n\ Sustain: Amount of filter that is sustained when a key is held \n\ \n\ Release: Amount of time it takes for the filter envelope to stop\n\ affecting the filter. Combining a low filter release with a\n\ high amplitude release time can cause an interesting effect. \n\ \n\ Bottom: \n\ \n\ Amplitude envelope: \n\ \n\ Attack: Amount of time it takes for the signal to reach its peak. \n\ \n\ Decay: Amount of time it takes for the signal to drop to the\n\ sustain level \n\ Sustain: How quickly the sound decays to silence. \n\ \n\ Release: How long it takes the sound to decay to silence after\n\ releasing a key. \n\ \n\ VCA: \n\ \n\ Env: When on, this causes the Amplitude envelope to affect the sound.\n\ I.E, If you have a long attack time, you get a long attack time. \n\ Gate: When on, this causes the Amplitude envelope only (not the filter\n\ envelope) to be be bypassed. \n\ Gain: Gain of signal. \n\ \n\ Effects Section: \n\ \n\ 0: No effects \n\ 1: Soft Chorus \n\ 2: Phaser \n\ 3: Ensemble \n\ \n\ Intensity: How much the effects affect the output. \n\ \n\ There are some mildly anomolous effects possible from the MG section, especially\n\ with the VCA. The MG and the env are summed into the VCA which means if the env\n\ decays to zero then the LFO may end up pumping the volume, something that may\n\ be unexpected. Similarly, if the LFO is pumping and the voice finally stops its\n\ cycle then the closing gate may cause a pop on the MG signal. These can be \n\ resolved however the current behavious is probably close to the original.\n\ \n\ Bristol thanks Andrew Coughlan for patches, bug reports, this manual page and\n\ diverse suggestions to help improve the application.\n\ \n\ Korg in no way endorses this emulation of their classic synthesiser and have \n\ their own emulation product that gives the features offered here. Korg, \n\ Mono/Poly, Poly-6, MS-20, Vox and Continental are all registered names or \n\ trademarks of Korg Inc of Japan.\n\ \n", " ARP AXXE\n\ --------\n\ \n\ TBD\n\ \n\ At the risk of getting flamed, this is potentially the ugliest synth ever made,\n\ although the competition is strong. It was implemented as a build up to the far\n\ more useful ARP 2600 to understand the ARP components and their implementation.\n\ \n\ The implementation is a giveaway written during a week long business trip to \n\ Athens to keep me busy in the hotel. Its design lead on to the Odyssey and that\n\ was the step towards the final big brother, the ARP 2600.\n\ \n", " ARP ODYSSEY\n\ -----------\n\ \n\ Ring modulation is correct here, it is a multiplier. This deviates from the\n\ original instrument that used an XOR function on the pulsewave outputs of the\n\ two oscillators. The implementation has two models, Mark-I and Mark-II. These\n\ implement different filters as per the original. Although their characteristics\n\ are different it is not suggested they are a particularly close emulation of\n\ the original.\n\ \n\ TBD\n\ \n", " Memory Moog\n\ -----------\n\ \n\ TBD.\n\ \n\ This is actually a lot warmer than the Mini emulator, largely due to being\n\ later code. The mini should be revisited but I am saving that pleasure for when\n\ some more filters are available. [This was done during the 0.20 stream using the\n\ Houvilainen filters and bandwidth limited oscillators to produce a far richer\n\ sound. Also incorporate a number of fixes to the emulation stages.].\n\ \n", " ARP 2600\n\ --------\n\ \n\ This synth will probably never get a writeup, it is kind of beyond the scope of\n\ this document. There are some discrepancies with the original:\n\ \n\ The filters do not self oscillate, they require an input signal. The output\n\ stage is global to all voices so cannot be patched back into the signal path.\n\ The original did not have a chorus, only a spring reverb. The input stage has\n\ not been tested for either signal nor envelope following code. The voltage\n\ manipulators were not in the first bristol upload with this emulation (-60), \n\ but a future release will include mixing inverters, a lag processor, and\n\ possibly also a Hz->V extractor. The unit has an extra LFO where the original\n\ had just a clock trigger circuit, it produces a TRI wave, can be used to\n\ trigger the AR envelope and be used for modulation. The electroswitch is\n\ unidirectional, two inputs switchable to one output. The sample and hold \n\ circuit cannot accept an external clock. The Keyboard inputs to the VCO cannot\n\ accept and alternative signal other than the MIDI note with tracking of this \n\ note either enabled or disabled.\n\ \n\ The rest works, ie, all the VCO/VCF/VCA/ENV/AMP and any of the 30 or so outputs\n\ can be repatched into any of the 50 or so inputs. Patches cause no overhead in\n\ the engine as it uses default buffering when not repatched, so feel free to put\n\ in as many cables as you can fit. Patches in the GUI still demand a lot of CPU\n\ cycles. Release -77 improved this about 5-fold and further improvements are in\n\ the pipeline: the 0.10 stream implemented color caching and XImage graphics\n\ interface which massively improved GUI performance.\n\ \n", NULL, /* SAKs */ NULL, /* MS-20 */ NULL, /* Solina */ NULL, /* RoadRunner */ NULL, /* Granular */ " REALISTIC MG-1 CONCERTMATE\n\ --------------------------\n\ \n\ This is a pimpy little synth. It was sold through the Realistic electronics \n\ chain, also known as Radio Shack (and as Tandy, in the UK at least). It was\n\ relatively cheap but had a design from Moog Music (from after Robert Moog\n\ had left?) including the patented ladder filter. It consisted of a monophonic\n\ synth, dual oscillator, lfo, noise, filter, env, and a ring modulator. On top\n\ of that there was an organ circuit to give 'polyphony'. It was not really\n\ polyphonic although different descriptions will tell you it had 10 voices. \n\ These write-ups are by people who probably only had 10 fingers, the truth is\n\ that the organ circuit was as per any other - it had a master oscillator at\n\ about 2MHz and this was divided using binary counters to deliver a frequency\n\ for every note. The output of the 'poly' section was lamentable at best, it is\n\ a fairly pure square wave passed through the filter and contour. This is fully\n\ emulated although in addition to the contour bristol implements a per note\n\ envelope just to groom the note - this prevents ticks when new keys are pressed\n\ with the mono envelope fully open. There is no access to this env, it just has\n\ fast attack and decay times to smooth the signal and is preconfigured by the\n\ user interface on startup.\n\ \n\ The mono section is reasonably fun, the oscillators can be synchronised and\n\ there is a ring modulator so the range of sounds is quite wide. The emulator\n\ uses a chaimberlain filter so is not as warm as the Moog ladder filters.\n\ \n\ The list of people who used this is really quite amazing. The promotion for\n\ the product had Elton John holding one up in the air, although seeing as he\n\ probably already had every other synth known to man, holding it up in the\n\ air is likely to be all he ever did with it. Who knows how much they had to\n\ pay him to do it - the photo was nice though, from the days when Elton was\n\ still bald and wearing ridiculously oversized specs.\n\ \n\ Tuning:\n\ \n\ One control each for the poly oscillator and mono oscillators\n\ \n\ Glide:\n\ \n\ Only affects the monophonic oscillators.\n\ \n\ Modulation:\n\ \n\ One LFO with rate and waveshape selection\n\ produces tri, square and S/H signals.\n\ can trigger the envelope\n\ One noise source.\n\ The modulation can be directed to:\n\ Oscillators for vibrato\n\ Filter for wah-wah effects\n\ \n\ Oscillator-1:\n\ \n\ Tri or square wave\n\ Octave from -2 to 0 transposition\n\ Sync selector (synchronises Osc-2 to Osc-1)\n\ \n\ Oscillator-2:\n\ \n\ Tri or pulse wave\n\ Detune. This interoperates with the sync setting to alter harmonics\n\ Octave from -1 to +1 transposition\n\ \n\ Contour: This is not an ADSR, rather an AR envelope\n\ \n\ Sustain: AR or ASR envelope selector.\n\ Tracking: controls mono oscillators\n\ Envelope control\n\ Key tracking (gate, no env)\n\ Continuous (always on)\n\ Rise (attack time)\n\ Fall (release time)\n\ \n\ Filter:\n\ \n\ Cutoff frequency\n\ Emphasis\n\ Contour depth\n\ Keyboard tracking off, 1/2, full.\n\ \n\ Mixer: Levels for\n\ Mono Osc-1\n\ Mono Osc-2\n\ Noise\n\ RingMod of the mono oscillators (called 'bell').\n\ Poly Osc level.\n\ \n\ Master Volume control.\n\ \n\ One extra button was added to save the current settings. For the rest the \n\ controls reflect the simplicity of the original. The implementation is a single\n\ synth, however due to the engine architecture having a pre-operational routine,\n\ a post-operational routine and an operate(polyphonic emulator) the emulation\n\ executes the mono synth in the pre- and post- ops to be mono, these are called\n\ just once per cycle. The poly synth is executed in the operate() code so is \n\ polyphonic. This leads to one minor deviation from the original routing in\n\ that if you select continuous tone controls then you will also hear one note\n\ from the poly section. This is a minor issue as the poly oscillator can be\n\ zeroed out in the mixer.\n\ \n\ It is noted here that this emulation is just a freebie, the interface is kept\n\ simple with no midi channel selection (start it with the -channel option and\n\ it stays there) and no real memories (start it with the -load option and it\n\ will stay on that memory location). There is an extra button on the front\n\ panel (a mod?) and pressing it will save the current settings for next time\n\ it is started. I could have done more, and will if people are interested, but\n\ I built it since the current developments were a granular synth and it was\n\ hard work getting my head around the grain/wave manipulations, so to give \n\ myself a rest I put this together one weekend. The Rhodesbass and ARP AXXE\n\ were done for similar reasons. I considered adding another mod button, to make\n\ the mono section also truly polyphonic but that kind of detracts from the\n\ original. Perhaps I should put together a Polymoog sometime that did kind of\n\ work like that anyway.\n\ \n\ This was perhaps a strange choice, however I like the way it highlights the\n\ difference between monophonic, polyphonic and 'neopolyphonic' synthesised\n\ organs (such as the polymoog). Its a fun synth as well, few people are likely\n\ to every bother buying one as they cost more now than when they were produced\n\ due to being collectable: for the few hundred dollars they would set you back\n\ on eBay you can get a respectable polyphonic unit.\n\ So here is an emulator, for free, for those who want to see how they worked.\n\ \n", " Vox Continental 300\n\ -------------------\n\ \n\ There is an additional emulator for the later Mark-II, Super, 300 or whatever\n\ model you want to call it. This is probably closest to the 300. It was a \n\ dual manual organ, the lower manual is a Continental and the upper manual had\n\ a different drawbar configuration, using 8', 4' and 2', another two compound\n\ drawbars that represented 5-1/3'+1-3/5', and 2-2/3'+2'+1' respectively. This\n\ gave upper manual a wider tonic range, plus it had the ability to apply some\n\ percussive controls to two of the drawbars. Now, depending on model, some of \n\ these values could be different and bristol does not emulate all the different\n\ combinations, it uses the harmonics described above and applies percussive to\n\ the 2' and 5-1/3' harmonics (which is arguably incorrect however it gives\n\ a wider combination of percussive harmonics).\n\ \n\ The percussive has 4 controls, these are selectors for the harmonics that will\n\ be driven through the percussive decay (and then no longer respond to the \n\ drawbars), a decay rate called 'L' which acts as a Longer decay when selected,\n\ and a volume selector called 'S' which stands for Soft. The variables are \n\ adjustable in the mods section. The mods panel is intended to be hidden as\n\ they are just variable parameters. On the original units these were PCB mounted\n\ pots that were not generally accessible either. The panel is visible when you\n\ turn the power control off, not that I suppress the keyboard or anything when\n\ the power is off, but it gave me something useful do to with this button. The\n\ transparency layer is fixed here and is used to apply some drop shadow and a\n\ few beer spills on the cover.\n\ \n\ There is an additional Bass section for those who bought the optional Bass\n\ pedals (my old one had them). The emulation allow the selection of Flute and\n\ Reed strengths, and to select 8' or 8'/16' harmonics. The 'Sustain' control\n\ does not currently operate (0.10.9) but that can be fixed if people request\n\ the feature.\n\ \n\ The lower manual responds to the MIDI channel on which the emulation was \n\ started. The upper manual responds to notes greater than MIDI key 48 on the\n\ next channel up. The Bass section also responds to this second channel on keys\n\ lower than #48. Once started you cannot change the midi channel - use the \n\ '-channel' option at startup to select the one you want. The actual available\n\ max is 15 and that is enforced.\n\ \n\ The emulation only contains 6 available presets and a 'Save' button that you \n\ need to double click to overwrite any preset. The emulation actually uses \n\ banks, so if you started it with '-load 23' it would start up by selecting\n\ bank 20, and load memory #3 from that bank. Any saved memories are also then\n\ written back to bank 20, still with just 6 memories accessible 20-25. You can\n\ access more via MIDI bank select and program change operations if suitably\n\ linked up.\n\ \n\ Vox is a trade name owned by Korg Inc. of Japan, and Continental is one of \n\ their registered trademarks. Bristol does not intend to infringe upon these\n\ registered names and Korg have their own remarkable range of vintage emulations\n\ available. You are directed to their website for further information of true\n\ Korg products.\n\ \n", " Roland Jupiter 8\n\ ----------------\n\ \n\ This emulator is anticipated in 0.20.4.\n\ \n\ The Jupiter synthesizers were the bigger brothers of the Juno series: their\n\ capabilities, sounds and prices were all considerably larger. This is the\n\ larger of the series, the others being the -4 and -6. The -6 and the rack\n\ mounted MKS-80 both came out after the Jupiter-8 and had somewhat more flexible\n\ features. Several of these have been incorporated into the emulation and that\n\ is documented below.\n\ \n\ A quick rundown of the synth and emulation:\n\ \n\ The synth runs as two layers, each of which is an independent emulator running\n\ the same algorithm, both layers are controlled from the single GUI. The layers\n\ are started with a set of voices, effectively 4+4 per default however bristol\n\ plays with those numbers to give the split/layer at 4 voices each and the 'All'\n\ configuration with 8 voices - it juggles them around depending on the Poly \n\ mode you select. You can request a different number of voices and the emulator \n\ will effectively allocate half the number to each layer. If you request 32\n\ voices you will end up with 4+4 though since 32 is interpreted as the default.\n\ \n\ The Poly section is used to select between Dual layers, Split keyboard and the\n\ 8voice 'All' mode. You can redefine the split point with a double click on the\n\ 'Split' button and then pressing a key. If you have linked the GUI up to the\n\ MIDI you should be able to press a key on your master keyboard rather than on\n\ the GUI.\n\ \n\ After that you can select the layer as upper or lower to review the parameter \n\ settings of each layer: they are as follows:\n\ \n\ LFO:\n\ Frequency\n\ Delay\n\ Waveform (tri, saw, square, s&h)\n\ \n\ VCO Mods:\n\ LFO and ENV-1\n\ Destination to modulate frequency of DCO1, DCO2 or both.\n\ \n\ PWM:\n\ PW\n\ PWM\n\ Modified by Env-1 or LFO\n\ \n\ DCO-1:\n\ Crossmod (FM) from DCO2 to DCO1\n\ Modified by Env-1\n\ \n\ Octave range 16' to 2' (all mixable)\n\ Waveform: Tri, saw, pulse, square (all mixable)\n\ \n\ DCO-2:\n\ Sync (1->2 or 2->1 or off)\n\ Range: 32' to 2' (all mixable)\n\ Tuning\n\ Waveform: tri, saw, pulse, noise (all mixable)\n\ \n\ Mix:\n\ Osc 1 and Osc 2\n\ \n\ HPF:\n\ High pass filter of signal\n\ \n\ Filter:\n\ Cutoff\n\ Emphasis\n\ LPF/BPF/HPF\n\ Env modulation\n\ Source from Env-1 or Env-2\n\ LFO mod amount\n\ Keyboard tracking amount\n\ \n\ VCA:\n\ Env-2 modulation\n\ LFO modulation\n\ \n\ ADSR-1:\n\ A/D/S/R\n\ Keyboard tracking amount\n\ Invert\n\ \n\ ADSR-2:\n\ A/D/S/R\n\ Keyboard tracking amount\n\ \n\ Pan:\n\ Stereo panning of layer\n\ \n\ All of the above 40 or so parameters are part of the layer emulation and are\n\ separately configurable.\n\ \n\ The keyboard can operate in several different modes which are selectable from\n\ the Poly and Keyboard mode sections. The first main one is Dual, Split and All.\n\ Dual configure the two synth layers to be placed on top of each other. Split\n\ configures them to be next to each other and by double clicking the split\n\ button you can then enter a new split point by pressing a key. The All setting\n\ gives you a single layer with all 8 voices active. These settings are for the\n\ whole synth.\n\ \n\ The Poly section provides different playing modes for each layer independently.\n\ There are 3 settings: Solo give the layer access to a single voice for playing\n\ lead solos. Unison give the layer however many voices it is allowed (8 if in \n\ the All mode, 4 otherwise) and stacks them all on top of each other. This is\n\ similar to Solo but with multiple voices layered onto each other. Unison is \n\ good for fat lead sounds, Solo better for mono bass lines where Unison might\n\ have produced unwanted low frequency signal phasing. The third option is Poly\n\ mode 1 where the synth allocates a single voice to each key you press. The\n\ original also had Poly mode 2 which was not available at the first bristol\n\ release - this mode would apply as many notes as available to the keys you\n\ pressed: 1 key = 8 voices as in Unison, with 2 keys pressed each would get 4\n\ voices each, 4 keys pressed would get 2 voices and mixtures in there for other\n\ key combinations. This may be implemented in a future release but it is a\n\ rather left field option and would have to be put into the MIDI library that\n\ controls the voice assignments.\n\ \n\ The arpeggiator integrated into bristol is a general design and will differ\n\ from the original. The default settings are 4 buttons controlling the range\n\ of the arpeggiation, from 1 to 4 octaves, 4 buttons controlling the mode as\n\ Up, Down, Up+Down or Random sequencing of the notes available, and 4 notes\n\ that are preloaded into the sequence.\n\ \n\ Finally there are two global controls that are outside of the memories - the\n\ rate and clock source (however externally driven MTC has not been implemented\n\ yet). It is noted that the Arpeggiator settings are separate from the sequence\n\ information, ie, Up/Down/Rnd, the range and the arpeggiator clock are not the\n\ same as the note memory, this is discussed further in the memory setting\n\ section below.\n\ \n\ It is possible to redefine the arpeggiator sequence: select the function \n\ button on the right hand side, then select any of the arpeggiator mode buttons,\n\ this will initiate the recording. It does not matter which of the mode is\n\ selected since they will all start the recording sequence. When you have\n\ finished then select the mode button again (you may want to clear the function\n\ key if still active). You can record up to 256 steps, either from the GUI\n\ keyboard or from a master controller and the notes are saved into a midi\n\ key memory.\n\ \n\ There is no capability to edit the sequences once they have been entered, that\n\ level of control is left up to separate MIDI sequencers for which there are\n\ many available on Linux. Also, the note memory is actually volatile and will\n\ be lost when the emulation exits. If you want to save the settings then you\n\ have to enter them from the GUI keyboard or make sure that the GUI is linked\n\ up to the master keyboard MIDI interface - you need to be able to see the\n\ GUI keyboard following the notes pressed on the master keyboard since only\n\ when the GUI sees the notes can it store them for later recall. If the GUI\n\ did view the sequence entered here then it will be saved with the patch in\n\ a separate file (so that it can be used with other bristol synths).\n\ \n\ In addition to the Arpeggiator there is the 'Chord' control. The original\n\ synth had two green panel buttons labelled 'Hold', they were actually similar\n\ to the sustain pedal on a MIDI keyboard or piano, with one for each layer of\n\ the synth. They have been redefined here as Chord memory. When activated the\n\ layer will play a chord of notes for every key press. The notes are taken from\n\ separate chord memory in the Arpeggiator sequencer. The result is very similar\n\ to the Unison mode where every voice is activated for a single key, the\n\ difference here is that every voice may be playing a different note to give\n\ phat chords. To configure a chord you enable the function key and the target\n\ Hold button to put the synth into chord learning mode, play a set of notes\n\ (you don't have to hold them down), and click again to finalise the chord.\n\ If there are more chord notes than voices available then all voices will\n\ activate. If there are more voices than notes then you will be able to play\n\ these chord polyphonically, for example, if you have 8 voices and entered\n\ just 4 chorded notes then you will have 2 note polyphony left. You should\n\ also be able to play arpeggiations of chords. The maximum number of notes\n\ in a chord is 8.\n\ \n\ The synth has a modifier panel which functions as performance options which \n\ can be applied selectively to different layers:\n\ \n\ Bender:\n\ This is the depth of the settings and is mapped by the engine to\n\ continuous controller 1 - the 'Mod' wheel. The emulation also tracks\n\ the pitch wheel separately.\n\ \n\ Bend to VCO\n\ This applies an amount of pitch bend from the Mod wheel selectively\n\ to either VCO-1 and/or VCO-2. These settings only affect the Mod\n\ layers selected from the main panel. Subtle modifications applied in\n\ different amounts to each oscillator can widen the sound considerable\n\ by introducing small amounts of oscillator phasing.\n\ \n\ Bend to VCF\n\ Affects the depth of cutoff to the filter with on/off available. Again\n\ only applies to layers activate with the Mod setting.\n\ \n\ LFO to VCO:\n\ The mod panel has a second global LFO producing a sine wave. This can\n\ be driven in selectable amounts to both VCO simultaneously. Layers are\n\ selected from the Mod buttons.\n\ \n\ LFO to VCF:\n\ The LFO can be driven in selectable amounts to both VCO or to the VCF.\n\ Layers are selected from the Mod buttons.\n\ \n\ Delay:\n\ This is the rise time of the LFO from the first note pressed. There is\n\ no apparent frequency control of the second LFO however bristol allows\n\ the frequency and gain of the LFO to track velocity using function B4\n\ (see below for function settings). Since there is only one LFO per\n\ emulation then the velocity tracking can be misleading as it only \n\ tracks from a single voice and may not track the last note. For this\n\ reason it can be disabled. Using a tracking from something like channel\n\ pressure is for future study.\n\ \n\ Glide:\n\ Glissando between key frequencies, selectable to be either just to the\n\ upper layer, off, or to both layers.\n\ \n\ Transpose:\n\ There are two transpose switches for the lower and upper layers \n\ respectively. The range is +/1 one octave.\n\ \n\ Modifier panel settings are saved in the synth memories and are loaded with\n\ the first memory (ie, with dual loaded memories discussed below). The ability\n\ to save these settings in memory is an MKS-80 feature that was not available\n\ in either the Jupiter-6 or -8.\n\ \n\ There are several parts to the synth memories. Layer parameters govern sound\n\ generation, synth parameters that govern operating modes such Dual/Split,\n\ Solo/Unison etc, Function settings that modify internal operations, the\n\ parameters for the mod panel and finally the Arpeggiator sequences. These\n\ sequences are actually separate from the arpeggiator settings however that\n\ was covered in the notes above.\n\ \n\ When a patch is loaded then only the layer parameters are activated so that the\n\ new sound can be played, and the settings are only for the selected layer. This\n\ means any chord or arpeggiation can be tried with the new voice active.\n\ \n\ When a memory is 'dual loaded' by a double click on the Load button then all\n\ the memory settings will be read and activated: the current layer settings,\n\ synth settings, operational parameters including the peer layer parameters\n\ for dual/split configurations. Dual loading of the second layer will only \n\ happen if the memory was saved as a split/double with a peer layer active.\n\ \n\ The emulation adds several recognised Jupiter-6 capabilities that were not a\n\ part of the Jupiter-8 product. These are\n\ \n\ 1. PW setting as well as PWM\n\ 2. Cross modulation can be amplified with envelope-1 for FM type sounds\n\ 3. Sync can be set in either direction (DCO1 to 2 or DCO2 to 1)\n\ 4. The waveforms for DCO 1&2 are not exclusive but mixable\n\ 5. The LFO to VCA is a continuous controller rather than stepped\n\ 6. The envelope keyboard tracking is continuous rather than on/off\n\ 7. The filter option is multimode LP/BP/HP rather than 12/24dB\n\ 8. Layer detune is configurable\n\ 9. Layer transpose switches are available\n\ 10. Arpeggiator is configurable on both layers\n\ \n\ Beyond these recognised mods it is also possible to select any/all DCO\n\ transpositions which further fattens up the sound as it allows for more\n\ harmonics. There is some added detune between the waveforms with its depth\n\ being a function of the -detune setting. Separate Pan and Balance controls\n\ have been implemented, Pan is the stereo positioning and is configurable per\n\ layer. Balance is the relative gain between each of the layers.\n\ \n\ There are several options that can be configured from the 'f' button\n\ in the MIDI section. When you push the f(n) button then the patch and bank\n\ buttons will not select memory locations but display the on/off status of 16\n\ algorithmic changes to the emulation. Values are saved in the synth memories.\n\ These are bristol specific modifications and may change between releases unless\n\ otherwise documented.\n\ \n\ F(n):\n\ \n\ f(p1): Env-1 retriggers \n\ f(p2): Env-1 conditionals\n\ f(p3): Env-1 attack sensitivity\n\ f(p4): Env-2 retriggers\n\ f(p5): Env-2 conditionals\n\ f(p6): Env-2 attack sensitivity\n\ f(p7): Noise per voice/layer\n\ f(p8): Noise white/pink\n\ \n\ f(b1): LFO-1 per voice/layer\n\ f(b2): LFO-1 Sync to Note ON\n\ f(b3): LFO-1 velocity tracking\n\ f(b4): Arpeggiator retrigger\n\ f(b5): LFO-2 velocity tracking\n\ f(b6): NRP enable\n\ f(b7): Debug MIDI\n\ f(b8): Debug GUI controllers\n\ \n\ The same function key also enables the learning function of the arpeggiator \n\ and chord memory, as explained above. When using the arpeggiator you may want\n\ to test with f(b4) enabled, it will give better control of the filter envelope.\n\ \n\ \n\ Other differences to the original are the Hold keys on the front panel. These\n\ acted as sustain pedals however for the emulation that does not function very\n\ well. With the original the buttons were readily available whilst playing and\n\ could be used manually, something that does not work well with a GUI and a\n\ mouse. For this reason they were re-used for 'Unison Chording' discussed above.\n\ Implementing them as sustain pedals would have been an easier if less flexible\n\ option and users are advised that the bristol MIDI library does recognise the\n\ sustain controller as the logical alternative here.\n\ \n\ Another difference would be the quality of the sound. The emulation is a lot\n\ cleaner and not as phat as the original. You might say it sounds more like\n\ something that comes from Uranus rather than Jupiter and consideration was\n\ indeed given to a tongue in cheek renaming of the emulation..... The author is\n\ allowed this criticism as he wrote the application - as ever, if you want the\n\ original sound then buy the original synth (or get Rolands own emulation?).\n\ \n\ A few notes are required on oscillator sync since by default it will seem to \n\ be quite noisy. The original could only product a single waveform at a single\n\ frequency at any one time. Several emulators, including this one, use a bitone\n\ oscillator which generates complex waveforms. The Bristol Bitone can generate\n\ up to 4 waveforms simultaneously at different levels for 5 different harmonics\n\ and the consequent output is very rich, the waves can be slightly detuned, \n\ the pulse output can be PW modulated. As with all the bristol oscillators that\n\ support sync, the sync pulse is extracted as a postive leading zero crossing.\n\ Unfortunately if the complex bitone output is used as input to sync another\n\ oscillator then the result is far too many zero crossings to extract a good\n\ sync. For the time being you will have to simplify the sync source to get a\n\ good synchronised output which itself may be complex wave. A future release\n\ will add a sync signal from the bitone which will be a single harmonic at the\n\ base frequency and allow both syncing and synchronised waveform outputs to be\n\ arbitrary.\n\ \n", " CRUMAR BIT-1, BIT-99, BIT-100\n\ -----------------------------\n\ \n\ I was considering the implementation of the Korg-800, a synth I used to borrow\n\ without having due respect for it - it was a late low cost analogue having \n\ just one filter for all the notes and using the mildly annoying data entry\n\ buttons and parameter selectors. Having only one filter meant that with key\n\ tracking enabled the filter would open up as different keys were pressed,\n\ wildly changing the sound of active notes. Anyway, whilst considering how to\n\ implement the entry keys (and having features like the mouse tracking the\n\ selectors of the parameter graphics) I was reminded of this synthesizer. It\n\ was developed by Crumar but released under the name 'Bit' as the Crumar name\n\ was associated with cheesy roadrunner electric pianos at the time (also\n\ emulated by Bristol). This came out at the same time as the DX-7 but for\n\ half the price, and having the split and layer facilities won it several awards\n\ that would otherwise have gone to the incredibly innovative DX. However with\n\ the different Crumar models being released as the digital era began they kind\n\ of fell between the crack. It has some very nice mod features though, it was\n\ fun to emulate and hopefully enjoyable to play with.\n\ \n\ As a side note, the Korg Poly-800 is now also emulated by bristol\n\ \n\ A quick rundown of the Bit features are below. The different emulated models\n\ have slightly different default parameter values and/or no access to change\n\ them:\n\ \n\ Two DCO with mixed waveforms.\n\ VCF with envelope\n\ VCA with envelope\n\ Two LFO able to mod all other components, controlled by the wheel and key\n\ velocity, single waveform, one had ramp and the other sawtooth options.\n\ \n\ The envelopes were touch sensitive for gain but also for attack giving plenty \n\ of expressive capabilities. The bristol envelope, when configured for velocity\n\ sensitive parameters (other than just gain) will also affect the attack rate.\n\ \n\ The front panel had a graphic that displayed all the available parameters and\n\ to change then you had to select the \"Address\" entry point then use the up/down\n\ entry buttons to change its value. Bristol uses this with the addition that the\n\ mouse can click on a parameter to start entering modifications to it.\n\ \n\ The emulation includes the 'Compare' and 'Park' features although they are a\n\ little annoying without a control surface. They work like this (not quite the\n\ same as the original): When you select a parameter and change it's value then\n\ the changes are not actually made to the active program, they just change the\n\ current sounds. The Compare button can be used to flip between the last loaded\n\ value and the current modified one to allow you to see if you prefer the sound\n\ before or after the modification.\n\ \n\ If you do prefer the changes then to keep them you must \"Park\" them into the\n\ running program before saving the memory. At the time of writing the emulation\n\ emulated the double click to park&write a memory, however it also has an actual\n\ Save button since 'Save to Tape' is not a feature here. You can use park and\n\ compare over dual loaded voices: unlike the original, which could only support\n\ editing of sounds when not in split/double, this emulation allows you to edit\n\ both layers by selecting the upper/lower entry buttons and then using the\n\ sensitive panel controls to select the addressed parameters. This is not the\n\ default behaviour, you first have to edit address 102 and increment it. Then,\n\ each layer can be simultaneously edited and just needs to be parked and saved\n\ separately. The Park/Compare cache can be disabled by editing parameter DE 101,\n\ changes are then made to the synth memory and not the cache.\n\ \n\ The memories are organised differently to the original. It had 99 memories, and\n\ the ones from 75 and above were for Split and Layered memories. Bristol can \n\ have all memories as Split or Layer. When you save a memory it is written to\n\ memory with a 'peer' program locator. When you load it with a single push on \n\ the Load button it returns to the active program, but if you double click then\n\ its 'peer' program is loaded into the other layer: press Load once to get the\n\ first program entered, then press it again - the Split/Layer will be set to\n\ the value from the first program and the second layer will be loaded. This \n\ naturally requires that the first memory was saved with Split/Layer enabled.\n\ It is advised (however not required) that this dual loading is done from the\n\ lower layer. This sequence will allow the lower layer to configure certain\n\ global options that the upper layer will not overwrite, for example the layer\n\ volumes will be select from the lower layer when the upper layer is dual \n\ loaded.\n\ \n\ For MIDI program change then since this quirky interface cannot be emulated\n\ then the memories above 75 will be dual loaded, the rest will be single loaded.\n\ \n\ Bristol will also emulate a bit-99 and a Bit-99m2 that includes some parameter\n\ on the front panel that were not available on the original. The engine uses the\n\ exact same algorithm for all emulations but the GUI presents different sets of\n\ parameters on the front panel. Those that are not displayed can only be accessed\n\ from the data entry buttons. The -99m2 put in a few extra features (ie, took a\n\ few liberties) that were not in the original:\n\ \n\ DCO adds PWM from the LFO, not in the original\n\ DCO-2 adds Sync to DCO-1, also not in the original\n\ DCO-2 adds FM from DCO-1\n\ DCO add PWM from Envelope\n\ Glide has been added\n\ DCO harmonics are not necessarily exclusive\n\ Various envelope option for LFO\n\ S&H LFO modulation\n\ \n\ The reason these were added was that bristol could already do them so were\n\ quite easy to incorporate, and at least gave two slightly different emulations.\n\ \n\ The oscillators can work slightly differently as well. Since this is a purely\n\ digital emulations then the filters are a bit weak. This is slightly compensated\n\ by the ability to configure more complex DCO. The transpose selectors (32', 16',\n\ 8' and 2') were exclusive in the original. That is true here also, however if\n\ controllers 84 and 85 are set to zero then they can all work together to fatten\n\ out the sound. Also, the controllers look like boolean however that is only the\n\ case if the data entry buttons are used, if you change the value with the data\n\ entry pot then they act more like continuous drawbars, a nice effect however \n\ the display will not show the actual value as the display remains boolean, you\n\ have to use your ear. The square wave is exclusive and will typically only \n\ function on the most recently selected (ie, typically highest) harmonic.\n\ \n\ The same continuous control is also available on the waveform selectors. You\n\ can mix the waveform as per the original however the apparent boolean selectors\n\ are again continuous from 0.0 to 1.0. The net result is that the oscillators \n\ are quite Voxy having the ability to mix various harmonic levels of different\n\ mixable waveforms.\n\ \n\ The stereo mode should be correctly implemented too. The synth was not really\n\ stereo, it had two outputs - one for each layer. As bristol is stereo then each\n\ layer is allocated to the left or right channel. In dual or split they came\n\ out separate feeds if Stereo was selected. This has the rather strange side\n\ effect of single mode with 6 voices. If stereo is not selected then you have\n\ a mono synth. If stereo is selected then voices will exit from a totally \n\ arbitrary output depending on which voices is allocated to each note.\n\ In contrast to the original the Stereo parameter is saved with the memory and\n\ if you dual load a split/layer it is taken from the first loaded memory only.\n\ The implementation actually uses two different stereo mixes selectable with the\n\ Stereo button: Mono is a centre pan of the signal and Stereo pans hardleft and\n\ hardright respectively. These mixes can be changed with parameters 110 to 117\n\ using extended data entry documented below.\n\ \n\ The default emulation takes 6 voices for unison and applies 3+3 for the split\n\ and double modes. You can request more, for example if you used '-voices 16'\n\ at startup then you would be given 8+8. As a slight anomaly you cant request 32\n\ voices - this is currently interpreted as the default and gives you 3+3.\n\ \n\ The bit-1 did not have the Stereo control - the controller presented is the\n\ Unison button. You can configure stereo from the extended data entry ID 110 and\n\ 111 which give the LR channel panning for 'Mono' setting, it should default to\n\ hard left and right panning. Similarly the -99 emulations do not have a Unison\n\ button, the capability is available from DE 80.\n\ \n\ The memories for the bit-1 and bit-99 should be interchangeable however the\n\ code maintains separate directories.\n\ \n\ There are three slightly different Bit GUI's. The first is the bit-1 with a \n\ limited parameter set as it only had 64 parameters. The second is the bit-99\n\ that included midi and split options in the GUI and has the white design that\n\ was an offered by Crumar. The third is a slightly homogenous design that is \n\ specific to bristol, similar to the black panelled bit99 but with a couple of\n\ extra parameters. All the emulations have the same parameters, some require you\n\ use the data entry controls to access them. This is the same as the original, \n\ there were diverse parameters that were not in memories that needed to be\n\ entered manually every time you wanted the feature. The Bristol Bit-99m2 has\n\ about all of the parameters selectable from the front panel however all of the\n\ emulations use the same memories so it is not required to configure them at\n\ startup (ie, they are saved). The emulation recognises the following parameters:\n\ \n\ Data Entry 1 LFO-1 triangle wave selector (exclusive switch)\n\ Data Entry 2 LFO-1 ramp wave selector (exclusive switch)\n\ Data Entry 3 LFO-1 square wave selector (exclusive switch)\n\ Data Entry 4 LFO-1 route to DCO-1\n\ Data Entry 5 LFO-1 route to DCO-2\n\ Data Entry 6 LFO-1 route to VCF\n\ Data Entry 7 LFO-1 route to VCA\n\ Data Entry 8 LFO-1 delay\n\ Data Entry 9 LFO-1 frequency\n\ Data Entry 10 LFO-1 velocity to frequency sensitivity\n\ Data Entry 11 LFO-1 gain\n\ Data Entry 12 LFO-1 wheel to gain sensitivity\n\ \n\ Data Entry 13 VCF envelope Attack\n\ Data Entry 14 VCF envelope Decay\n\ Data Entry 15 VCF envelope Sustain\n\ Data Entry 16 VCF envelope Release\n\ Data Entry 17 VCF velocity to attack sensitivity (and decay/release) \n\ Data Entry 18 VCF keyboard tracking\n\ Data Entry 19 VCF cutoff\n\ Data Entry 20 VCF resonance\n\ Data Entry 21 VCF envelope amount\n\ Data Entry 22 VCF velocity to gain sensitivity\n\ Data Entry 23 VCF envelope invert\n\ \n\ Data Entry 24 DCO-1 32' harmonic\n\ Data Entry 25 DCO-1 16' harmonic\n\ Data Entry 26 DCO-1 8' harmonic\n\ Data Entry 27 DCO-1 4' harmonic\n\ Data Entry 28 DCO-1 Triangle wave\n\ Data Entry 29 DCO-1 Ramp wave\n\ Data Entry 30 DCO-1 Pulse wave\n\ Data Entry 31 DCO-1 Frequency 24 semitones\n\ Data Entry 32 DCO-1 Pulse width\n\ Data Entry 33 DCO-1 Velocity PWM\n\ Data Entry 34 DCO-1 Noise level\n\ \n\ Data Entry 35 DCO-2 32' harmonic\n\ Data Entry 36 DCO-2 16' harmonic\n\ Data Entry 37 DCO-2 8' harmonic\n\ Data Entry 38 DCO-2 4' harmonic\n\ Data Entry 39 DCO-2 Triangle wave\n\ Data Entry 40 DCO-2 Ramp wave\n\ Data Entry 41 DCO-2 Pulse wave\n\ Data Entry 42 DCO-2 Frequency 24 semitones\n\ Data Entry 43 DCO-2 Pulse width\n\ Data Entry 44 DCO-2 Env to pulse width\n\ Data Entry 45 DCO-2 Detune\n\ \n\ Data Entry 46 VCA velocity to attack sensitivity (and decay/release) \n\ Data Entry 47 VCA velocity to gain sensitivity\n\ Data Entry 48 VCA overall gain ADSR\n\ Data Entry 49 VCA Attack\n\ Data Entry 50 VCA Decay\n\ Data Entry 51 VCA Sustain\n\ Data Entry 52 VCA Release\n\ \n\ Data Entry 53 LFO-2 triangle wave selector (exclusive switch)\n\ Data Entry 54 LFO-2 saw wave selector (exclusive switch)\n\ Data Entry 55 LFO-2 square wave selector (exclusive switch)\n\ Data Entry 56 LFO-2 route to DCO-1\n\ Data Entry 57 LFO-2 route to DCO-2\n\ Data Entry 58 LFO-2 route to VCF\n\ Data Entry 59 LFO-2 route to VCA\n\ Data Entry 60 LFO-2 delay\n\ Data Entry 61 LFO-2 frequency\n\ Data Entry 62 LFO-2 velocity to frequency sensitivity\n\ Data Entry 63 LFO-2 gain\n\ Data Entry 12 LFO-2 wheel to gain sensitivity\n\ \n\ Data Entry 64 Split\n\ Data Entry 65 Upper layer transpose\n\ Data Entry 66 Lower Layer gain\n\ Data Entry 67 Upper Layer gain\n\ \n\ The following were visible in the Bit-99 graphics only:\n\ \n\ Data Entry 68 MIDI Mod wheel depth\n\ Data Entry 69 MIDI Velocity curve (0 = soft, 10=linear, 25 = hard)\n\ Data Entry 70 MIDI Enable Debug\n\ Data Entry 71 MIDI Enable Program Change\n\ Data Entry 72 MIDI Enable OMNI Mode\n\ Data Entry 73 MIDI Receive channel\n\ \n\ Data Entry 74 MIDI Mem Search Upwards\n\ Data Entry 75 MIDI Mem Search Downwards\n\ Data Entry 76 MIDI Panic (all notes off)\n\ \n\ Most of the MIDI options are not as per the original. This is because they are\n\ implemented in the bristol MIDI library and not the emulation.\n\ \n\ The following were added which were not really part of the Bit specifications\n\ so are only visible on the front panel of the bit100. For the other emulations\n\ they are accessible from the address entry buttons.\n\ \n\ Data Entry 77 DCO-1->DCO-2 FM\n\ Data Entry 78 DCO-2 Sync to DCO-1\n\ Data Entry 79 Keyboard glide\n\ Data Entry 80 Unison\n\ \n\ Data Entry 81 LFO-1 SH\n\ Data Entry 82 LFO-1 PWM routing for DCO-1\n\ Data Entry 83 LFO-1 PWM routing for DCO-2\n\ Data Entry 84 LFO-1 wheel tracking frequency\n\ Data Entry 85 LFO-1 velocity tracking gain\n\ Data Entry 86 LFO-1 per layer or per voice\n\ \n\ Data Entry 87 LFO-2 SH\n\ Data Entry 88 LFO-2 PWM routing for DCO-1\n\ Data Entry 89 LFO-2 PWM routing for DCO-2\n\ Data Entry 90 LFO-2 wheel tracking frequency\n\ Data Entry 91 LFO-2 velocity tracking gain\n\ Data Entry 92 LFO-2 per layer or per voice\n\ \n\ Data Entry 93 ENV-1 PWM routing for DCO-1\n\ Data Entry 94 ENV-1 PWM routing for DCO-2\n\ \n\ Data Entry 95 DCO-1 restricted harmonics\n\ Data Entry 96 DCO-2 restricted harmonics\n\ \n\ Data Entry 97 VCF Filter type\n\ Data Entry 98 DCO-1 Mix\n\ \n\ Data Entry 99 Noise per layer\n\ \n\ Data Entry 00 Extended data entry (above 99)\n\ \n\ Extended data entry is for all parameters above number 99. Since the displays\n\ only have 2 digits it is not totally straightforward to enter these values and\n\ they are only available in Single mode, not dual or split - strangely similar\n\ to the original specification for editing memories. These are only activated for\n\ the lower layer loaded memory, not for dual loaded secondaries or upper layer\n\ loaded memories. You can edit the upper layer voices but they will be saved with\n\ their original extended parameters. This may seem correct however it is possible\n\ to edit an upper layer voice, save it, and have it sound different when next\n\ loaded since the extended parameters were taken from a different lower layer.\n\ This is kind of intentional but if in doubt then only ever dual load voices from\n\ the lower layer and edit them in single mode (not split or layer). Per default\n\ the emulation, as per the original, will not allow voice editing in Split or\n\ Layer modes however it can be enabled with DE 102.\n\ \n\ All the Bit emulations recognise extended parameters. They are somewhat in a\n\ disorganised list as they were built in as things developed. For the most part\n\ they should not be needed.\n\ The Bit-100 includes some in its silkscreen, for the others you can access them\n\ as follows:\n\ \n\ 1. deselect split or double\n\ 2. select addr entry\n\ 3. use 0..9 buttons to enter address 00\n\ 4. increment value to '1'. Last display should show EE (Extended Entry)\n\ \n\ 5. select last two digits of desired address with 0-9 buttons\n\ 6. change value (preferably with pot).\n\ \n\ 7. when finished, select address 00 again (this is now actually 100) to exit\n\ \n\ Data Entry 100 Exit extended data entry\n\ Data Entry 101 enable WriteThru scratchpad (disables park and compare)\n\ Data Entry 102 enable layer edits on Split/Double memories.\n\ Data Entry 103 LFO-1 Sync to note on\n\ Data Entry 104 LFO-2 Sync to note on\n\ Data Entry 105 ENV-1 zero retrigger\n\ Data Entry 106 ENV-2 zero retrigger\n\ Data Entry 107 LFO-1 zero retrigger\n\ Data Entry 108 LFO-2 zero retrigger\n\ Data Entry 109 Debug enable (0 == none, 5 == persistent)\n\ \n\ Data Entry 110 Left channel Mono gain, Lower\n\ Data Entry 111 Right channel Mono gain, Lower\n\ Data Entry 112 Left channel Stereo gain, Lower\n\ Data Entry 113 Right channel Stereo gain, Lower\n\ Data Entry 114 Left channel Mono gain, Upper\n\ Data Entry 115 Right channel Mono gain, Upper\n\ Data Entry 116 Left channel Stereo gain, Upper\n\ Data Entry 117 Right channel Stereo gain, Upper\n\ Data Entry 118 Bit-100 flag\n\ Data Entry 119 Temperature sensitivity\n\ \n\ Data Entry 120 MIDI Channel tracking layer-2 (same/different channel)\n\ Data Entry 121 MIDI Split point tracking layer-2 (same/different split)\n\ Data Entry 122 MIDI Transpose tracking (layer-2 or both layers) N/A\n\ Data Entry 123 MIDI NRP enable\n\ \n\ Data Entry 130 Free Memory Search Up\n\ Data Entry 131 Free Memory Search Down\n\ Data Entry 132 ENV-1 Conditional\n\ Data Entry 133 ENV-2 Conditional\n\ Data Entry 134 LFO-1 ENV Conditional\n\ Data Entry 135 LFO-2 ENV Conditional\n\ Data Entry 136 Noise white/pink\n\ Data Entry 137 Noise pink filter (enable DE 136 Pink)\n\ Data Entry 138 Glide duration 0 to 30 seconds\n\ Data Entry 139 Emulation gain level\n\ \n\ Data Entry 140 DCO-1 Square wave gain\n\ Data Entry 141 DCO-1 Subharmonic level\n\ Data Entry 142 DCO-2 Square wave gain\n\ Data Entry 143 DCO-2 Subharmonic level\n\ \n\ The 150 range will be incorporated when the Arpeggiator code is more stable,\n\ currently in development for the Jupiter. This is anticipated in 0.20.4:\n\ \n\ Data Entry 150 Arpeggiator Start/Stop\n\ Data Entry 151 Arpeggiator mode D, U/D, U or Random\n\ Data Entry 152 Arpeggiator range 1, 2, 3, 4 octaves\n\ Data Entry 153 Arpeggiator rate\n\ Data Entry 154 Arpeggiator external clock\n\ Data Entry 155 Arpeggiator retrigger envelopes\n\ Data Entry 156 Arpeggiator poly-2 mode\n\ Data Entry 157 Chord Enable\n\ Data Entry 158 Chord Relearn\n\ Data Entry 159 Sequencer Start/Stop\n\ Data Entry 160 Sequencer mode D, U/D, U or Random\n\ Data Entry 161 Sequencer range 1, 2, 3, 4 octaves\n\ Data Entry 162 Sequencer rate\n\ Data Entry 163 Sequencer external clock\n\ Data Entry 164 Sequencer retrigger envelopes\n\ Data Entry 165 Sequencer Relearn\n\ \n\ The following can be manually configured but are really for internal uses only\n\ and will be overwritten when memories are saved to disk. The Split/Join flag,\n\ for example, is used by dual loading memories to configure the peer layer to\n\ load the memory in DE-198, and the stereo placeholder for configuring the stereo\n\ status of any single loaded memory.\n\ \n\ Data Entry 193 Reserved: save bit-1 formatted memory\n\ Data Entry 194 Reserved: save bit-99 formatted memory\n\ Data Entry 195 Reserved: save bit-100 formatted memory\n\ Data Entry 196 Reserved: Split/Join flag - internal use\n\ Data Entry 197 Reserved: Stereo placeholder - internal use\n\ Data Entry 198 Reserved: Peer memory pointer - internal use\n\ Data Entry 199 Reserved: DCO-2 Wheel mod (masks entry 12) - internal use\n\ \n\ The tuning control in the emulation is on the front panel rather than on the\n\ rear panel as in the original. It had a keyboard sensitivity pot however that\n\ is achieved separately with bristol using velocity curves from the MIDI control\n\ settings. The front panel rotary defaults to 0% tuning and is not saved in the\n\ memory. The front panel gain controls are also not saved in the memory and\n\ default to 0.8 at startup.\n\ \n\ The net emulation is pretty intensive as it runs with over 150 operational\n\ parameters.\n\ \n\ A few notes are required on oscillator sync since by default it may seem to \n\ be quite noisy. The original could only produce a single waveform at a single\n\ frequency at any one time. Several emulators, including this one, use a bitone\n\ oscillator which generates complex waveforms. The Bristol Bitone can generate\n\ up to 4 waveforms simultaneously at different levels for 5 different harmonics\n\ and the consequent output is very rich, the waves can be slightly detuned, \n\ the pulse output can be PW modulated. As with all the bristol oscillators that\n\ support sync, the sync pulse is extracted as a postive leading zero crossing.\n\ Unfortunately if the complex bitone output is used as input to sync another\n\ oscillator then the result is far too many zero crossings to extract a good\n\ sync.\n\ Code has been implemented to generate a second sync source using a side output\n\ sync wave which is then fed to a sideband sync input on the oscillator, the\n\ results are far better\n\ \n", NULL, /* Master */ NULL, /* CS-80 */ " Sequential Circuits Prophet Pro-One\n\ -----------------------------------\n\ \n\ Sequential circuits released amongst the first truly polyphonic synthesisers\n\ where a group of voice circuits (5 to 10 of them) were linked to an onboard\n\ computer that gave the same parameters to each voice and drove the notes to\n\ each voice from the keyboard. The costs were nothing short of exhorbitant and\n\ this lead to Sequential releasing a model with just one voice board as a mono-\n\ phonic equivalent. The sales ran up to 10,000 units, a measure of its success\n\ and it continues to be recognised alongside the Mini Moog as a fat bass synth.\n\ \n\ The design of the Prophet synthesisers follows that of the Mini Moog. It has\n\ three oscillators one of them as a dedicated LFO. The second audio oscillator\n\ can also function as a second LFO, and can cross modulate oscillator A for FM \n\ type effects. The audible oscillators have fixed waveforms with pulse width\n\ modulation of the square wave. These are then mixed and sent to the filter with\n\ two envelopes, for the filter and amplifier.\n\ \n\ The Pro-1 had a nice bussing matrix where 3 different sources, LFO, Filter Env\n\ and Oscillator-B could be mixed in varying amounts to two different modulation\n\ busses and each bus could then be chosen as inputs to modulation destinations.\n\ One bus was a direct bus from the mixed parameters, the second bus was under\n\ the modwheel to give configurable expressive control.\n\ \n\ LFO:\n\ \n\ Frequency: 0.1 to 50 Hz\n\ Shape: Ramp/Triangle/Square. All can be selected, none selected should\n\ give a sine wave\n\ \n\ Modulations:\n\ \n\ Source:\n\ \n\ Filter Env amount to Direct or Wheel Mod busses\n\ Oscillator-B amount to Direct or Wheel Mod busses\n\ LFO to Direct amount or Wheel Mod busses\n\ \n\ Dest:\n\ \n\ Oscillator-A frequency from Direct or Wheel Mod busses\n\ Oscillator-A PWM from Direct or Wheel Mod busses\n\ Oscillator-B frequency from Direct or Wheel Mod busses\n\ Oscillator-B PWM from Direct or Wheel Mod busses\n\ Filter Cutoff from Direct or Wheel Mod busses\n\ \n\ Osc-A:\n\ \n\ Tune: +/-7 semitones\n\ Freq: 16' to 2' in octave steps\n\ Shape: Ramp or Square\n\ Pulse Width: only when Square is active.\n\ Sync: synchronise to Osc-B\n\ \n\ Osc-B:\n\ \n\ Tune: +/-7 semitones\n\ Freq: 16' to 2' in octave steps\n\ Fine: +/- 7 semitones\n\ Shape: Ramp/Triangle/Square\n\ Pulse Width: only when Square is active.\n\ LFO: Lowers frequency by 'several' octaves.\n\ KBD: enable/disable keyboard tracking.\n\ \n\ Mixer:\n\ \n\ Gain for Osc-A, Osc-B, Noise\n\ \n\ Filter:\n\ \n\ Cutoff: cuttof frequency\n\ Res: Resonance/Q/Emphasis\n\ Env: amount of modulation affecting to cutoff.\n\ KBD: amount of keyboard trackingn to cutoff\n\ \n\ Envelopes: One each for PolyMod (filter) and amplifier.\n\ \n\ Attack\n\ Decay\n\ Sustain\n\ Release\n\ \n\ Sequencer:\n\ \n\ On/Off\n\ Record Play\n\ Rate configured from LFO\n\ \n\ Arpeggiator:\n\ \n\ Up/Off/UpDown\n\ Rate configured from LFO\n\ \n\ Glide:\n\ \n\ Amount of portamento\n\ Auto/Normal - first key will/not glide.\n\ \n\ Global:\n\ \n\ Master Tune\n\ Master Volume\n\ \n\ \n\ Memories are loaded by selecting the 'Bank' button and typing in a two digit\n\ bank number followed by load. Once the bank has been selected then 8 memories\n\ from the bank can be loaded by pressing another memory select and pressing\n\ load. The display will show free memories (FRE) or programmed (PRG).\n\ There is an additional Up/Down which scan for the next program and a 'Find'\n\ key which will scan up to the next unused memory location.\n\ \n\ The original supported two sequences, Seq1 and Seq2, but these have not been\n\ implemented. Instead the emulator will save a sequence with each memory location\n\ which is a bit more flexible if not totally in the spirit of the original.\n\ \n\ The Envelope amount for the filter is actually 'Mod Amount'. To get the filter\n\ envelope to drive the filter it must be routed to the filter via a mod bus. This\n\ may differ from the original.\n\ Arpeggiator range is two octaves.\n\ The Mode options may not be correctly implemented due to the differences in\n\ the original being monophonic and the emulator being polyphonic. The Retrig is\n\ actually 'rezero' since we have separate voices. Drone is a Sustain key that\n\ emulates a sustain pedal.\n\ Osc-B cannot modulate itself in polyphonic mode (well, it could, it's just that\n\ it has not been coded that way).\n\ The filter envelope is configured to ignore velocity.\n\ \n\ The default filters are quite expensive. The -lwf option will select the less\n\ computationally expensive lightweight Chamberlain filters which have a colder\n\ response but require zonks fewer CPU cycles.\n\ \n", NULL, /* Voyager = explorer, stuff later */ " Moog Sonic-6\n\ ------------\n\ \n\ This original design was made by an engineer who had previously worked with \n\ Moog on the big modular systems, Gene Zumchek. He tried to get Moog Inc to \n\ develop a small standalone unit rather than the behemoths however he could \n\ not get heard. After leaving he built a synth eventually called a Sonic-5 that\n\ did fit the bill but sales volumes were rather small. He had tied up with a\n\ business manager who worked out that the volume was largely due to the name\n\ not being known, muSonics.\n\ This was quickly overcome by accident. Moog managed to run his company into\n\ rather large debt and the company folded. Bill Waytena, working with Zumcheck,\n\ gathered together the funding needed to buy the remains of the failed company\n\ and hence Moog Inc was labled on the rebadged Sonic-6. Zumcheck was eventually\n\ forced to leave this company (or agreed to) as he could not work with Moog.\n\ After a few modifications Bob Moog actually used this unit quite widely for\n\ lecturing on electronic music. For demonstrative purposes it is far more\n\ flexible than any of Moog's own non-modular designs and it was housed in a\n\ transport case rather than needing a shipping crate as the modular systems\n\ required.\n\ \n\ The emulation features are given below, but first a few of the differences to \n\ the original\n\ \n\ Added a mod wheel that can drive GenX/Y.\n\ PWM is implemented on the oscillator B\n\ Installed an ADSR rather than AR, selectable.\n\ No alternative scalings - use scala file support\n\ Not duo or dia phonic. Primarily poly with separated glide.\n\ \n\ The original was duophonic, kind of. It had a keyboard with high note and low\n\ note precedence and the two oscillators could be driven from different notes.\n\ Its not really duophony and was reportedly not nice to play but it added some\n\ flexibility to the instrument. This features was dropped largley because it\n\ is ugly to emulate in a polyphonic environment but the code still has glide\n\ only on Osc-B. It has the two LFO that can be mixed, or at full throw of the \n\ GenXY mixer they will link X->A and Y->B giving some interesting routing, two\n\ osc each with their own LFO driving the LFO from the mod wheel or shaping it\n\ with the ADSR. Playing around should give access to X driving Osc-A, then \n\ Osc-A and GenY driving Osc-B with Mod and shaping for some investigation of\n\ FM synthesis. The gruesome direct output mixer is still there, having the osc\n\ and ring-mod bypass the filter and amplifier completely (or can be mixed back\n\ into the 'actuated' signal).\n\ \n\ There is currently no likely use for an external signal even though the\n\ graphics are there.\n\ \n\ The original envelope was AR or ASR. The emulator has a single ADSR and a \n\ control switch to select AR (actually AD), ASR, ADSD (MiniMoog envelope) or\n\ ADSR.\n\ \n\ Generator-Y has a S/H function on the noise source for a random signal which \n\ replaced the square wave. Generator-X still has a square wave.\n\ \n\ Modulators:\n\ \n\ Two LFO, X and Y:\n\ \n\ Gen X:\n\ Tri/Ramp/Saw/Square\n\ Tuning\n\ Shaping from Envelope or Modwheel\n\ \n\ Gen Y:\n\ Tri/Ramp/Saw/Rand\n\ Tuning\n\ Shaping from Envelope or Modwheel\n\ \n\ Master LFO frequency\n\ \n\ GenXY mixer\n\ \n\ Two Oscillators, A and B\n\ \n\ Gen A:\n\ Tri/Ramp/Pulse\n\ PulseWidth\n\ Tuning\n\ Transpose 16', 8', 4' (*)\n\ \n\ Mods:\n\ \n\ Envelope\n\ GenXY(or X)\n\ Low frequency, High Frequency (drone), KBD Tracking\n\ \n\ Gen B:\n\ Tri/Ramp/Pulse\n\ PulseWidth\n\ Tuning\n\ Transpose 16' 8', 4'\n\ \n\ Mods:\n\ \n\ Osc-B\n\ GenXY(or Y)\n\ PWM\n\ \n\ GenAB mix\n\ \n\ Ring Mod:\n\ \n\ Osc-B/Ext\n\ GenXY/Osc-A\n\ \n\ Noise\n\ \n\ Pink/White\n\ \n\ Mixer\n\ \n\ GenAB\n\ RingMod\n\ External\n\ Noise\n\ \n\ Filter (**)\n\ \n\ Cutoff\n\ Emphasis\n\ \n\ Mods:\n\ \n\ ADSR\n\ Keyboard tracking\n\ GenXY\n\ \n\ Envelope:\n\ \n\ AR/ASR/ADSD/ADSR\n\ Velociy on/off\n\ \n\ Trigger:\n\ \n\ GenX\n\ GenY\n\ Kbd (rezero only)\n\ \n\ Bypass (key gated audio)\n\ \n\ Direct Output Mixer\n\ \n\ Osc-A\n\ Osc-B\n\ RingMod\n\ \n\ \n\ The keyboard has controls for\n\ \n\ Glide (Osc-B only)\n\ Master Volume\n\ PitchWheel\n\ ModWheel (gain modifier on LFO)\n\ \n\ Global Tuning\n\ \n\ MultiLFO X and Y\n\ \n\ * The oscillator range was +/-2 octave switch and a +/-1 octave pot. This\n\ emulator has +/-1 octave switch and +/-7 note pot. That may change in a future\n\ release to be more like the original, probably having a multiway 5 stage octave\n\ selector.\n\ \n\ ** The filter will self oscillate at full emphasis however this is less \n\ prominent at lower frequencies (much like the Moog ladder filter). The filter\n\ is also 'not quite' in tune when played as an oscillator, this will also change\n\ in a future release.\n\ \n\ There may be a reverb on the emulator. Or there may not be, that depends on\n\ release. The PitchWheel is not saved in the memories, the unit is tuned on\n\ startup and this will maintain tuning to other instruments. The MultiLFO allow\n\ you to configure single LFO per emulation or one per voice, independently.\n\ Having polyphony means you can have the extra richness of independent LFO per\n\ voice however that does not work well if they are used as triggers, for example,\n\ you end up with a very noisy result. With single triggers for all voices the\n\ result is a lot more predictable.\n\ \n\ The Sonic-6 as often described as having bad tuning, that probably depends on \n\ model since different oscillators were used at times. Also, different units\n\ had different filters (Zumchek used a ladder of diodes to overcome the Moog\n\ ladder of transister patent). The original was often described as only being\n\ useful for sound effects. Personally I don't think that was true however the\n\ design is extremely flexible and the mods are applied with high gains so to\n\ get subtle sounds they only have to be applied lightly. Also, this critique\n\ was in comparison to the Mini which was not great for sound effects since it,\n\ in contrast, had very little in the way of modifiers.\n\ \n\ The actual mod routing here is very rich. The two LFO can be mixed to provide\n\ for more complex waves and have independent signal gain from the ADSR. To go\n\ a step further it is possible to take the two mixed LFO into Osc-A, configure\n\ that as an LFO and feed it into Osc-B for some very complex mod signals. That\n\ way you can get a frequency modulated LFO which is not possible from X or Y. As\n\ stated, if these are applied heavily you will get ray guns and car alarms but\n\ in small amounts it is possible to just shape sounds. Most of the mod controls\n\ have been made into power functions to give more control at small values.\n\ \n\ The memory panel gives access to 72 banks of 8 memories each. Press the Bank\n\ button and two digits for the bank, then just select the memory and press Load.\n\ You can get the single digit banks by selecting Bank->number->Bank. There is\n\ a save button which should require a double click but does not yet (0.30.0),\n\ a pair of buttons for searching up and down the available memories and a button\n\ called 'Find' which will select the next available free memory.\n\ \n\ Midi options include channel, channel down and, er, thats it.\n\ \n", " CRUMAR TRILOGY\n\ --------------\n\ \n\ This text is primarily that of the Stratus since the two synths were very \n\ similar. This is the bigger brother having all the same features with the added\n\ string section. There were some minor differences in the synth circuits for\n\ switchable or mixable waveforms.\n\ \n\ This unit is a hybrid synth/organ/string combo, an early polyphonic using an\n\ organ divider circuit rather than independent VCO and having a set of filters\n\ and envelope for the synth sounds, most manufacturers came out with similar\n\ designs. The organ section was generally regarded as pretty bad here, there\n\ were just five controls, four used for the volume of 16, 8, 4 and 2 foot \n\ harmonics and a fifth for overall organ volume. The synth section had 6 voices\n\ and some quite neat little features for a glide circuitry and legato playing\n\ modes. The string section could mix 3 waveforms with vibrato on some so when\n\ mixed with the straight waveform would produce phasing.\n\ \n\ The emulator consists of two totally separate layers, one emulating the organ\n\ circuitry and another the synth. The organ has maximum available polyphony as\n\ the algorithm is quite lightweight even though diverse liberties have been\n\ taken to beef up the sound. The synth section is limited to 6 voices unless\n\ otherwise specified at run time. The organ circuitry is used to generate the\n\ string section.\n\ \n\ The legato playing modes affects three sections, the LFO modulation, VCO \n\ selection and glide:\n\ \n\ LFO: this mod has a basic envelope to control the gain of the LFO using delay,\n\ slope and gain. In 'multi' mode the envelope is triggered for every note that\n\ is played and in the emulator this is actually a separate LFO per voice, a bit\n\ fatter than the original. In 'Mono' mode there is only one LFO that all voices\n\ will share and the envelope is triggered in Legato style, ie, only once for\n\ a sequence of notes - all have to be released for the envelope to recover.\n\ \n\ VCO: The original allowed for wavaeform selection to alternate between notes, \n\ something that is rather ugly to do with the bristol architecture. This is \n\ replaced with a VCO selector where each note will only take the output from\n\ one of the two avalable oscillators and gives the ntoes a little more\n\ separation. The legato mode works whereby the oscillator selection is only\n\ made for the first note in a sequence to give a little more sound consistency.\n\ \n\ Glide: This is probably the coolest feature of the synth. Since it used an\n\ organ divider circuit it was not possible to actually glide from one note to\n\ another - there are really only two oscillators in the synth section, not two\n\ per voice. In contrast the glide section could glide up or down from a selected\n\ amount to the real frequency. Selected from down with suitable values would\n\ give a nice 'blue note' effect for example. In Legato mode this is done only\n\ for the first keypress rather than all of the since the effect can be a bit\n\ over the top if applied to each keystroke in a sequence. At the same time it\n\ was possible to Sync the two oscillators, so having only one of them glide \n\ and be in sync then without legato this gave a big phasing entrance to each\n\ note, a very interesting effect. The Glide has 4 modes:\n\ \n\ A. Both oscillators glide up to the target frequency\n\ B. Only oscillator-2 glides up to the target frequency\n\ C. Only oscillator-2 glides down to the target frequency\n\ D. Both oscillators glide down to the target frequency\n\ \n\ These glide options with different sync and legato lead to some very unique\n\ sounds and are emulated here with only minor differences.\n\ \n\ The features, then notes on the differences to the original:\n\ \n\ A. Organ Section\n\ \n\ 16, 8, 4 and 2 foot harmonic strengths.\n\ Volume.\n\ \n\ B. Synth Section\n\ \n\ LFO Modulation\n\ \n\ Rate - 0.1 to 50Hz approx\n\ Slope - up to 10 seconds\n\ Delay - up to 10 seconds\n\ Gain\n\ \n\ Routing selector: VCO, VCF, VCA\n\ Mono/Multi legato mode\n\ Shape - Tri/Ramp/Saw/Square\n\ \n\ Oscillator 1\n\ \n\ Tuning\n\ Sync 2 to 1\n\ Octave selector\n\ \n\ Oscillator 2\n\ \n\ Tuning\n\ Octave trill\n\ Octave selector\n\ \n\ Waveform Ramp and Square mix\n\ Alternate on/off\n\ Mono/Multi legato mode VCO selection\n\ \n\ Glide\n\ \n\ Amount up or down from true frequency\n\ Speed of glide\n\ Mono/Multi legato mode\n\ Direction A, B, C, D\n\ \n\ Filter\n\ \n\ Cutoff frequency\n\ Resonance\n\ Envelope tracking -ve to +ve\n\ Pedal tracking on/off\n\ \n\ Envelope\n\ \n\ Attack\n\ Decay\n\ Sustain\n\ Release\n\ \n\ Gain\n\ \n\ C. String Section\n\ \n\ 16' 8' mix\n\ Subharmonic gain\n\ Attack\n\ Release\n\ \n\ Volume\n\ \n\ Diverse liberties were taken with the reproduction, these are manageable from\n\ the options panel by selecting the button next to the keyboard. This opens up\n\ a graphic of a PCB, mostly done for humorous effect as it not in the least bit\n\ representative of the actual hardware. Here there are a number of surface\n\ mounted controllers. These are as below but may change by release:\n\ \n\ P1 Master volume\n\ \n\ P2 Organ pan\n\ P3 Organ waveform distorts\n\ P4 Organ spacialisation\n\ P5 Organ mod level\n\ J1 Organ key grooming \n\ P6 Organ tuning (currently inactive *)\n\ \n\ P7 Synth pan\n\ P8 Synth tuning\n\ P9 Synth osc1 harmonics\n\ P10 Synth osc2 harmonics\n\ J2 Synth velocity sensitivity\n\ J3 Synth filter type\n\ P11 Synth filter tracking\n\ \n\ P12 String pan\n\ P13 String harmonics\n\ P14 String spacialisation\n\ P15 String mod level\n\ P16 String waveform distorts\n\ \n\ *: To make the organ tunable the keymap file has to be removed.\n\ \n\ Master (P1) volume affects both layers simultaneously and each layer can be\n\ panned (P2/P7) and tuned (P8) separately to give phasing and spacialisation.\n\ The synth layer has the default frequency map of equal temperament however the\n\ organ section uses a 2MHz divider frequency map that is a few cents out for\n\ each key. The Trilogy actually has this map for both layers and that can easily\n\ be done with the emulator, details on request.\n\ \n\ It is currently not possible to retune the organ divider circuit, it has a\n\ private microtonal mapping to emulate the few percent anomalies of the divider\n\ circuit and the frequencies are predefined. The pot is still visible in P6 and\n\ can be activated by removing the related microtonal mapping file, details from\n\ the author on request.\n\ \n\ Diverse liberties were taken with the Organ section since the original only \n\ produced 4 pure (infinite bandwidth) square waves that were mixed together, \n\ an overly weak result. The emulator adds a waveform distort (P3), an notched\n\ control that produces a pure sine wave at centre point. Going down it will\n\ generate gradually increasing 3rd and 5th harmonics to give it a squarey wave\n\ with a distinct hammond tone. The distortion actually came from the B3 emulator\n\ which models the distort on the shape of the hammond tonewheels themselves.\n\ Going up from centre point will produce gradually sharper sawtooth waves using\n\ a different phase distortion.\n\ \n\ Organ spacialisation (P4) will separate out the 4 harmonics to give them \n\ slightly different left and right positions to fatten out the sound. This works\n\ in conjunction with the mod level (P5) where one of the stereo components of\n\ each wave is modified by the LFO to give phasing changes up to vibrato.\n\ \n\ The organ key grooming (J1) will either give a groomed wave to remove any\n\ audible clicks from the key on and off events or when selected will produce \n\ something akin to a percussive ping for the start of the note.\n\ \n\ The result for the organ section is that it can produce some quite nice sounds\n\ reminiscent of the farfisa range to not quite hammond, either way far more\n\ useful than the flat, honking square waves. The original sound can be made by\n\ waveform to a quarter turn or less, spacialisation and mod to zero, key\n\ grooming off.\n\ \n\ The synth has 5 modifications at the first release. The oscillator harmonics\n\ can be fattened at the top or bottom using P9 and P10, one control for each\n\ oscillator, low is more bass, high is more treble. Some of the additional\n\ harmonics will be automatically detuned a little to fatten out the sound as a\n\ function of the -detune parameter defaulting to 100.\n\ \n\ The envelope can have its velocity sensitively to the filter enabled or disabled\n\ (J2) and the filter type can be a light weight filter for a thinner sound but at\n\ far lower CPU load (J3).\n\ \n\ The filter keyboard tracking is configurable (P11), this was outside of the spec\n\ of the Trilogy however it was implemented here to correct the keyboard tracking\n\ of the filter for all the emulations and the filter should now be playable.\n\ The envelope touch will affect this depending on J2 since velocity affects the\n\ cut off frequency and that is noticeable when playing the filter. This jumper\n\ is there so that the envelope does not adversely affect tuning but can still be\n\ used to have the filter open up with velocity if desired.\n\ \n\ The mod application is different from the original. It had a three way selector\n\ for routing the LFO to either VCO, VCA or VCF but only a single route. This\n\ emulation uses a continuous notched control where full off is VCO only, notch\n\ is VCF only and full on is VCA however the intermidiate positions will route\n\ proportional amounts to two components.\n\ \n\ The LFO has more options (Ramp and Saw) than the original (Tri and Square).\n\ \n\ The extra options are saved with each memory however they are only loaded at\n\ initialisation and when the 'Load' button is double-clicked. This allows you to\n\ have them as global settings or per memory as desired. The MemUp and MemDown \n\ will not load the options, only the main settings.\n\ \n\ VCO mod routing is a little bit arbitrary in this first release however I could\n\ not find details of the actual implementation. The VCO mod routing only goes\n\ to Osc-1 which also takes mod from the joystick downward motion. Mod routing\n\ to Osc-2 only happens if 'trill' is selected. This seemed to give the most\n\ flexibility, directing the LFO to VCF/VCA and controlling vibrato from the \n\ stick, then having Osc-2 separate so that it can be modified and sync'ed to\n\ give some interesting phasing.\n\ \n\ As of the first release there are possibly some issues with the oscillator \n\ Sync selector, it is perhaps a bit noisy with a high content of square wave.\n\ Also, there are a couple of minor improvements that could be made to the \n\ legato features but they will be done in a future release. They regard how\n\ the glide is applied to the first or all in a sequence of notes.\n\ \n\ The joystick does not always pick up correctly however it is largely for \n\ presentation, doing actual work you would use a real joystick or just use the\n\ modwheel (the stick generates and tracks continuous controller 1 - mod). The\n\ modwheel tracking is also a bit odd but reflects the original architecture - \n\ at midpoint on the wheel there is no net modulation, going down affects VCO\n\ in increasing amounts and going up from mid affect the VCF. The control feels\n\ like it should be notched however generally that is not the case with mod\n\ wheels.\n\ \n\ A few notes are required on oscillator sync since by default it will seem to \n\ be quite noisy. The original could only product a single waveform at a single\n\ frequency at any one time. Several emulators, including this one, use a bitone\n\ oscillator which generates complex waveforms. The Bristol Bitone can generate\n\ up to 4 waveforms simultaneously at different levels for 5 different harmonics\n\ and the consequent output is very rich, the waves can be slightly detuned, \n\ the pulse output can be PW modulated. As with all the bristol oscillators that\n\ support sync, the sync pulse is extracted as a postive leading zero crossing.\n\ Unfortunately if the complex bitone output is used as input to sync another\n\ oscillator then the result is far too many zero crossings to extract a good\n\ sync. For the time being you will have to simplify the sync source to get a\n\ good synchronised output which itself may be complex wave. A future release\n\ will add a sync signal from the bitone which will be a single harmonic at the\n\ base frequency and allow both syncing and synchronised waveform outputs to be\n\ arbitrary. For the Trilogy this simplification of the sync waveform is done\n\ automatically by the Sync switch, this means the synchronised output sounds\n\ correct but the overall waveform may be simpler.\n\ \n", NULL, /* Trilogy ODC */ " CRUMAR STRATUS\n\ --------------\n\ \n\ This unit is a hybrid synth/organ combo, an early polyphonic synth using an\n\ organ divider circuit rather than independent VCO and having a set of filters\n\ and envelope for the synth sounds, most manufacturers came out with similar\n\ designs. The organ section was generally regarded as pretty bad here, there\n\ were just five controls, four used for the volume of 16, 8, 4 and 2 foot \n\ harmonics and a fifth for overall organ volume. The synth section had 6 voices\n\ and some quite neat little features for a glide circuitry and legato playing\n\ modes.\n\ \n\ The emulator consists of two totally separate layers, one emulating the organ\n\ circuitry and another the synth. The organ has maximum available polyphony as\n\ the algorithm is quite lightweight even though diverse liberties have been\n\ taken to beef up the sound. The synth section is limited to 6 voices unless\n\ otherwise specified at run time.\n\ \n\ The legato playing modes affects three sections, the LFO modulation, VCO \n\ selection and glide:\n\ \n\ LFO: this mod has a basic envelope to control the gain of the LFO using delay,\n\ slope and gain. In 'multi' mode the envelope is triggered for every note that\n\ is played and in the emulator this is actually a separate LFO per voice, a bit\n\ fatter than the original. In 'Mono' mode there is only one LFO that all voices\n\ will share and the envelope is triggered in Legato style, ie, only once for\n\ a sequence of notes - all have to be released for the envelope to recover.\n\ \n\ VCO: The original allowed for wavaeform selection to alternate between notes, \n\ something that is rather ugly to do with the bristol architecture. This is \n\ replaced with a VCO selector where each note will only take the output from\n\ one of the two avalable oscillators and gives the ntoes a little more\n\ separation. The legato mode works whereby the oscillator selection is only\n\ made for the first note in a sequence to give a little more sound consistency.\n\ \n\ Glide: This is probably the coolest feature of the synth. Since it used an\n\ organ divider circuit it was not possible to actually glide from one note to\n\ another - there are really only two oscillators in the synth section, not two\n\ per voice. In contrast the glide section could glide up or down from a selected\n\ amount to the real frequency. Selected from down with suitable values would\n\ give a nice 'blue note' effect for example. In Legato mode this is done only\n\ for the first keypress rather than all of the since the effect can be a bit\n\ over the top if applied to each keystroke in a sequence. At the same time it\n\ was possible to Sync the two oscillators, so having only one of them glide \n\ and be in sync then without legato this gave a big phasing entrance to each\n\ note, a very interesting effect. The Glide has 4 modes:\n\ \n\ A. Both oscillators glide up to the target frequency\n\ B. Only oscillator-2 glides up to the target frequency\n\ C. Only oscillator-2 glides down to the target frequency\n\ D. Both oscillators glide down to the target frequency\n\ \n\ These glide options with different sync and legato lead to some very unique\n\ sounds and are emulated here with only minor differences.\n\ \n\ The features, then notes on the differences to the original:\n\ \n\ A. Organ Section\n\ \n\ 16, 8, 4 and 2 foot harmonic strengths.\n\ Volume.\n\ \n\ B. Synth Section\n\ \n\ LFO Modulation\n\ \n\ Rate - 0.1 to 50Hz approx\n\ Slope - up to 10 seconds\n\ Delay - up to 10 seconds\n\ Gain\n\ \n\ Routing selector: VCO, VCF, VCA\n\ Mono/Multi legato mode\n\ Shape - Tri/Ramp/Saw/Square\n\ \n\ Oscillator 1\n\ \n\ Tuning\n\ Sync 2 to 1\n\ Octave selector\n\ \n\ Oscillator 2\n\ \n\ Tuning\n\ Octave trill\n\ Octave selector\n\ \n\ Waveform Ramp and Square mix\n\ Alternate on/off\n\ Mono/Multi legato mode VCO selection\n\ \n\ Glide\n\ \n\ Amount up or down from true frequency\n\ Speed of glide\n\ Mono/Multi legato mode\n\ Direction A, B, C, D\n\ \n\ Filter\n\ \n\ Cutoff frequency\n\ Resonance\n\ Envelope tracking -ve to +ve\n\ Pedal tracking on/off\n\ \n\ Envelope\n\ \n\ Attack\n\ Decay\n\ Sustain\n\ Release\n\ \n\ Gain\n\ \n\ Diverse liberties were taken with the reproduction, these are manageable from\n\ the options panel by selecting the button next to the keyboard. This opens up\n\ a graphic of a PCB, mostly done for humorous effect as it not in the least bit\n\ representative of the actual hardware. Here there are a number of surface\n\ mounted controllers. These are as below but may change by release:\n\ \n\ P1 Master volume\n\ \n\ P2 Organ pan\n\ P3 Organ waveform distorts\n\ P4 Organ spacialisation\n\ P5 Organ mod level\n\ J1 Organ key grooming \n\ P6 Organ tuning (currently inactive *)\n\ \n\ P7 Synth pan\n\ P8 Synth tuning\n\ P9 Synth osc1 harmonics\n\ P10 Synth osc2 harmonics\n\ J2 Synth velocity sensitivity\n\ J3 Synth filter type\n\ P11 Synth filter tracking\n\ \n\ *: To make the organ tunable the keymap file has to be removed.\n\ \n\ Master (P1) volume affects both layers simultaneously and each layer can be\n\ panned (P2/P7) and tuned (P8) separately to give phasing and spacialisation.\n\ The synth layer has the default frequency map of equal temperament however the\n\ organ section uses a 2MHz divider frequency map that is a few cents out for\n\ each key. The Stratus actually has this map for both layers and that can easily\n\ be done with the emulator, details on request.\n\ \n\ It is currently not possible to retune the organ divider circuit, it has a\n\ private microtonal mapping to emulate the few percent anomalies of the divider\n\ circuit and the frequencies are predefined. The pot is still visible in P6 and\n\ can be activated by removing the related microtonal mapping file, details from\n\ the author on request.\n\ \n\ Diverse liberties were taken with the Organ section since the original only \n\ produced 4 pure (infinite bandwidth) square waves that were mixed together, \n\ an overly weak result. The emulator adds a waveform distort (P3), an notched\n\ control that produces a pure sine wave at centre point. Going down it will\n\ generate gradually increasing 3rd and 5th harmonics to give it a squarey wave\n\ with a distinct hammond tone. The distortion actually came from the B3 emulator\n\ which models the distort on the shape of the hammond tonewheels themselves.\n\ Going up from centre point will produce gradually sharper sawtooth waves using\n\ a different phase distortion.\n\ \n\ Organ spacialisation (P4) will separate out the 4 harmonics to give them \n\ slightly different left and right positions to fatten out the sound. This works\n\ in conjunction with the mod level (P5) where one of the stereo components of\n\ each wave is modified by the LFO to give phasing changes up to vibrato.\n\ \n\ The organ key grooming (J1) will either give a groomed wave to remove any\n\ audible clicks from the key on and off events or when selected will produce \n\ something akin to a percussive ping for the start of the note.\n\ \n\ The result for the organ section is that it can produce some quite nice sounds\n\ reminiscent of the farfisa range to not quite hammond, either way far more\n\ useful than the flat, honking square waves. The original sound can be made by\n\ waveform to a quarter turn or less, spacialisation and mod to zero, key\n\ grooming off.\n\ \n\ The synth has 5 modifications at the first release. The oscillator harmonics\n\ can be fattened at the top or bottom using P9 and P10, one control for each\n\ oscillator, low is more bass, high is more treble. Some of the additional\n\ harmonics will be automatically detuned a little to fatten out the sound as a\n\ function of the -detune parameter defaulting to 100.\n\ \n\ The envelope can have its velocity sensitively to the filter enabled or disabled\n\ (J2) and the filter type can be a light weight filter for a thinner sound but at\n\ far lower CPU load (J3).\n\ \n\ The filter keyboard tracking is configurable (P11), this was outside of the spec\n\ of the Stratus however it was implemented here to correct the keyboard tracking\n\ of the filter for all the emulations and the filter should now be playable.\n\ The envelope touch will affect this depending on J2 since velocity affects the\n\ cut off frequency and that is noticeable when playing the filter. This jumper\n\ is there so that the envelope does not adversely affect tuning but can still be\n\ used to have the filter open up with velocity if desired.\n\ \n\ The mod application is different from the original. It had a three way selector\n\ for routing the LFO to either VCO, VCA or VCF but only a single route. This\n\ emulation uses a continuous notched control where full off is VCO only, notch\n\ is VCF only and full on is VCA however the intermidiate positions will route\n\ proportional amounts to two components.\n\ \n\ The LFO has more options (Ramp and Saw) than the original (Tri and Square).\n\ \n\ The extra options are saved with each memory however they are only loaded at\n\ initialisation and when the 'Load' button is double-clicked. This allows you to\n\ have them as global settings or per memory as desired. The MemUp and MemDown \n\ will not load the options, only the main settings.\n\ \n\ VCO mod routing is a little bit arbitrary in this first release however I could\n\ not find details of the actual implementation. The VCO mod routing only goes\n\ to Osc-1 which also takes mod from the joystick downward motion. Mod routing\n\ to Osc-2 only happens if 'trill' is selected. This seemed to give the most\n\ flexibility, directing the LFO to VCF/VCA and controlling vibrato from the \n\ stick, then having Osc-2 separate so that it can be modified and sync'ed to\n\ give some interesting phasing.\n\ \n\ As of the first release there are possibly some issues with the oscillator \n\ Sync selector, it is perhaps a bit noisy with a high content of square wave.\n\ Also, there are a couple of minor improvements that could be made to the \n\ legato features but they will be done in a future release. They regard how\n\ the glide is applied to the first or all in a sequence of notes.\n\ \n\ The joystick does not always pick up correctly however it is largely for \n\ presentation, doing actual work you would use a real joystick or just use the\n\ modwheel (the stick generates and tracks continuous controller 1 - mod). The\n\ modwheel tracking is also a bit odd but reflects the original architecture - \n\ at midpoint on the wheel there is no net modulation, going down affects VCO\n\ in increasing amounts and going up from mid affect the VCF. The control feels\n\ like it should be notched however generally that is not the case with mod\n\ wheels.\n\ \n\ A few notes are required on oscillator sync since by default it will seem to \n\ be quite noisy. The original could only product a single waveform at a single\n\ frequency at any one time. Several emulators, including this one, use a bitone\n\ oscillator which generates complex waveforms. The Bristol Bitone can generate\n\ up to 4 waveforms simultaneously at different levels for 5 different harmonics\n\ and the consequent output is very rich, the waves can be slightly detuned, \n\ the pulse output can be PW modulated. As with all the bristol oscillators that\n\ support sync, the sync pulse is extracted as a postive leading zero crossing.\n\ Unfortunately if the complex bitone output is used as input to sync another\n\ oscillator then the result is far too many zero crossings to extract a good\n\ sync. For the time being you will have to simplify the sync source to get a\n\ good synchronised output which itself may be complex wave. A future release\n\ will add a sync signal from the bitone which will be a single harmonic at the\n\ base frequency and allow both syncing and synchronised waveform outputs to be\n\ arbitrary. For the Stratus this simplification of the sync waveform is done\n\ automatically by the Sync switch, this means the synchronised output sounds\n\ correct but the overall waveform may be simpler.\n\ \n", " KORG POLY 800\n\ -------------\n\ \n\ This is a low cost hybrid synth, somewhere between the Korg PolySix and their\n\ Mono/Poly in that is polyphonic but only has one filter rather than one per\n\ voice that came with the PolySix. It may have also used organ divider circuits\n\ rather than individual oscillators - it did not have glide as a feature which\n\ would be indicative of a divider circuit.\n\ \n\ It featured 8 oscillators that could be applied as either 4 voices with dual\n\ osc or 8 voices with a single osc. The architecture was verging on the\n\ interesting since each oscillator was fead into an individual envelope generator\n\ (described below) and then summed into the single filter, the filter having\n\ another envelope generator, 9 in total. This lead to cost reduction over having\n\ a filter per voice however the single filter leads to breathing, also discussed\n\ below. The envelopes were digitally generated by an on-board CPU.\n\ \n\ The control panel has a volume, global tuning control and a 'Bend' control\n\ that governs the depth of the pitch bend from the joystick and the overall \n\ amount of DCO modulation applied by the joystick. There is no sequencer in\n\ this emulation largely because there are far better options now available than\n\ this had but also due to a shortage of onscreen realestate.\n\ \n\ The Poly, Chord and Hold keys are emulated, hold being a sustain key. The\n\ Chord relearn function works follows:\n\ \n\ Press the Hold key\n\ Press the Chord key with 2 seconds\n\ Press the notes on the keyboard (*)\n\ Press the Chord key again\n\ \n\ After that the single chord can be played from a single note as a monophonic\n\ instrument. The Chord is saved individually with each memory.\n\ * Note that the chord is only saved if (a) it was played from the GUI keyboard\n\ or (b) the GUI was linked up to any MIDI device as well as the engine. The \n\ reason is that the GUI maintains memories and so if a chord is played on your\n\ actual keyboard then both the engine and the GUI needs a copy, the engine to\n\ be able to play the notes and the GUI to be able to save them.\n\ \n\ The keypanel should function very similar to the original. There is a Prog \n\ button that selects between Program selection or Parameter selection and an \n\ LED should show where the action is. There is the telephone keyboard to enter\n\ program or parameters numbers and an up/down selector for parameter value.\n\ The Bank/Hold selector also works, it fixes the bank number so programs can\n\ be recalled from a single bank with a single button press. The Write function\n\ is as per the original - Press Write, then two digits to save a memory.\n\ \n\ The front panel consists of a data entry panel and a silkscreen of the parameter\n\ numbers (this silkscreen is active in the emulation). Fifty parameters are\n\ available from the original instrument:\n\ \n\ DE 11 DCO1 Octave transposition +2 octaves\n\ DE 12 DCO1 Waveform Square or Ramp\n\ DE 13 DCO1 16' harmonic\n\ DE 14 DCO1 8' harmonic\n\ DE 15 DCO1 4' harmonic\n\ DE 16 DCO1 2' harmonic\n\ DE 17 DCO1 level\n\ \n\ DE 18 DCO Double (4 voice) or Single (8 voice)\n\ \n\ DE 21 DCO2 Octave transposition +2 octaves\n\ DE 22 DCO2 Waveform Square or Ramp\n\ DE 23 DCO2 16' harmonic\n\ DE 24 DCO2 8' harmonic\n\ DE 25 DCO2 4' harmonic\n\ DE 26 DCO2 2' harmonic\n\ DE 27 DCO2 level\n\ DE 31 DCO2 semitone transpose\n\ DE 32 DCO2 detune\n\ \n\ DE 33 Noise level\n\ \n\ DE 41 Filter cutoff frequency\n\ DE 42 Filter Resonance\n\ DE 43 Filter Keyboard tracking off/half/full\n\ DE 44 Filter Envelope polarity\n\ DE 45 Filter Envelope amount\n\ DE 46 Filter Envelope retrigger\n\ \n\ DE 48 Chorus On/Off\n\ \n\ DE 51 Env-1 DCO1 Attack\n\ DE 52 Env-1 DCO1 Decay\n\ DE 53 Env-1 DCO1 Breakpoint\n\ DE 54 Env-1 DCO1 Slope\n\ DE 55 Env-1 DCO1 Sustain\n\ DE 56 Env-1 DCO1 Release\n\ \n\ DE 61 Env-2 DCO2 Attack\n\ DE 62 Env-2 DCO2 Decay\n\ DE 63 Env-2 DCO2 Breakpoint\n\ DE 64 Env-2 DCO2 Slope\n\ DE 65 Env-2 DCO2 Sustain\n\ DE 66 Env-2 DCO2 Release\n\ \n\ DE 71 Env-3 Filter Attack\n\ DE 72 Env-3 Filter Decay\n\ DE 73 Env-3 Filter Breakpoint\n\ DE 74 Env-3 Filter Slope\n\ DE 75 Env-3 Filter Sustain\n\ DE 76 Env-3 Filter Release\n\ \n\ DE 81 Mod LFO Frequency\n\ DE 82 Mod Delay\n\ DE 83 Mod DCO\n\ DE 84 Mod VCF\n\ \n\ DE 86 Midi channel\n\ DE 87 Midi program change enable\n\ DE 88 Midi OMNI\n\ \n\ Of these 25 pararmeters, the emulation has changed 88 to be OMNI mode rather \n\ than the original sequence clock as internal or external. This is because the\n\ sequencer function was dropped as explained above.\n\ \n\ Additional to the original many of the controls which are depicted as on/off\n\ are actually continuous. For example, the waveform appears to be either square\n\ or ramp. The emulator allows you to use the up/down Value keys to reproduce\n\ this however if you use the potentiometer then you can gradually move from one\n\ wave to the next. The different harmonics are also not on/off, you can mix\n\ each of them together with different amounts and if you configure a mixture\n\ of waveforms and a bit of detune the sound should widen due to addition of a\n\ bit of phasing within the actual oscillator.\n\ \n\ The envelope generators are not typical ADSR. There is an initial attack from\n\ zero to max gain then decay to a 'Breakpoint'. When this has been reached then\n\ the 'Slope' parameter will take the signal to the Sustain level, then finally\n\ the release rate. The extra step of breakpoint and slope give plenty of extra\n\ flexibility to try and adjust for the loss of a filter per voice and the \n\ emulation has a linear step which should be the same as the original. The\n\ ninth envelope is applied to the single filter and also as the envelope for \n\ the noise signal level.\n\ \n\ The single filter always responded to the highest note on the keyboard. This\n\ gives a weaker overall sound and if playing with two hands then there is a\n\ noticible effect with keytracking - left hand held chords will cause filter\n\ breathing as the right hand plays solos and the keyboard tracking changes \n\ from high to low octaves. Note that the emulator will implement a single\n\ filter if you select DE 46 filter envelope retrigger to be single trigger, it\n\ will be played legato style. If multiple triggers are selected then the\n\ emulator will produce a filter and envelope for each voice.\n\ \n\ Bristol adds a number of extra parameters to the emulator that are not\n\ available from the mouse on the silkscreen and were not a part of the design\n\ of the poly800. You have to select Prog such that the LED is lit next to the\n\ Param display, then select the two digit parameter from the telephone keyboard:\n\ \n\ DE 28 DCO Sync 2 to 1\n\ DE 34 DCO-1 PW\n\ DE 35 DCO-1 PWM\n\ DE 36 DCO-2 PW\n\ DE 37 DCO-2 PWM\n\ DE 38 DCO temperature sensitivity\n\ DE 67 DCO Glide\n\ \n\ DE 85 Mod - Uni/Multi per voice or globally\n\ \n\ DE 57 Envelope Touch response\n\ \n\ DE 47 Chorus Parameter 0\n\ DE 58 Chorus Parameter 1\n\ DE 68 Chorus Parameter 2\n\ DE 78 Chorus Parameter 3\n\ \n\ If DataEntry 28 is selected for oscillator sync then LFO MOD to DCO-1 is no\n\ longer applied, it only goes to DCO-2. This allows for the interesting sync\n\ modulated slow vibrato of DCO-2. The LFO mod is still applied via the joystick.\n\ \n\ DE 38 global detune will apply both temperature sensitivity to each oscillator\n\ but also fatten out the harmonics by detuning them independently. It is only \n\ calculated at 'note on' which can be misleading - it has no effect on existing\n\ notes which is intentional if misleading.\n\ \n\ DE 57 is a bitmask for the three envelopes to define which ones will give a\n\ response to velocity with a default to '3' for velocity tracking oscillator\n\ gain:\n\ \n\ value DEG1 DEG2 DEG3\n\ DCO1 DCO2 FILT\n\ \n\ 0 - - -\n\ 1 V - -\n\ 2 - V -\n\ 3 V V -\n\ 4 - - V\n\ 5 V - V\n\ 6 - V V\n\ 7 V V V\n\ \n\ This gives some interesting velocity tracking capabilities where just one osc\n\ can track velocity to introduce harmonic content keeping the filter at a fixed\n\ cutoff frequence. Having a bit of detune applied globally and locally will keep\n\ the sound reasonably fat for each oscillator.\n\ \n\ The filter envelope does not track velocity for any of the distributed voices,\n\ this was intentional since when using high resonance it is not desirable that\n\ the filter cutoff changes with velocity, it tends to be inconsistently \n\ disonant.\n\ \n\ If you want to use this synth with controller mappings then map the value \n\ entry pot to your easiest to find rotary, then click the mouse on the membrane\n\ switch to select which parameter you want to adjust with that control each time.\n\ The emulator is naturally not limited to just 4/8 voices, you can request more\n\ in which case single oscillator will give you the requested number of voices\n\ and double will give you half that amount.\n\ \n\ The Bristol Poly-800 is dedicated to Mark.\n\ \n", " Baumann BME-700\n\ ---------------\n\ \n\ This unusual German synth had a build volume of about 500 units and only one\n\ useful source of information could be found on it: a report on repair work for\n\ one of the few existing examples at www.bluesynths.com. The BME systems were\n\ hand built and judging by some reports on build quality may have been sold in\n\ kit form. The unit was produced in the mid 1970's.\n\ \n\ The synth has a very interesting design, somewhat reminiscent of the Moog Sonic\n\ and Explorer synths. It has two modulating LFO with fairly high top frequency,\n\ two filter and two envelopes. The envelopes are either AR or ASR but they can\n\ be mixed together to generate amongst other features an ADSR, very innovative.\n\ There is only one oscillator but the sound is fattened out by the use of two\n\ parallel filters, one acting as a pure resonator and the other as a full VCF.\n\ \n\ The synth has been left with a minimum of overhead. There are just 8 memory\n\ locations on the front panel with Load, Save and Increment buttons and one\n\ panel of options to adjust a few parameters on the oscillator and filters. It\n\ is possible to get extra memories by loading banks with -load: if you request\n\ starting in memory #21 the emulator will stuff 20 into the bank and 1 into the\n\ memory location. There is no apparant midi channel selector, use -channel \n\ and then stay on it. This could have been put into the options panel however \n\ having midi channel in a memory is generally a bad idea.\n\ \n\ A. MOD\n\ \n\ Two LFO:\n\ \n\ frequency from 0.1 to 100 Hz\n\ Triangle and Square wave outputs\n\ \n\ Mix control\n\ \n\ Mod-1/2 into the VCO FM\n\ Env-1/Mod-2 into the VCO FM\n\ \n\ B. Oscillator\n\ \n\ Single VCO\n\ \n\ Glide 0 to 10s, on/off.\n\ PW Man: 5 to 50% duty cycle\n\ Auto depth:\n\ \n\ Envelope-1\n\ Mod-1, Mod-1/2, Tri/Square\n\ \n\ Vibrato depth\n\ Tuning\n\ 8', 4', 16' transposition\n\ \n\ Shape\n\ \n\ continuous control from Square to Tri wave.\n\ \n\ Mix of noise or VCO output\n\ \n\ C. Res Filter\n\ \n\ Sharp (24db/Oct), Flat (12dB/Oct)\n\ 5 frequency switches\n\ \n\ D. Envelopes\n\ \n\ Two envelopes\n\ \n\ Rise time\n\ Fall Time\n\ AR/ASR selector\n\ \n\ Two independent mixes of Env, for VCF and VCA.\n\ \n\ E. Filter\n\ \n\ Frequency\n\ Resonance\n\ Env/Mod selector\n\ \n\ Modulation\n\ \n\ KBD tracking\n\ Mod-1 or Mod-2, Tri/Square\n\ \n\ F. Amplifier\n\ \n\ Mix resonator/filter.\n\ Volume\n\ \n\ Mod depth\n\ \n\ Mod-1 or Mod-2, Tri/Square\n\ \n\ The oscillator is implemented as a non-resampling signal generator, this means\n\ it uses heuristics to estimate the wave at any given time. The harmonic content\n\ is a little thin and although the generation method seems to be correct in how\n\ it interprets signal ramps and drains from an analogue circuit this is one area\n\ of improvement in the emulator. There are options to produce multiple waveforms\n\ described below.\n\ \n\ The resonant filter is implemented with a single Houvilainen and actually only\n\ runs at 24dB/Oct. There are controls for remixing the different taps, a form\n\ of feedforward and when in 'Flat' mod there is more remixing of the poles, this\n\ does generate a slower roll off but gives the signal a bit more warmth than a\n\ pure 12dB/Oct would.\n\ \n\ \n\ There is a selector in the Memory section to access some options:\n\ \n\ G. Options\n\ \n\ LFO\n\ \n\ Synchronise wave to key on events\n\ Multi LFO (per voice).\n\ \n\ Oscillator\n\ \n\ Detune (temperature sensitivity)\n\ Multi - remix 8' with 16' or 4'.\n\ \n\ Noise\n\ \n\ Multi Noise (per voice).\n\ White/Pink\n\ Pink Filter\n\ \n\ ResFilter\n\ \n\ Sharp Resonance/Remix\n\ Flat Resonance/Remix\n\ \n\ Envelope\n\ \n\ Velocity Sensitive\n\ Rezero for note on\n\ Gain\n\ \n\ Filter\n\ \n\ Remix\n\ KBD tracking depth\n\ \n\ The emulator probably gives the best results with the following:\n\ \n\ startBristol -bme700 -mono -hnp -retrig -channel 1\n\ \n\ This gives a monophonic emulation with high note preference and multiple\n\ triggers.\n\ \n\ The options from section G are only loaded under two circumstances: at system\n\ start from the first selected memory location and if the Load button is given\n\ a DoubleClick. All other memory load functions will inherrit the settings that\n\ are currently active.\n\ \n", " Bristol BassMaker\n\ -----------------\n\ \n\ The BassMaker is not actually an emulator, it is a bespoke sequencer design but\n\ based on the capabilities of some of the early analogue sequencers such as the\n\ Korg SQ-10. Supplying this probably leaves bristol open to a lot of feature\n\ requests for sequencer functionaliity and it is stated here that the BassMaker\n\ is supposed to be simple so excess functionality will probably be declined as\n\ there are plenty of other sequencing applications that can provide a richer\n\ feature set.\n\ \n\ The main page gives access to a screen of controls for 16 steps and a total of\n\ 4 pages are available for a total of 64 steps. The pages are named 'A' through\n\ 'D'. Each step has 5 options:\n\ \n\ Note: one octave of note selection\n\ Transpose: +/- one octave transposition of the note.\n\ Volume: MIDI note velocity\n\ Controller: MIDI modulation, discussed further below\n\ Triggers: Note On/Off enablers\n\ \n\ The trigger button gives 4 options indicated by the LED:\n\ \n\ off: note on/off are sent\n\ red: only send note_on\n\ green: only send note_off\n\ yellow: do not send note on/off\n\ \n\ The 'Controllers' setting has multiple functions which can be selected from\n\ the menu as explained below. The options available are as follows:\n\ \n\ Send semitone tuning\n\ \n\ Send glide rate\n\ \n\ Send modwheel\n\ \n\ Send expression pedal (controller value)\n\ \n\ Send Note: the controller will be 12 discrete steps as per the 'Note' \n\ setting and this note will be sent on the Secondary MIDI channel.\n\ \n\ The semitone tuning and glide work for the majority of the emulations. Some do\n\ not support fine tune controls (Vox, Hammond, others). If you are missing these\n\ capabilities for specific emulators raise a change request on Sourceforge.net.\n\ \n\ At the top of the window there is a panel to manage the sequencer. It has the\n\ following functions:\n\ \n\ Speed: step rate through the notes\n\ DutyCycle: ratio of note-on to note-off\n\ \n\ Start/Pause\n\ Stop: stop and return to first step/page\n\ \n\ Direction:\n\ Up\n\ Down\n\ Up/Down\n\ Random\n\ \n\ Select: which of the pages to include in the sequence.\n\ Edit: which page is currently displayed to be edited.\n\ \n\ Memory:\n\ 0..9 key entry buttons, 1000 memories available\n\ Load\n\ Save: doubleclick to save current sequence\n\ \n\ Menu Panel\n\ Up, Down menu\n\ Function (return to previous level)\n\ Enter: enter submenu or enter value if in submenu\n\ \n\ The menu consists of several tables, these can be stepped through using the Up\n\ and Down arrows to move through the menu and the 'Enter' arrow to select a sub\n\ menu or activate any option. The 'Fn' button returns one level:\n\ \n\ Memory:\n\ \n\ Find next free memory upwards\n\ Find next memory upwards\n\ Find next memory downwards\n\ \n\ Copy:\n\ \n\ Copy current edit page to 'A', 'B', 'C' or 'D'.\n\ \n\ Control - Set the control value to send:\n\ \n\ semitone tuning\n\ glide rate\n\ modwheel\n\ expression pedal (controller value)\n\ note events\n\ \n\ First midi channel\n\ \n\ Primary midi channel for note events\n\ \n\ Second midi channel\n\ \n\ Secondary midi channel when 'Control' configured to 'Note' events.\n\ \n\ Global Transpose\n\ \n\ Transpose the whole sequence up or down 12 semitones\n\ \n\ Clear - configure default value for all of the:\n\ \n\ Notes to zero\n\ Transpose to zero (midpoint)\n\ Volume to 0.8\n\ Control to midpoint\n\ Triggers to on/off\n\ \n\ As of the first release in 0.30.8 large parts of the Controllers functionality\n\ was only lightly tested. If you do not get the results you anticipate you may\n\ require a fix.\n\ \n", " Bristol SID\n\ -----------\n\ \n\ In release 0.40 bristol introduced a piece of code that emulated the Commodore\n\ C64 6581 SID chip. The interface uses byte settings of the 31 chip registers to\n\ be close to the original plus some floating point IO for extracting the audio\n\ signal and configuring some analogue parameters and the 'softSID' is clocked\n\ by the sample extraction process.\n\ \n\ The chip uses integer maths and logic for the oscillators, ring mod, sync and\n\ envelopes and emulates the analogue components of the 6581 with floating point\n\ code, for the filter and S/N generation.\n\ \n\ The oscillators will run as per the original using a single phase accumulator\n\ and 16 bit frequency space. All the waveforms are extracted logically from the\n\ ramp waveform generated by the phase accumulation. Sync and RingMod are also\n\ extracted with the same methods. The noise generation is exor/add as per the\n\ original however the noise signal will not degenerate when mixing waveforms.\n\ The output waves are ANDed together. The bristol control register has an option\n\ for Multi waveforms and when selected each oscillator will have its own phase\n\ accumulator, can have a detune applied and will be mixed by summation rather\n\ than using an AND function.\n\ \n\ The envelope is an 8 bit up/down counter with a single gate bit. All the 4 bit\n\ parameters give rates taken from the chip specifications including the slightly\n\ exponential decay and release. Attack is a linear function and the sustain level\n\ can only be decreased when active as the counter also refuses to count back up\n\ when passed its peak.\n\ \n\ The filter implements a 12dB/Octave multimode chamberlain filter providing LP,\n\ BP and HP signals. This is not the best filter in the world however neither was\n\ the original. An additional 24dB/Octave LP filter has been added, optionally \n\ available and with feedforward to provide 12/18dB signals. Between them the \n\ output can be quite rich.\n\ \n\ The emulator provides some control over the 'analogue' section. The S/N ratio\n\ can be configured from inaudible (just used to prevent denormal of the filter)\n\ up to irritating levels. Oscillator leakage is configurable from none up to \n\ audible levels and the oscillator detune is configurable in cents although\n\ this is a digital parameter and was not a part of the original.\n\ \n\ Voice-3 provides an 8 bit output of its oscillator and envelope via the normal\n\ output registers and the otherwise unused X and Y Analogue registers contain\n\ the Voice-1 and Voice-2 oscillator output.\n\ \n\ The bristol -sid emulator uses two softSID, one generating three audio voices\n\ and a second one providing modulation signals by sampling the voice-3 osc and\n\ env outputs and also by configuring voice-1 to generate noise to the output, \n\ resampling this noise and gating it from voice-3 to get sample and hold. This\n\ would have been possible with the original as well if the output signal were\n\ suitably coupled back on to one of the X/Y_Analogue inputs.\n\ \n\ The emulator has several key assignment modes. The emulator is always just\n\ monophonic but uses internal logic to assign voices. It can be played as a big\n\ mono synth with three voices/oscillators, polyphonically with all voices either\n\ sounding the same or optionally configured individually, and as of this release\n\ a single arpeggiating mode - Poly-3. Poly-3 will assign Voice-1 to the lowest\n\ note, voice-3 to the highest note and will arpeggiate Voice-2 through all other\n\ keys that are pressed with a very high step rate. This is to provide some of\n\ the sounds of the original C64 where fast arpeggiation was used to sounds \n\ chords rather than having to use all the voices. This first implementation \n\ does not play very well in Poly-3, a subsequent release will probably have a\n\ split keyboard option where one half will arpeggiate and the other half will\n\ play notes.\n\ \n\ This is NOT a SID player, that would require large parts of the C64 to also be\n\ emulated and there are plenty of SID players already available.\n\ \n\ Bristol again thanks Andrew Coughlan, here for proposing the implementation of\n\ a SID chip which turned out to be a very interesting project.\n\ \n", NULL, /* Not used */ NULL, /* Not used */ NULL, /* Not used */ NULL, /* Not used */ NULL, /* Not used */ NULL, /* Not used */ NULL, /* Not used */ NULL, /* Not used */ NULL, /* Not used */ NULL, /* Not used */ NULL, /* Not used */ NULL, /* Not used */ NULL, /* Not used */ NULL, /* Not used */ NULL, /* Not used */ NULL, /* Not used */ NULL, /* Not used */ NULL, /* Not used */ NULL, /* Not used */ }; bristol-0.60.11/brighton/brightonMixerMenu.c0000644000175000017500000007071311746476475015741 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include #include #include #include "brightonMixer.h" #include "brightoninternals.h" #define DISPLAY1 (FUNCTION_COUNT - 6) #define DISPLAY2 (FUNCTION_COUNT - 5) #define DISPLAY3 (FUNCTION_COUNT - 4) #define DISPLAY4 (FUNCTION_COUNT - 3) #define DISPLAY5 (FUNCTION_COUNT - 2) #define DISPLAY6 (FUNCTION_COUNT - 1) #include "brighton.h" #include "brightonMini.h" #include "brightonMixer.h" #include "brightonMixerMemory.h" static char text[128]; /*static char scratch[MAX_CHAN_COUNT][16]; */ static char memscratch[16]; static char *removeInterface(guiSynth *); static char *printInterface(guiSynth *); static char *printTrackMenu(guiSynth *); static char *printMidiMenu(guiSynth *); static char *trackDown(guiSynth *); static char *trackUp(guiSynth *); static char *midiDown(guiSynth *); static char *midiUp(guiSynth *); static char *setTrackText(guiSynth *); static char *printMemMenu(guiSynth *); static char *memoryBuildList(guiSynth *); static char *memoryList(guiSynth *); static char *memoryShowList(guiSynth *); static char *memoryListUp(guiSynth *); static char *memoryListDown(guiSynth *); static char *memorySel1(guiSynth *); static char *memorySel2(guiSynth *); static char *memorySel3(guiSynth *); static char *memorySel4(guiSynth *); static char *songSel1(guiSynth *); static char *songSel2(guiSynth *); static char *songSel3(guiSynth *); static char *songSel4(guiSynth *); static char *songList(guiSynth *); static char *createSongDir(guiSynth *); extern int loadMixerMemory(guiSynth *, char *, int); extern int saveMixerMemory(guiSynth *, char *); extern void displayPanel(guiSynth *, char *, int, int, int); extern int setMixerMemory(mixerMem *, int, int, float *, char *); /* * Ok, fixed table sizes, but a kilo of memories will do for now. */ #define MIXER_MEM_COUNT 1024 int memCount = -1, memIndex = 0; char memList[MIXER_MEM_COUNT][32]; guiSynth *theSynth; /* * We should not really have to rely on timers within the GUI: The engine will * evaluate RMS and Peak signal values for the channels, and save them. The * Midi thread should take these values X times per second (ie, with a timer) * and send a message to the GUI over the interface tap. * * Whenever the GUI gets a VU message it should update the VU meter display. */ u_long vuInterval = 100000; /* * Need a set of structures that allow a TitleBar strings, 5 substrings, * 2 "next menus" for the Title, 2 "next menus" or otherwise functions. */ typedef char *(*MenuFunc)(guiSynth *); typedef struct mLine { char title[32]; int last, next; MenuFunc lmenuFunc; MenuFunc rmenuFunc; } mLine; #define line1 line[0] #define line2 line[1] #define line3 line[2] #define line4 line[3] #define line5 line[4] typedef struct Menu { mLine title; mLine line[5]; } Menu; #define MENU_COUNT 32 int currentMenu = -1; int currentTrack = 0; char *setInt0() { vuInterval = 0; return(NULL); } char *setInt50() { vuInterval = 50000; return(NULL); } char *setInt100() { vuInterval = 100000; return(NULL); } char *setInt200() { vuInterval = 200000; return(NULL); } static char * loadShim(guiSynth *synth) { loadMixerMemory(synth, memscratch, 0); return(NULL); } static char * saveShim(guiSynth *synth) { saveMixerMemory(synth, memscratch); return(NULL); } static char * undoShim(guiSynth *synth) { loadMixerMemory(synth, "revert", 0); return(NULL); } Menu functionMenu[MENU_COUNT] = { { {" Main Menu ", 3, 1, 0, 0}, {{"Effects Bus ", 1, 2, 0, 0}, {"Track VU ", 3, 12, 0, 0}, {"Audio Mem ", 13, 14, 0, 0}, {"Stats Print ", 15, -1, 0, printInterface}, {"Midi Quit ", 17, 16, 0, 0}}, }, { {" Effects Menu ", 0, 2, 0, 0}, {{"Pre 1 Post 1 ", 4, 8, 0, 0}, {"Pre 2 Post 2 ", 5, 9, 0, 0}, {"Pre 3 Post 3 ", 6, 10, 0, 0}, {"Pre 4 Post 4 ", 7, 11, 0, 0}, {" Main ", -1, 0, 0, 0}}, }, { {" Bus Menu ", 1, 3, 0, 0}, {{"Effects Bus ", 1, 2, 0, 0}, {"Stats ", 3, -1, 0, 0}, {" ", -1, -1, 0, 0}, {" ", -1, -1, 0, 0}, {" Main ", -1, 0, 0, 0}}, }, { {" Track Menu ", 2, 12, printTrackMenu, 0}, {{" ", -1, -1, 0, 0}, {"Text: ", -1, -1, 0, 0}, {"Down UP ", -1, -1, trackDown, trackUp}, {" ", -1, -1, 0, 0}, {" MAIN ", -1, 0, setTrackText, 0}}, }, /* 4: */ { {" Pre 1 Menu ", 1, 1, 0, 0}, {{"P 1 P 4 ", -1, -1, 0, 0}, {"P 2 P 5 ", -1, -1, 0, 0}, {"P 3 P 6 ", -1, -1, 0, 0}, {"Prev Next ", 11, 5, 0, 0}, {" Main ", -1, 0, 0, 0}}, }, { {" Pre 2 Menu ", 1, 1, 0, 0}, {{"P 1 P 4 ", -1, -1, 0, 0}, {"P 2 P 5 ", -1, -1, 0, 0}, {"P 3 P 6 ", -1, -1, 0, 0}, {"Prev next ", 4, 6, 0, 0}, {" Main ", -1, 0, 0, 0}}, }, { {" Pre 3 Menu ", 1, 1, 0, 0}, {{"P 1 P 4 ", -1, -1, 0, 0}, {"P 2 P 5 ", -1, -1, 0, 0}, {"P 3 P 6 ", -1, -1, 0, 0}, {"Prev next ", 5, 7, 0, 0}, {" Main ", -1, 0, 0, 0}}, }, { {" Pre 4 Menu ", 1, 1, 0, 0}, {{"P 1 P 4 ", -1, -1, 0, 0}, {"P 2 P 5 ", -1, -1, 0, 0}, {"P 3 P 6 ", -1, -1, 0, 0}, {"Prev next ", 6, 8, 0, 0}, {" Main ", -1, 0, 0, 0}}, }, /* 8: */ { {" Post 1 Menu ", 1, 1, 0, 0}, {{"P 1 P 4 ", -1, -1, 0, 0}, {"P 2 P 5 ", -1, -1, 0, 0}, {"P 3 P 6 ", -1, -1, 0, 0}, {"Prev next ", 7, 9, 0, 0}, {" Main ", -1, 0, 0, 0}}, }, { {" Post 2 Menu ", 1, 1, 0, 0}, {{"P 1 P 4 ", -1, -1, 0, 0}, {"P 2 P 5 ", -1, -1, 0, 0}, {"P 3 P 6 ", -1, -1, 0, 0}, {"Prev next ", 8, 10, 0, 0}, {" Main ", -1, 0, 0, 0}}, }, { {" Post 3 Menu ", 1, 1, 0, 0}, {{"P 1 P 4 ", -1, -1, 0, 0}, {"P 2 P 5 ", -1, -1, 0, 0}, {"P 3 P 6 ", -1, -1, 0, 0}, {"Prev next ", 9, 11, 0, 0}, {" Main ", -1, 0, 0, 0}}, }, { {" Post 4 Menu ", 1, 1, 0, 0}, {{"P 1 P 4 ", -1, -1, 0, 0}, {"P 2 P 5 ", -1, -1, 0, 0}, {"P 3 P 6 ", -1, -1, 0, 0}, {"Prev next ", 10, 4, 0, 0}, {" Main ", -1, 0, 0, 0}}, }, /* 12: */ { {" VU Menu ", 3, 13, 0, 0}, {{"Interval 50ms ", -1, -1, setInt50, 0}, {"Interval 100ms ", -1, -1, setInt100, 0}, {"Interval 200ms ", -1, -1, setInt200, 0}, {" ", -1, -1, 0, 0}, {"Off MAIN ", -1, 0, setInt0, 0}}, }, { {" Audio Menu ", 12, 14, 0, 0}, {{"Effects Bus ", 0, 2, 0, 0}, {"Stats ", 0, -1, 0, 0}, {" ", -1, -1, 0, 0}, {" ", -1, -1, 0, 0}, {" MAIN ", -1, 0, 0, 0}}, }, { {" MEM Menu ", 13, 15, printMemMenu, 0}, {{"Name: ", -1, -1, 0, 0}, {"Create Song ", -1, -1, createSongDir, 0}, {"Load Search ", -1, 20, loadShim, memoryList}, {"Save Undo ", -1, -1, saveShim, undoShim}, {"Songs MAIN ", 21, 0, songList, 0}}, }, { {" Stats Menu ", 14, 0, 0, 0}, {{"Effects Bus ", 0, 2, 0, 0}, {"Stats ", 0, -1, 0, 0}, {" ", -1, -1, 0, 0}, {" ", -1, -1, 0, 0}, {" MAIN ", -1, 0, 0, 0}}, }, /* 16: */ { {" Quit Menu ", 0, 0, 0, 0}, {{" ", -1, -1, 0, 0}, {" ", -1, -1, 0, 0}, {" Really quit? ", -1, -1, 0, 0}, {" ", -1, -1, 0, 0}, {"No Yes ", 0, 3, 0, removeInterface}}, }, { {" Midi Menu ", 0, 0, printMidiMenu, 0}, {{" ", -1, -1, 0, 0}, {"Channel: ", -1, -1, 0, 0}, {" Up ", -1, -1, 0, midiUp}, {" Down ", -1, -1, 0, midiDown}, {" Main ", -1, 0, 0, 0}}, }, { }, { }, /* 20: */ { {"Back Search Main ", 14, 0, 0, 0}, {{" ", 14, 14, memorySel1, memorySel1}, {" ", 14, 14, memorySel2, memorySel2}, {" ", 14, 14, memorySel3, memorySel3}, {" ", 14, 14, memorySel4, memorySel4}, {"Down UP ", 20, 20, memoryListUp, memoryListDown}}, }, { {"Back Songs Main ", 14, 0, 0, 0}, {{" ", 20, 20, songSel1, songSel1}, {" ", 20, 20, songSel2, songSel2}, {" ", 20, 20, songSel3, songSel3}, {" ", 20, 20, songSel4, songSel4}, {"Down UP ", 21, 21, memoryListUp, memoryListDown}}, }, { }, { }, /* 24: */ { }, { }, { }, { }, /* 28: */ { }, { }, { }, { } }; static void displayMenu(guiSynth *synth, int panel, int menu) { if (functionMenu[currentMenu].title.lmenuFunc != 0) { /* * If we have a left function to draw the display, it must do all the * lines. */ functionMenu[menu].title.lmenuFunc(synth); return; } else if (functionMenu[currentMenu].title.rmenuFunc != 0) { displayPanel(synth, functionMenu[menu].title.rmenuFunc(synth), 0, FUNCTION_PANEL, DISPLAY1); } else { displayPanel(synth, functionMenu[menu].title.title, 0, FUNCTION_PANEL, DISPLAY1); } displayPanel(synth, functionMenu[menu].line1.title, 0, FUNCTION_PANEL, DISPLAY2); displayPanel(synth, functionMenu[menu].line2.title, 0, FUNCTION_PANEL, DISPLAY3); displayPanel(synth, functionMenu[menu].line3.title, 0, FUNCTION_PANEL, DISPLAY4); displayPanel(synth, functionMenu[menu].line4.title, 0, FUNCTION_PANEL, DISPLAY5); displayPanel(synth, functionMenu[menu].line5.title, 0, FUNCTION_PANEL, DISPLAY6); } int functionOp(guiSynth *synth, int panel, int index, int operator, float value) { if ((synth->flags && OPERATIONAL) == 0) return(0); /* printf("functionOp(%x, %i, %i, %i, %f)\n", */ /* synth, panel, index, operator, value); */ if (currentMenu == -1) { /* * This is to init to the first menu */ currentMenu = 0; displayMenu(synth, panel, currentMenu); /* * And use the chance to seed the interupts for the VU meter. */ theSynth = synth; return(0); } if ((index == 13) || (index == 24) || (index == 25)) { /* * memory buttons, 13 is 'rezero', 24 is load and 25 is save? * * These are bespoke since the generic synth memories use a single * panel of parameters whilst the mixer needs many? */ if (index == 25) { if (memCount < 0) memoryBuildList(synth); if (++memIndex > memCount) memIndex = 0; sprintf(memscratch, "%s", memList[memIndex]); loadMixerMemory(synth, memList[memIndex], 0); currentMenu = 14; printMemMenu(synth); return(0); } if (index == 24) { if (memCount < 0) memoryBuildList(synth); if (--memIndex < 0) memIndex = memCount; sprintf(memscratch, "%s", memList[memIndex]); loadMixerMemory(synth, memList[memIndex], 0); currentMenu = 14; printMemMenu(synth); return(0); } if (index == 13) { loadMixerMemory(synth, "revert", 0); return(0); } } if ((index >= DISPLAY1) && (index <= DISPLAY5)) { /* * If we have an event here it is going to be a keypress. */ if (currentMenu == 3) { int i; char scratch[32]; /* * Track menu, this will be track naming text. Value will be an * ascii char, put it at the end of the string. char 08 and 7f are * delete, ie, remove a character. * * Then print it on line2. */ sprintf(scratch, "%s", getMixerMemory((mixerMem *) synth->mem.param, currentTrack + 4, 79)); i = strlen(scratch); if ((value == 0xff08) || (value == -1)) { /* * Should be backspace/delete */ if (i > 0) scratch[i - 1] = '\0'; } else if (i == 15) /* * If max length then return now */ return(0); else { scratch[i] = value; scratch[i + 1] = '\0'; } setMixerMemory((mixerMem *) synth->mem.param, currentTrack + 4, 79, 0, scratch); sprintf(text, "Text: %s ", scratch); displayPanel(synth, text, 0, FUNCTION_PANEL, DISPLAY3); setTrackText(synth); return(0); } /* * See if we are in the memory menu; */ else if (currentMenu == 14) { int i; /* * Track menu, this will be track naming text. Value will be an * ascii char, put it at the end of the string. char 08 and 7f are * delete, ie, remove a character. * * Then print it on line2. */ i = strlen(memscratch); if ((value == 0xff08) || (value == -1)) { if (i > 0) memscratch[i - 1] = '\0'; } else if (i == 15) return(0); else { memscratch[i] = value; memscratch[i + 1] = '\0'; } sprintf(text, "Name: %s ", memscratch); displayPanel(synth, text, 0, FUNCTION_PANEL, DISPLAY2); return(0); } else if ((currentMenu == 20) || (currentMenu == 21)) { int k, j, i = memIndex; /* * This is the search window. Go through the memList looking for * the next entry that starts with the given letter. */ for (j = 0; j <= memCount; j ++) { if (++i > memCount) i = 0; if (memList[i][0] == value) { memIndex = i; memoryShowList(synth); return(0); } } /* * If we get here then we could not find a match on the first * letter. Lets see about the second letter (not sure why, or if * it really makes sense */ i = memIndex; for (j = 0; j <= memCount; j ++) { if (++i > memCount) i = 0; if (memList[i][1] == value) { memIndex = i; memoryShowList(synth); return(0); } } /* * If that failed then I personally think we should look for any * entry that contains the given character. We might consider * dropping the last search. */ i = memIndex; for (j = 0; j <= memCount; j++) { if (++i > memCount) i = 0; for (k = 0; memList[i][k] != '\0'; k++) { if (memList[i][k] == value) { memIndex = i; memoryShowList(synth); return(0); } } } } return(0); } /* * Title back * * Apart from the title, the rest of the lines can be put into procedures * so that we can call the code with an index, as it is now an array. * * This is damn ugly. How was it not made into a case or a structured * array of calls? */ if (operator == 0) { if (functionMenu[currentMenu].title.last != -1) { currentMenu = functionMenu[currentMenu].title.last; displayMenu(synth, panel, currentMenu); } } else if (operator == 1) { /* * Title forward */ if (functionMenu[currentMenu].title.next != -1) { currentMenu = functionMenu[currentMenu].title.next; displayMenu(synth, panel, currentMenu); } } else if (operator == 2) { /* * Line 1 back */ if (functionMenu[currentMenu].line1.lmenuFunc != 0) { functionMenu[currentMenu].line1.lmenuFunc(synth); return(0); } if (functionMenu[currentMenu].line1.last != -1) { currentMenu = functionMenu[currentMenu].line1.last; displayMenu(synth, panel, currentMenu); } } else if (operator == 7) { /* * Line 1 forward */ if (functionMenu[currentMenu].line1.rmenuFunc != 0) { functionMenu[currentMenu].line1.rmenuFunc(synth); return(0); } if (functionMenu[currentMenu].line1.next != -1) { currentMenu = functionMenu[currentMenu].line1.next; displayMenu(synth, panel, currentMenu); } } else if (operator == 3) { /* * Line 2 back */ if (functionMenu[currentMenu].line2.lmenuFunc != 0) { functionMenu[currentMenu].line2.lmenuFunc(synth); return(0); } if (functionMenu[currentMenu].line2.last != -1) { currentMenu = functionMenu[currentMenu].line2.last; displayMenu(synth, panel, currentMenu); } } else if (operator == 8) { /* * Line 2 forward */ if (functionMenu[currentMenu].line2.rmenuFunc != 0) { functionMenu[currentMenu].line2.rmenuFunc(synth); return(0); } if (functionMenu[currentMenu].line2.next != -1) { currentMenu = functionMenu[currentMenu].line2.next; displayMenu(synth, panel, currentMenu); } } else if (operator == 4) { /* * Line 3 back */ if (functionMenu[currentMenu].line3.lmenuFunc != 0) { functionMenu[currentMenu].line3.lmenuFunc(synth); return(0); } if (functionMenu[currentMenu].line3.last != -1) { currentMenu = functionMenu[currentMenu].line3.last; displayMenu(synth, panel, currentMenu); } } else if (operator == 9) { /* * Line 3 forward */ if (functionMenu[currentMenu].line3.rmenuFunc != 0) { functionMenu[currentMenu].line3.rmenuFunc(synth); return(0); } if (functionMenu[currentMenu].line3.next != -1) { currentMenu = functionMenu[currentMenu].line3.next; displayMenu(synth, panel, currentMenu); } } else if (operator == 5) { /* * Line 4 back */ if (functionMenu[currentMenu].line4.lmenuFunc != 0) { functionMenu[currentMenu].line4.lmenuFunc(synth); return(0); } if (functionMenu[currentMenu].line4.last != -1) { currentMenu = functionMenu[currentMenu].line4.last; displayMenu(synth, panel, currentMenu); } } else if (operator == 10) { if (functionMenu[currentMenu].line4.rmenuFunc != 0) { functionMenu[currentMenu].line4.rmenuFunc(synth); return(0); } /* * Line 4 forward */ if (functionMenu[currentMenu].line4.next != -1) { currentMenu = functionMenu[currentMenu].line4.next; displayMenu(synth, panel, currentMenu); } } else if (operator == 6) { /* * Line 5 back */ if (functionMenu[currentMenu].line5.lmenuFunc != 0) { functionMenu[currentMenu].line5.lmenuFunc(synth); return(0); } if (functionMenu[currentMenu].line5.last != -1) { currentMenu = functionMenu[currentMenu].line5.last; displayMenu(synth, panel, currentMenu); } } else if (operator == 11) { if (functionMenu[currentMenu].line5.rmenuFunc != 0) { functionMenu[currentMenu].line5.rmenuFunc(synth); return(0); } /* * Line 5 forward */ if (functionMenu[currentMenu].line5.next != -1) { currentMenu = functionMenu[currentMenu].line5.next; displayMenu(synth, panel, currentMenu); } } return(0); } static char * printInterface(guiSynth *synth) { /* * Export image to bitmap file. */ brightonXpmWrite(synth->win, "/tmp/mixer.xpm"); return(NULL); } #warning - fixed track configuration at 16 tracks. static char * trackDown(guiSynth *synth) { if (--currentTrack < 0) currentTrack = 15; printTrackMenu(synth); return(NULL); } static char * trackUp(guiSynth *synth) { if (++currentTrack == 16) currentTrack = 0; printTrackMenu(synth); return(NULL); } static char * midiUp(guiSynth *synth) { if (++synth->midichannel == 16) synth->midichannel = 15; printMidiMenu(synth); return(NULL); } static char * midiDown(guiSynth *synth) { if (--synth->midichannel < 0) synth->midichannel = 0; printMidiMenu(synth); return(NULL); } static char * setTrackText(guiSynth *synth) { char scratch[32]; sprintf(scratch, "%s", getMixerMemory((mixerMem *) synth->mem.param, currentTrack + 4, 79)); displayPanel(synth, scratch, 0, currentTrack + 4, PARAM_COUNT - 1); /* * Looks ugly? The issue is that the channels use contiguous store in the * gui, but I have to separate this into the memories. */ setMixerMemory((mixerMem *) synth->mem.param, CHAN_PANEL, 79 + (currentTrack * 80), 0, scratch); return(NULL); } static char * printTrackMenu(guiSynth *synth) { char scratch[32]; if ((currentTrack + 4) < 0) return(NULL); sprintf(scratch, "%s", getMixerMemory((mixerMem *) synth->mem.param, currentTrack + 4, 79)); /* * Create text for track display */ sprintf(text, " Track %i Menu ", currentTrack + 1); displayPanel(synth, text, 0, FUNCTION_PANEL, DISPLAY1); displayPanel(synth, functionMenu[3].line[0].title, 0, FUNCTION_PANEL, DISPLAY2); sprintf(text, "Text: %s ", scratch); displayPanel(synth, text, 0, FUNCTION_PANEL, DISPLAY3); displayPanel(synth, functionMenu[3].line[2].title, 0, FUNCTION_PANEL, DISPLAY4); displayPanel(synth, functionMenu[3].line[3].title, 0, FUNCTION_PANEL, DISPLAY5); displayPanel(synth, functionMenu[3].line[4].title, 0, FUNCTION_PANEL, DISPLAY6); return(NULL); } static char * songSel1(guiSynth *synth) { currentMenu = 20; /* * Set the current song to the given name and then print the list of * songs in that directory */ loadMixerMemory(synth, memList[memIndex], 1); memoryList(synth); return(NULL); } static char * songSel2(guiSynth *synth) { currentMenu = 20; memIndex += 1; if (memIndex > memCount) memIndex -= memCount + 1; loadMixerMemory(synth, memList[memIndex], 1); memoryList(synth); return(NULL); } static char * songSel3(guiSynth *synth) { currentMenu = 20; memIndex += 2; if (memIndex > memCount) memIndex -= memCount + 1; loadMixerMemory(synth, memList[memIndex], 1); memoryList(synth); return(NULL); } static char * songSel4(guiSynth *synth) { currentMenu = 20; memIndex += 3; if (memIndex > memCount) memIndex -= memCount + 1; loadMixerMemory(synth, memList[memIndex], 1); memoryList(synth); return(NULL); } static char * createSongDir(guiSynth *synth) { loadMixerMemory(synth, memscratch, 2); return(NULL); } static char * memorySel1(guiSynth *synth) { currentMenu = 14; sprintf(memscratch, "%s", memList[memIndex]); printMemMenu(synth); return(NULL); } static char * memorySel2(guiSynth *synth) { currentMenu = 14; memIndex += 1; if (memIndex > memCount) memIndex -= memCount + 1; sprintf(memscratch, "%s", memList[memIndex]); printMemMenu(synth); return(NULL); } static char * memorySel3(guiSynth *synth) { currentMenu = 14; memIndex += 2; if (memIndex > memCount) memIndex -= memCount + 1; sprintf(memscratch, "%s", memList[memIndex]); printMemMenu(synth); return(NULL); } static char * memorySel4(guiSynth *synth) { currentMenu = 14; memIndex += 3; if (memIndex > memCount) memIndex -= memCount + 1; sprintf(memscratch, "%s", memList[memIndex]); printMemMenu(synth); return(NULL); } static char * songBuildList(guiSynth *synth) { char *entry; memCount = -1; while ((entry = getMixerMemory((mixerMem *) synth->mem.param, MM_GETLIST, 1)) != 0) sprintf(memList[++memCount], "%s", entry); /*while ((entry = ((char *) mixerMemory(synth, MM_GET, MM_GETLIST, 1, 0))) != 0) sprintf(memList[++memCount], "%s", entry); */ return(NULL); } static char * memoryBuildList(guiSynth *synth) { char *entry; memCount = -1; while ((entry = (getMixerMemory((mixerMem *) synth->mem.param, MM_GETLIST, 0))) != 0) sprintf(memList[++memCount], "%s", entry); return(NULL); } static char * songShowList(guiSynth *synth) { int mi = memIndex; if (memCount < 0) songBuildList(synth); /* * Then show the memory entries in the panel from the list with the * given index */ sprintf(text, "%s", functionMenu[21].title.title); displayPanel(synth, text, 0, FUNCTION_PANEL, DISPLAY1); displayPanel(synth, memList[mi], 0, FUNCTION_PANEL, DISPLAY2); if (mi++ >= memCount) mi = 0; displayPanel(synth, memList[mi], 0, FUNCTION_PANEL, DISPLAY3); if (mi++ >= memCount) mi = 0; displayPanel(synth, memList[mi], 0, FUNCTION_PANEL, DISPLAY4); if (mi++ >= memCount) mi = 0; displayPanel(synth, memList[mi], 0, FUNCTION_PANEL, DISPLAY5); displayPanel(synth, functionMenu[21].line[4].title, 0, FUNCTION_PANEL, DISPLAY6); return(NULL); } static char * memoryShowList(guiSynth *synth) { int mi = memIndex; if (memCount < 0) memoryBuildList(synth); /* * Then show the memory entries in the panel from the list with the * given index */ sprintf(text, "%s", functionMenu[20].title.title); displayPanel(synth, text, 0, FUNCTION_PANEL, DISPLAY1); displayPanel(synth, memList[mi], 0, FUNCTION_PANEL, DISPLAY2); if (mi++ >= memCount) mi = 0; displayPanel(synth, memList[mi], 0, FUNCTION_PANEL, DISPLAY3); if (mi++ >= memCount) mi = 0; displayPanel(synth, memList[mi], 0, FUNCTION_PANEL, DISPLAY4); if (mi++ >= memCount) mi = 0; displayPanel(synth, memList[mi], 0, FUNCTION_PANEL, DISPLAY5); displayPanel(synth, functionMenu[20].line[4].title, 0, FUNCTION_PANEL, DISPLAY6); return(NULL); } static char * songList(guiSynth *synth) { /* * We need to build a list of the memories in our default directory. * This should become a few routines, one that builds that list and two * that allow us to scroll up and down it. */ songBuildList(synth); songShowList(synth); currentMenu = 21; return(NULL); } static char * memoryList(guiSynth *synth) { /* * We need to build a list of the memories in our default directory. * This should become a few routines, one that builds that list and two * that allow us to scroll up and down it. */ memoryBuildList(synth); memoryShowList(synth); currentMenu = 20; return(NULL); } static char * memoryListDown(guiSynth *synth) { /* * Cycle upwards though our list and show the names. */ if (++memIndex > memCount) memIndex = 0; memoryShowList(synth); return(NULL); } static char * memoryListUp(guiSynth *synth) { /* * Cycle downwards though our list and show the names. */ if (--memIndex < 0) memIndex = memCount; memoryShowList(synth); return(0); } static char * printMemMenu(guiSynth *synth) { /* * Create text for track display displayPanel(synth, " Mem Menu ", 0, FUNCTION_PANEL, DISPLAY1); */ displayPanel(synth, functionMenu[14].title.title, 0, FUNCTION_PANEL, DISPLAY1); sprintf(text, "Name: %s ", memscratch); displayPanel(synth, text, 0, FUNCTION_PANEL, DISPLAY2); displayPanel(synth, functionMenu[14].line[1].title, 0, FUNCTION_PANEL, DISPLAY3); displayPanel(synth, functionMenu[14].line[2].title, 0, FUNCTION_PANEL, DISPLAY4); displayPanel(synth, functionMenu[14].line[3].title, 0, FUNCTION_PANEL, DISPLAY5); displayPanel(synth, functionMenu[14].line[4].title, 0, FUNCTION_PANEL, DISPLAY6); return(NULL); } static char * printMidiMenu(guiSynth *synth) { /* * Create text for track display */ displayPanel(synth, " Midi Menu ", 0, FUNCTION_PANEL, DISPLAY1); displayPanel(synth, functionMenu[17].line[0].title, 0, FUNCTION_PANEL, DISPLAY2); sprintf(text, "Channel: %i ", synth->midichannel + 1); displayPanel(synth, text, 0, FUNCTION_PANEL, DISPLAY3); displayPanel(synth, functionMenu[17].line[2].title, 0, FUNCTION_PANEL, DISPLAY4); displayPanel(synth, functionMenu[17].line[3].title, 0, FUNCTION_PANEL, DISPLAY5); displayPanel(synth, functionMenu[17].line[4].title, 0, FUNCTION_PANEL, DISPLAY6); return(NULL); } static char * removeInterface(guiSynth *synth) { /* * Exit application, completely. */ brightonRemoveInterface(synth->win); return(NULL); } brightonEvent event; int doAlarm() { event.type = BRIGHTON_FLOAT; event.value = 0.0; /* brightonSendEvent((void *) theSynth->win, 2, DISPLAY1 - 1, &event); */ return(0); } bristol-0.60.11/brighton/brightonJuno.c0000644000175000017500000006116111746476475014740 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include #include "brighton.h" #include "brightonMini.h" #include "brightoninternals.h" static int junoInit(); static int junoConfigure(); static int junoCallback(brightonWindow *, int, int, float); static int midiCallback(brightonWindow *, int, int, float); extern guimain global; #include "brightonKeys.h" #define FIRST_DEV 0 #define DEVICE_COUNT (56 + FIRST_DEV) #define ACTIVE_DEVS (39 + FIRST_DEV) #define DISPLAY_DEV (DEVICE_COUNT - 1) #define MEM_MGT ACTIVE_DEVS #define MIDI_MGT (MEM_MGT + 12) #define KEY_TRANSPOSE (FIRST_DEV + 6) #define KEY_HOLD (FIRST_DEV + 7) #define CHORUS (FIRST_DEV + 32) #define KEY_PANEL 1 /* * This structure is for device definition. The structure is defined in * include/brighton.h, further definitions in brighton/brightonDevtable.h and * include/brightoninternals.h * * typedef int (*brightonCallback)(int, float); * typedef struct BrightonLocations { * int device; 0=rotary, 1=scale, etc. * float relx, rely; relative position with regards to 1000 by 1000 window * float relw, relh; relative height. * int from, to; * brightonCallback callback; specific to this dev * char *image; bitmap. If zero take a device default. * int flags; * } brightonLocations; * * This example is for a junoBristol type synth interface. */ #define D3 80 #define BR1 300 #define BR2 BR1 + D3 #define BR3 BR2 + D3 #define BR4 BR3 + D3 #define MBR2 BR4 #define MBR1 MBR2 - 100 #define MBR3 MBR2 + 100 #define MBR4 MBR3 + 100 #define R1 200 #define R2 275 #define R3 450 #define R4 650 #define D1 15 #define D2 31 #define C1 10 #define C2 C1 + D2 - 1 #define C3 C2 + D1 + 1 #define C4 C3 + D2 - 7 #define C5 C4 + D2 + 4 #define C6 C5 + D1 + 2 /* Need to insert a few for the arpeg */ #define C6_1 C6 + D2 - 6 #define C6_2 C6_1 + D2 - 4 #define C6_3 C6_2 + D2 - 2 #define C6_4 C6_3 + D2 - 1 #define C7 275 #define C8 C7 + D1 #define C9 C8 + D2 - 9 #define C10 C9 + D2 - 6 #define C11 C10 + D1 + 4 #define C12 C11 + D2 - 12 #define C13 C12 + D1 + D2 + 4 /* text space */ #define C14 C13 + 15 #define C15 C14 + 15 #define C16 C15 + D2 + 3 #define C17 C16 + D1 #define C18 C17 + D2 + 2 /* HPF */ #define C19 C18 + D2 + 5 #define C20 C19 + D1 + 1 #define C21 C20 + D2 - 6 #define C22 C21 + D2 - 10 #define C23 C22 + D1 + 2 #define C24 C23 + D1 + 3 #define C25 C24 + D2 + 5 #define C26 C25 + D1 - 2 #define C27 C26 + D2 - 3 #define C28 C27 + D1 + 4 #define C29 C28 + D1 + 2 #define C30 C29 + D1 + 3 #define C31 C30 + D2 #define C32 C31 + 15 #define C33 C32 + 16 #define C34 C33 + D2 + D1 - 13 #define C35 C34 + D1 + 3 #define C36 C35 + D1 + 3 #define C37 C36 + D1 + 3 #define C38 C37 + D1 + 3 #define W1 14 #define L1 485 #define S2 120 #define BS1 17 #define BS2 100 #define BS3 115 #define BS4 12 #define BS5 160 static brightonLocations locations[DEVICE_COUNT] = { /* Power, etc */ {"On/Off", 2, C1, BR2, 18, BS5, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_NOSHADOW}, {"DCO Mod", 1, C2, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW}, {"VCF Mod", 1, C3, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW}, {"Tuning", 0, C4, R2, S2, S2, 0, 1, 0, "bitmaps/knobs/knob1.xpm", 0, BRIGHTON_NOTCH}, {"Glide", 0, C4, R3 + 20, S2, S2, 0, 1, 0, "bitmaps/knobs/knob1.xpm", 0, 0}, {"LFO Manual", 2, C4 + 3, R4, BS1, BS2 + 40, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_NOSHADOW}, /* Transpose - 6 */ {"Transpose", 2, C5 + 1, BR2 + 30, 12, 180, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW}, {"Hold", 2, C6 + 2, BR2, BS1, BS5, 0, 1, 0, "bitmaps/buttons/touchoy.xpm", "bitmaps/buttons/touchy.xpm", BRIGHTON_NOSHADOW}, {"LFO Rate", 1, C7, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW}, {"LFO Delay", 1, C8, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW}, {"Man/Auto", 2, C9, BR2 + 70, BS4, BS3, 0, 1, 0, "bitmaps/buttons/sw1.xpm", "bitmaps/buttons/sw2.xpm", BRIGHTON_NOSHADOW}, /* DCO - 11 */ {"DCO-LFO Mod", 1, C10, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW}, {"PWM", 1, C11, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW}, {"PWM Source", 2, C12 + 1, BR2 + 30, 12, 180, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW}, {"Pulse", 2, C13 - 7, BR2, BS1, BS5, 0, 1, 0, "bitmaps/buttons/touchow.xpm", "bitmaps/buttons/touchw.xpm", BRIGHTON_NOSHADOW}, {"Ramp", 2, C14 - 3, BR2, BS1, BS5, 0, 1, 0, "bitmaps/buttons/touchoy.xpm", "bitmaps/buttons/touchy.xpm", BRIGHTON_NOSHADOW}, {"Square", 2, C15 + 2, BR2, BS1, BS5, 0, 1, 0, "bitmaps/buttons/touchoo.xpm", "bitmaps/buttons/toucho.xpm", BRIGHTON_NOSHADOW}, {"SubOsc", 1, C16, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW}, {"Noise", 1, C17, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW}, /* hpf - 19 */ {"HPF", 1, C18, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW}, /* filter - 20 */ {"Filter Freq", 1, C19, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW}, {"Resonance", 1, C20, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW}, {"Env +/-", 2, C21, BR2 + 70, BS4, BS3, 0, 1, 0, "bitmaps/buttons/sw1.xpm", "bitmaps/buttons/sw2.xpm", BRIGHTON_NOSHADOW}, {"FilterEnvMod", 1, C22, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW}, {"FilterLFOMod", 1, C23, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW}, {"Filter KBD", 1, C24, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW}, /* VCA - 26 */ {"Amp Env/Gate", 2, C25 - 10, BR2 + 70, BS4, BS3, 0, 1, 0, "bitmaps/buttons/sw1.xpm", "bitmaps/buttons/sw2.xpm", BRIGHTON_NOSHADOW}, {"Amp Level", 1, C26, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW}, /* adsr - 28 */ {"Attack", 1, C27, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW}, {"Decay", 1, C28, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW}, {"Sustain", 1, C29, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW}, {"Release", 1, C30, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW}, /* chorus - 32 */ {"Chorus 1", 2, C31 - 9, BR2, BS1, BS5, 0, 1, 0, "bitmaps/buttons/touchow.xpm", "bitmaps/buttons/touchw.xpm", BRIGHTON_NOSHADOW}, {"Chorus 2", 2, C32 - 4, BR2, BS1, BS5, 0, 2, 0, "bitmaps/buttons/touchoy.xpm", "bitmaps/buttons/touchy.xpm", BRIGHTON_NOSHADOW}, {"Chorus 3", 2, C33, BR2, BS1, BS5, 0, 4, 0, "bitmaps/buttons/touchoo.xpm", "bitmaps/buttons/toucho.xpm", BRIGHTON_NOSHADOW}, /* Arpeggiator - 35 */ {"Arpeg On", 2, C6_1, BR2, BS1, BS5, 0, 1, 0, "bitmaps/buttons/touchoo.xpm", "bitmaps/buttons/toucho.xpm", BRIGHTON_NOSHADOW}, {"Arpeg UpDown", 2, C6_2, BR2 + 30, 12, 180, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW}, {"Arpeg Range", 2, C6_3, BR2 + 30, 12, 180, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW}, {"Arpeg Rate", 1, C6_4, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW|BRIGHTON_REVERSE}, /* memory tablet */ {"", 2, C34, MBR2, BS1, BS2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlw.xpm", 0}, {"", 2, C35, MBR2, BS1, BS2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlw.xpm", 0}, {"", 2, C36, MBR2, BS1, BS2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlw.xpm", 0}, {"", 2, C37, MBR2, BS1, BS2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlw.xpm", 0}, {"", 2, C38, MBR2, BS1, BS2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlw.xpm", 0}, {"", 2, C34, MBR3, BS1, BS2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlw.xpm", 0}, {"", 2, C35, MBR3, BS1, BS2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlw.xpm", 0}, {"", 2, C36, MBR3, BS1, BS2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlw.xpm", 0}, {"", 2, C37, MBR3, BS1, BS2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlw.xpm", 0}, {"", 2, C38, MBR3, BS1, BS2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlw.xpm", 0}, {"", 2, C37, MBR1, BS1, BS2, 0, 1, 0, "bitmaps/buttons/touchnl.xpm", "bitmaps/buttons/touchnl.xpm", 0}, {"", 2, C38, MBR1, BS1, BS2, 0, 1, 0, "bitmaps/buttons/touchnlo.xpm", "bitmaps/buttons/touchnlo.xpm", 0}, {"", 2, C34, MBR1, BS1, BS2, 0, 1, 0, "bitmaps/buttons/touchnl.xpm", "bitmaps/buttons/touchnl.xpm", 0}, {"", 2, C35, MBR1, BS1, BS2, 0, 1, 0, "bitmaps/buttons/touchnl.xpm", "bitmaps/buttons/touchnl.xpm", 0}, {"", 2, C34, MBR4, BS1, BS2, 0, 1, 0, "bitmaps/buttons/touchnl.xpm", "bitmaps/buttons/touchnl.xpm", 0}, {"", 2, C38, MBR4, BS1, BS2, 0, 1, 0, "bitmaps/buttons/touchnl.xpm", "bitmaps/buttons/touchnl.xpm", 0}, {"", 3, C34 - 5, R1, 100, BS2, 0, 1, 0, 0, "bitmaps/images/alphadisplay3.xpm", 0}, }; /* */ /* * This is a set of globals for the main window rendering. Again taken from * include/brighton.h */ brightonApp junoApp = { "juno", 0, /* no blueprint on wood background. */ "bitmaps/textures/metal4.xpm", BRIGHTON_STRETCH, junoInit, junoConfigure, /* 3 callbacks, unused? */ midiCallback, destroySynth, {6, 100, 1, 2, 5, 520, 0, 0}, 820, 250, 0, 0, 5, /* panels */ { { "Juno", "bitmaps/blueprints/juno.xpm", "bitmaps/textures/metal6.xpm", BRIGHTON_STRETCH, /* flags */ 0, 0, junoCallback, 25, 20, 953, 550, DEVICE_COUNT, locations }, { "Keyboard", 0, "bitmaps/newkeys/nkbg.xpm", /* flags */ 0x020|BRIGHTON_STRETCH, 0, 0, keyCallback, 114, 562, 889, 425, KEY_COUNT, //keys keysprofile2 }, { "Mods", 0, //"bitmaps/blueprints/mods.xpm", "bitmaps/keys/vkbg.xpm", /* flags */ BRIGHTON_STRETCH, 0, 0, modCallback, 25, 562, 90, 410, 2, mods }, { "Wood", 0, "bitmaps/textures/wood.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 2, 5, 22, 985, 0, 0 }, { "Wood", 0, "bitmaps/textures/wood.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 979, 5, 21, 985, 0, 0 }, } }; /*static dispatcher dispatch[DEVICE_COUNT]; */ static int midiCallback(brightonWindow *win, int controller, int value, float n) { guiSynth *synth = findSynth(global.synths, win); printf("midi callback: %x, %i\n", controller, value); switch(controller) { case MIDI_PROGRAM: printf("midi program: %x, %i\n", controller, value); synth->location = value; if (loadMemory(synth, "juno", 0, synth->bank + synth->location, synth->mem.active, FIRST_DEV, 0) < 0) displayText(synth, "FRE", synth->location, DISPLAY_DEV); else displayText(synth, "PRG", synth->location, DISPLAY_DEV); break; case MIDI_BANK_SELECT: printf("midi banksel: %x, %i\n", controller, value); synth->bank = value; synth->location = (synth->location % 10) + value * 10; if (loadMemory(synth, "juno", 0, synth->bank + synth->location, synth->mem.active, FIRST_DEV, 0) < 0) displayText(synth, "FRE", synth->location, DISPLAY_DEV); else displayText(synth, "PRG", synth->location, DISPLAY_DEV); break; } return(0); } static int junoMidiSendMsg(void *synth, int fd, int chan, int c, int o, int v) { /*printf("%i, %i, %i\n", c, o, v); */ bristolMidiSendMsg(fd, chan, c, o, v); return(0); } static void junoMemory(guiSynth *synth, int fd, int chan, int c, int o, int v) { if (synth->flags & MEM_LOADING) return; if ((synth->flags & OPERATIONAL) == 0) return; switch (c) { default: case 0: synth->location = synth->location * 10 + o; if (synth->location >= 1000) synth->location = o; if (loadMemory(synth, "juno", 0, synth->bank + synth->location, synth->mem.active, FIRST_DEV, BRISTOL_STAT) < 0) displayText(synth, "FRE", synth->location, DISPLAY_DEV); else displayText(synth, "PRG", synth->location, DISPLAY_DEV); break; case 1: if (loadMemory(synth, "juno", 0, synth->bank + synth->location, synth->mem.active, FIRST_DEV, 0) < 0) displayText(synth, "FRE", synth->location, DISPLAY_DEV); else displayText(synth, "PRG", synth->bank + synth->location, DISPLAY_DEV); break; case 2: saveMemory(synth, "juno", 0, synth->bank + synth->location, FIRST_DEV); displayText(synth, "PRG", synth->bank + synth->location, DISPLAY_DEV); break; case 3: while (loadMemory(synth, "juno", 0, --synth->location, synth->mem.active, FIRST_DEV, 0) < 0) { if (synth->location < 0) synth->location = 1000; } displayText(synth, "PRG", synth->location, DISPLAY_DEV); break; case 4: while (loadMemory(synth, "juno", 0, ++synth->location, synth->mem.active, FIRST_DEV, 0) < 0) { if (synth->location > 999) synth->location = -1; } displayText(synth, "PRG", synth->location, DISPLAY_DEV); break; } } static void junoMidi(guiSynth *synth, int fd, int chan, int c, int o, int v) { int newchan; if ((synth->flags & OPERATIONAL) == 0) return; if (c == 1) { if ((newchan = synth->midichannel - 1) < 0) { synth->midichannel = 0; return; } } else { if ((newchan = synth->midichannel + 1) >= 15) { synth->midichannel = 15; return; } } if (global.libtest == 0) { bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_MIDICHANNEL|newchan); } synth->midichannel = newchan; displayText(synth, "MIDI", synth->midichannel + 1, DISPLAY_DEV); } /* * For the sake of ease of use, links have been placed here to be called * by any of the devices created. They would be better in some other file, * perhaps with this as a dispatch. * * Param refers to the device index in the locations table given below. */ static int junoCallback(brightonWindow * win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); int sendvalue; /*printf("junoCallback(%i, %f): %x\n", index, value, synth); */ if (synth == 0) return(0); if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0)) return(0); if (junoApp.resources[0].devlocn[index].to == 1) sendvalue = value * C_RANGE_MIN_1; else sendvalue = value; synth->mem.param[index] = value; if ((!global.libtest) || (index >= ACTIVE_DEVS)) synth->dispatch[index].routine(synth, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #define DEBUG #ifdef DEBUG else printf("dispatch[%p,%i](%i, %i, %i, %i, %i)\n", synth, index, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #endif return(0); } static void junoChorus(guiSynth *synth) { int value = 0; if (synth->mem.param[CHORUS]) value++; if (synth->mem.param[CHORUS + 1]) value+=2; if (synth->mem.param[CHORUS + 2]) value+=4; bristolMidiSendMsg(global.controlfd, synth->sid, 100, 0, value); } static void junoSublevel(guiSynth *synth) { /*printf("junoSublevel %f %f\n", synth->mem.param[16], synth->mem.param[17]); */ if (synth->mem.param[16] == 0) { bristolMidiSendMsg(global.controlfd, synth->sid, 1, 6, 0); return; } bristolMidiSendMsg(global.controlfd, synth->sid, 1, 6, ((int) (synth->mem.param[17] * C_RANGE_MIN_1))); } static void junoTranspose(guiSynth *synth) { if ((synth->flags & OPERATIONAL) == 0) return; //printf("junoTranspose %f\n", synth->mem.param[KEY_TRANSPOSE]); bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_TRANSPOSE + (int) (synth->mem.param[KEY_TRANSPOSE] * 12) - 12); /* if (synth->mem.param[KEY_TRANSPOSE] == 0) synth->transpose = 24; else if (synth->mem.param[KEY_TRANSPOSE] == 1) synth->transpose = 36; else synth->transpose = 48; */ } static void junoHold(guiSynth *synth) { if ((synth->flags & OPERATIONAL) == 0) return; /*printf("junoHold %x\n", synth); */ if (synth->mem.param[KEY_HOLD]) bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_HOLD|1); else bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_HOLD|0); } /* * Any location initialisation required to run the callbacks. For bristol, this * will connect to the engine, and give it some base parameters. * May need to generate some application specific menus. * Will also then make specific requests to some of the devices to alter their * rendering. */ static int junoInit(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); dispatcher *dispatch; int i; if (synth == 0) { synth = findSynth(global.synths, 0); if (synth == 0) { printf("cannot init\n"); return(0); } } synth->win = win; printf("Initialise the juno link to bristol: %p\n", synth->win); synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float)); synth->mem.count = DEVICE_COUNT; synth->mem.active = ACTIVE_DEVS; synth->dispatch = (dispatcher *) brightonmalloc(DEVICE_COUNT * sizeof(dispatcher)); dispatch = synth->dispatch; /* * We really want to have three connection mechanisms. These should be * 1. Unix named sockets. * 2. UDP sockets. * 3. MIDI pipe. */ if (!global.libtest) if ((synth->sid = initConnection(&global, synth)) < 0) return(-1); for (i = 0; i < DEVICE_COUNT; i++) synth->dispatch[i].routine = junoMidiSendMsg; dispatch[FIRST_DEV].controller = 126; dispatch[FIRST_DEV + 0].operator = 17; dispatch[FIRST_DEV + 1].controller = 126; dispatch[FIRST_DEV + 1].operator = 9; dispatch[FIRST_DEV + 2].controller = 126; dispatch[FIRST_DEV + 2].operator = 16; dispatch[FIRST_DEV + 3].controller = 126; dispatch[FIRST_DEV + 3].operator = 1; dispatch[FIRST_DEV + 4].controller = 126; dispatch[FIRST_DEV + 4].operator = 0; dispatch[FIRST_DEV + 5].controller = 126; dispatch[FIRST_DEV + 5].operator = 3; dispatch[FIRST_DEV + 6].routine = (synthRoutine) junoTranspose; dispatch[FIRST_DEV + 7].routine = (synthRoutine) junoHold; dispatch[FIRST_DEV + 8].controller = 0; dispatch[FIRST_DEV + 8].operator = 2; dispatch[FIRST_DEV + 9].controller = 7; dispatch[FIRST_DEV + 9].operator = 0; dispatch[FIRST_DEV + 10].controller = 126; dispatch[FIRST_DEV + 10].operator = 4; dispatch[FIRST_DEV + 11].controller = 126; dispatch[FIRST_DEV + 11].operator = 5; dispatch[FIRST_DEV + 12].controller = 126; dispatch[FIRST_DEV + 12].operator = 7; dispatch[FIRST_DEV + 13].controller = 126; dispatch[FIRST_DEV + 13].operator = 6; dispatch[FIRST_DEV + 14].controller = 1; dispatch[FIRST_DEV + 14].operator = 7; dispatch[FIRST_DEV + 15].controller = 1; dispatch[FIRST_DEV + 15].operator = 4; dispatch[FIRST_DEV + 16].controller = 1; dispatch[FIRST_DEV + 16].operator = 6; dispatch[FIRST_DEV + 17].controller = 1; dispatch[FIRST_DEV + 17].operator = 6; dispatch[FIRST_DEV + 16].routine = dispatch[FIRST_DEV + 17].routine = (synthRoutine) junoSublevel; dispatch[FIRST_DEV + 18].controller = 6; dispatch[FIRST_DEV + 18].operator = 0; dispatch[FIRST_DEV + 19].controller = 2; dispatch[FIRST_DEV + 19].operator = 0; dispatch[FIRST_DEV + 20].controller = 3; dispatch[FIRST_DEV + 20].operator = 0; dispatch[FIRST_DEV + 21].controller = 3; dispatch[FIRST_DEV + 21].operator = 1; dispatch[FIRST_DEV + 22].controller = 126; dispatch[FIRST_DEV + 22].operator = 11; dispatch[FIRST_DEV + 23].controller = 126; dispatch[FIRST_DEV + 23].operator = 12; dispatch[FIRST_DEV + 24].controller = 126; dispatch[FIRST_DEV + 24].operator = 13; dispatch[FIRST_DEV + 25].controller = 3; dispatch[FIRST_DEV + 25].operator = 3; dispatch[FIRST_DEV + 26].controller = 126; dispatch[FIRST_DEV + 26].operator = 8; dispatch[FIRST_DEV + 27].controller = 126; dispatch[FIRST_DEV + 27].operator = 15; dispatch[FIRST_DEV + 28].controller = 4; dispatch[FIRST_DEV + 28].operator = 0; dispatch[FIRST_DEV + 29].controller = 4; dispatch[FIRST_DEV + 29].operator = 1; dispatch[FIRST_DEV + 30].controller = 4; dispatch[FIRST_DEV + 30].operator = 2; dispatch[FIRST_DEV + 31].controller = 4; dispatch[FIRST_DEV + 31].operator = 3; dispatch[FIRST_DEV + 32].controller = 100; dispatch[FIRST_DEV + 32].operator = 0; dispatch[FIRST_DEV + 33].controller = 100; dispatch[FIRST_DEV + 33].operator = 0; dispatch[FIRST_DEV + 34].controller = 100; dispatch[FIRST_DEV + 34].operator = 0; dispatch[CHORUS].routine = dispatch[CHORUS + 1].routine = dispatch[CHORUS + 2].routine = (synthRoutine) junoChorus; dispatch[FIRST_DEV + 35].controller = BRISTOL_ARPEGGIATOR; dispatch[FIRST_DEV + 35].operator = BRISTOL_ARPEG_ENABLE; /* The next two may need shimming due to damaged values. */ dispatch[FIRST_DEV + 36].controller = BRISTOL_ARPEGGIATOR; dispatch[FIRST_DEV + 36].operator = BRISTOL_ARPEG_DIR; dispatch[FIRST_DEV + 37].controller = BRISTOL_ARPEGGIATOR; dispatch[FIRST_DEV + 37].operator = BRISTOL_ARPEG_RANGE; dispatch[FIRST_DEV + 38].controller = BRISTOL_ARPEGGIATOR; dispatch[FIRST_DEV + 38].operator = BRISTOL_ARPEG_RATE; /* Memory management */ dispatch[MEM_MGT].operator = 0; dispatch[MEM_MGT + 1].operator = 1; dispatch[MEM_MGT + 2].operator = 2; dispatch[MEM_MGT + 3].operator = 3; dispatch[MEM_MGT + 4].operator = 4; dispatch[MEM_MGT + 5].operator = 5; dispatch[MEM_MGT + 6].operator = 6; dispatch[MEM_MGT + 7].operator = 7; dispatch[MEM_MGT + 8].operator = 8; dispatch[MEM_MGT + 9].operator = 9; dispatch[MEM_MGT + 10].controller = 1; dispatch[MEM_MGT + 11].controller = 2; dispatch[MEM_MGT + 14].controller = 3; dispatch[MEM_MGT + 15].controller = 4; dispatch[MEM_MGT].routine = dispatch[MEM_MGT + 1].routine = dispatch[MEM_MGT + 2].routine = dispatch[MEM_MGT + 3].routine = dispatch[MEM_MGT + 4].routine = dispatch[MEM_MGT + 5].routine = dispatch[MEM_MGT + 6].routine = dispatch[MEM_MGT + 7].routine = dispatch[MEM_MGT + 8].routine = dispatch[MEM_MGT + 9].routine = dispatch[MEM_MGT + 10].routine = dispatch[MEM_MGT + 11].routine = dispatch[MEM_MGT + 14].routine = dispatch[MEM_MGT + 15].routine = (synthRoutine) junoMemory; /* Midi management */ dispatch[MIDI_MGT].routine = dispatch[MIDI_MGT + 1].routine = (synthRoutine) junoMidi; dispatch[MIDI_MGT].controller = 2; dispatch[MIDI_MGT + 1].controller = 1; /* Filter type */ bristolMidiSendMsg(global.controlfd, synth->sid, 3, 4, 4); /*bristol paramchange 126 17 1 */ bristolMidiSendMsg(global.controlfd, synth->sid, 126, 17, 1); /*after 500 bristol paramchange 7 1 12000 */ /*after 500 bristol paramchange 7 2 16383 */ /*after 500 bristol paramchange 7 3 0 */ /*after 500 bristol paramchange 7 4 16383 */ /*after 500 bristol paramchange 7 5 0 */ bristolMidiSendMsg(global.controlfd, synth->sid, 7, 1, 12000); bristolMidiSendMsg(global.controlfd, synth->sid, 7, 2, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 7, 3, 0); bristolMidiSendMsg(global.controlfd, synth->sid, 7, 4, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 7, 5, 0); bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_TRIGGER, 1); return(0); } /* * This will be called to make any routine specific parameters available. */ static int junoConfigure(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); brightonEvent event; if (synth == 0) { printf("problems going operational\n"); return(-1); } if (synth->flags & OPERATIONAL) return(0); printf("going operational\n"); synth->flags |= OPERATIONAL; synth->keypanel = 1; synth->keypanel2 = -1; synth->transpose = 36; loadMemory(synth, "juno", 0, synth->location, synth->mem.active, FIRST_DEV, 0); brightonPut(win, "bitmaps/blueprints/junoshade.xpm", 0, 0, win->width, win->height); /* * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only * occurs on first paint, so we suppress the first paint, and then request * an expose here. */ event.type = BRIGHTON_EXPOSE; event.intvalue = 1; brightonParamChange(synth->win, KEY_PANEL, -1, &event); configureGlobals(synth); return(0); } bristol-0.60.11/brighton/brightonBitOne.c0000644000175000017500000050133611746476475015210 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include #include "brighton.h" #include "brightonMini.h" #include "brightoninternals.h" static int bitoneInit(); static int bitoneConfigure(); static int bitoneCallback(brightonWindow *, int, int, float); static int midiCallback(brightonWindow *, int, int, float); static int bitoneExtendedEntry(guiSynth *, int, int, int, int, int); static int bitoneKeyCallback(brightonWindow *, int, int, float); extern guimain global; static guimain manual; #include "brightonKeys.h" /* * This will be changed for an eventual release however this allows me to test * all the emulations with the same memories. #define SYNTH_NAME "bitone" */ #define SYNTH_NAME synth->resources->name /* * We have 75 controls, will generate 150 for voice parameters. After that: * 2 + 2 + 1 + 10 + 3 + 8 + 8 = 184 and then a few for inc/dec buttons, etc. */ #define ACTIVE_DEVS 200 #define DEVICE_COUNT (ACTIVE_DEVS + 39) #define DISPLAY_DEV (ACTIVE_DEVS + 30) #define MEM_MGT ACTIVE_DEVS #define MIDI_MGT (MEM_MGT + 12) #define KEY_HOLD (7) #define KEY_PANEL 1 #define SAVE_MODE (ACTIVE_DEVS - 4) #define SAVE_STEREO (ACTIVE_DEVS - 3) #define SAVE_PEER (ACTIVE_DEVS - 2) #define STEREO_BUTTON (ACTIVE_DEVS + 2) #define PARK_BUTTON (ACTIVE_DEVS + 22) #define COMPARE_BUTTON (ACTIVE_DEVS + 23) #define DCO_1_EXCLUSIVE 95 #define DCO_2_EXCLUSIVE 96 #define EXTENDED_BUTTON 00 #define NON_EXTENDED_BUTTON 100 #define RADIOSET_1 (ACTIVE_DEVS + 9) #define RADIOSET_2 (ACTIVE_DEVS + 19) #define RADIOSET_3 ACTIVE_DEVS #define MODE_SINGLE 0 #define MODE_SPLIT 1 #define MODE_LAYER 2 #define ENTER_ADDRESS 0 #define ENTER_LOWER 1 #define ENTER_UPPER 2 static int mode = MODE_SINGLE, setsplit = 0.0, selectExtended = 0; #define DEF_SPLIT 72 /* * Max data entry identifier for bit-1 parameters. Extended data entry needs * to be handled separately. */ #define ENTRY_MAX 100 #define ENTRY_POT (ACTIVE_DEVS + 8) static int entryPoint = ENTER_ADDRESS; static int B1display[5]; /* * This is the scratchpad memory - we have on disk memories, on synth memories * with potentially one loaded memory per layer, then we have the prePark mem * where changes are made temporarily until parkted into the loaded memory. * * All parameter changes go into these layers and can be used as a quick compare * to the last loaded memories. If the settings are parked they become semi * permanant (as they have not actually been written to disk yet). We should * have a double click on Park to save both memories to disk as well. * * We need 5 scratchpads, one for each layer, a backup for each layer, and * a final one for memory copies. */ static float scratchpad0[ACTIVE_DEVS]; static float scratchpad1[ACTIVE_DEVS]; static float scratchpad2[ACTIVE_DEVS]; static float scratchpad3[ACTIVE_DEVS]; static float scratchpad4[ACTIVE_DEVS]; static float scratchpad5[DEVICE_COUNT]; /* * We are going to require 4 to cover upper and lower shadows, a fifth to * cover park/compare shadow of active memory, and we will take a sixth for * saving other memory types */ static guiSynth prePark[6]; static int memLower = 0, memUpper = -1; static int dc; /* * This structure is for device definition. The structure is defined in * include/brighton.h, further definitions in brighton/brightonDevtable.h and * include/brightoninternals.h * * typedef int (*brightonCallback)(int, float); * typedef struct BrightonLocations { * int device; 0=rotary, 1=scale, etc. * float relx, rely; relative position with regards to 1000 by 1000 window * float relw, relh; relative height. * int from, to; * brightonCallback callback; specific to this dev * char *image; bitmap. If zero take a device default. * int flags; * } brightonLocations; * * This example is for a bitoneBristol type synth interface. */ #define S1 418 #define S2 312 #define S3 228 #define S4 644 #define S5 262 #define S6 558 #define S7 644 #define S8 600 #define D1 42 #define W1 33 /* * We really need to define parameter types and ranges here to make the * interface complete. For example, the midi channels only go from 1 to 16 and * when selected as the input then the pot should configure this range. * * Similarly, if this is a button it should be 0 for the first half and 1 for * the second half. * * This only applies to the displays, not to the parameters. * * Continuous controllers actually deliver a value between 0 and 1 to the * engine - the Inc/Dec buttons actually do the steps emulating the original * by going from 0.0 to 1.0 in the given number of stages. The pot, however, * is continuous. Memories save the floating point value between 0 and 1.0, * the stepped values are firstly put on the display and sent to the engine * as the last stage of interpretation. * * The stepped controllers deliver integer values along the given range. */ #define BITONE_CONTINUOUS 0 #define BITONE_STEPPED 1 #define B1_INACTIVE 0x001 /* Skip this parameter */ #define B1_INHERIT_PRI 0x002 /* Copy from the primary layer when loading */ #define B1_INACTIVE_PEER 0x004 /* Not active in upper (second load) layer */ #define B1_USE_PRI 0x008 /* Take value from primary only */ #define B1_ALWAYS 0x010 /* All editing in double/split mode */ #define B1_INHERIT_SEC 0x020 /* Copy to the primary layer when changing */ #define B1_NO_LOAD 0x040 /* All editing in double/split mode */ #define B1_INHERIT_120 0x080 /* Copy to the primary layer when changing */ #define B1_INHERIT_121 0x100 /* Copy to the primary layer when changing */ #define B1_INHERIT_122 0x200 /* Copy to the primary layer when changing */ typedef struct B1range { int type; float min; float max; int op, cont; /* link to the engine code */ int flags; } b1range; /* * STEPPED controllers are sent as that integer value. CONTINUOUS are sent * as values from 0 to 1.0 but the range values specify how they are displayed * on the LEDs. */ b1range bitoneRange[ACTIVE_DEVS] = { {BITONE_STEPPED, 0, 1, 126, 126, B1_NO_LOAD}, /* Dummy entry */ /* LFO-1 */ {BITONE_STEPPED, 0, 1, 126, 13, 0}, {BITONE_STEPPED, 0, 1, 126, 14, 0}, {BITONE_STEPPED, 0, 1, 126, 15, 0}, {BITONE_CONTINUOUS, 0, 1, 126, 17, 0}, {BITONE_CONTINUOUS, 0, 1, 126, 18, 0}, {BITONE_CONTINUOUS, 0, 1, 126, 19, 0}, {BITONE_CONTINUOUS, 0, 1, 126, 20, 0}, {BITONE_CONTINUOUS, 0, 31, 2, 0, 0}, {BITONE_CONTINUOUS, 0, 63, 0, 0, 0}, {BITONE_CONTINUOUS, 0, 31, 0, 2, 0}, {BITONE_CONTINUOUS, 1, 32, 2, 4, 0}, {BITONE_CONTINUOUS, 0, 31, 126, 12, 0}, /* VCF - 13 */ {BITONE_CONTINUOUS, 0, 63, 7, 0, 0}, {BITONE_CONTINUOUS, 0, 63, 7, 1, 0}, {BITONE_CONTINUOUS, 0, 63, 7, 2, 0}, {BITONE_CONTINUOUS, 0, 63, 7, 3, 0}, {BITONE_CONTINUOUS, 0, 63, 7, 5, 0}, {BITONE_CONTINUOUS, 0, 1, 6, 3, 0}, {BITONE_CONTINUOUS, 0, 63, 6, 0, 0}, {BITONE_CONTINUOUS, 0, 63, 6, 1, 0}, {BITONE_CONTINUOUS, 0, 63, 6, 2, 0}, {BITONE_CONTINUOUS, 0, 63, 7, 8, 0}, {BITONE_STEPPED, 0, 1, 126, 39, 0}, /* invert */ /* DCO 1 - 24 */ {BITONE_CONTINUOUS, 0, 1, 4, 0, 0}, {BITONE_CONTINUOUS, 0, 1, 4, 1, 0}, {BITONE_CONTINUOUS, 0, 1, 4, 2, 0}, {BITONE_CONTINUOUS, 0, 1, 4, 3, 0}, {BITONE_CONTINUOUS, 0, 1, 4, 4, 0}, {BITONE_CONTINUOUS, 0, 1, 4, 5, 0}, {BITONE_CONTINUOUS, 0, 1, 4, 6, 0}, {BITONE_STEPPED, 0, 24, 4, 8, 0}, {BITONE_CONTINUOUS, 0, 31, 4, 7, 0}, {BITONE_CONTINUOUS, 0, 63, 4, 10, 0}, {BITONE_CONTINUOUS, 0, 63, 126, 8, 0}, /* DCO 2 - 35 */ {BITONE_CONTINUOUS, 0, 1, 5, 0, 0}, {BITONE_CONTINUOUS, 0, 1, 5, 1, 0}, {BITONE_CONTINUOUS, 0, 1, 5, 2, 0}, {BITONE_CONTINUOUS, 0, 1, 5, 3, 0}, {BITONE_CONTINUOUS, 0, 1, 5, 4, 0}, {BITONE_CONTINUOUS, 0, 1, 5, 5, 0}, {BITONE_CONTINUOUS, 0, 1, 5, 6, 0}, {BITONE_STEPPED, 0, 24, 5, 8, 0}, {BITONE_CONTINUOUS, 0, 31, 5, 7, 0}, {BITONE_CONTINUOUS, 0, 63, 5, 10, 0}, {BITONE_CONTINUOUS, 0, 63, 5, 9, 0}, /* VCA - 46 */ {BITONE_CONTINUOUS, 0, 63, 9, 5, 0}, {BITONE_CONTINUOUS, 0, 63, 9, 8, 0}, {BITONE_CONTINUOUS, 0, 63, 9, 4, 0}, {BITONE_CONTINUOUS, 0, 63, 9, 0, 0}, {BITONE_CONTINUOUS, 0, 63, 9, 1, 0}, {BITONE_CONTINUOUS, 0, 63, 9, 2, 0}, {BITONE_CONTINUOUS, 0, 63, 9, 3, 0}, /* LFO-2 - 53 */ {BITONE_STEPPED, 0, 1, 126, 21, 0}, {BITONE_STEPPED, 0, 1, 126, 22, 0}, {BITONE_STEPPED, 0, 1, 126, 23, 0}, {BITONE_CONTINUOUS, 0, 1, 126, 25, 0}, {BITONE_CONTINUOUS, 0, 1, 126, 26, 0}, {BITONE_CONTINUOUS, 0, 1, 126, 27, 0}, {BITONE_CONTINUOUS, 0, 1, 126, 28, 0}, {BITONE_CONTINUOUS, 0, 31, 3, 0, 0}, {BITONE_CONTINUOUS, 0, 63, 1, 0, 0}, {BITONE_CONTINUOUS, 0, 31, 1, 2, 0}, {BITONE_CONTINUOUS, 1, 32, 3, 4, 0}, /* Split Point, transpose and layer volumes - 64 */ {BITONE_STEPPED, 1, 60, 126, 101, B1_ALWAYS|B1_INHERIT_121}, {BITONE_STEPPED, 1, 60, 126, 101, B1_ALWAYS|B1_INHERIT_122}, {BITONE_CONTINUOUS, 0, 63, 126, 101, B1_USE_PRI|B1_ALWAYS}, {BITONE_CONTINUOUS, 0, 63, 126, 101, B1_USE_PRI|B1_ALWAYS}, /* MIDI REC - 68 */ {BITONE_CONTINUOUS, 0, 63, 126, 43, 0}, {BITONE_STEPPED, 0, 25, 126, 42, 0}, /* sensitivity */ {BITONE_STEPPED, 0, 2, 126, 101, 0}, /* debug */ {BITONE_STEPPED, 0, 1, 126, 101, 0}, /* Accept Program Change */ {BITONE_STEPPED, 0, 1, 126, 101, 0}, /* OMNI */ {BITONE_STEPPED, 1, 16, 126, 101, B1_ALWAYS|B1_INHERIT_120}, /* MIDI TRS - 74 */ {BITONE_STEPPED, 0, 1, 126, 101, B1_NO_LOAD}, /* MEM SEARCH UP */ {BITONE_STEPPED, 0, 1, 126, 101, B1_NO_LOAD}, /* MEM SEARCH DOWN */ {BITONE_STEPPED, 0, 1, 126, 101, B1_NO_LOAD}, /* release */ /* BIT-99 FM DCO-1->2, SYNC 2-<1, GLIDE, Unison - 77 */ {BITONE_CONTINUOUS, 0, 31, 126, 40, 0}, {BITONE_STEPPED, 0, 1, 126, 38, 0}, {BITONE_CONTINUOUS, 0, 63, 126, 0, B1_INHERIT_SEC|B1_USE_PRI|B1_INACTIVE_PEER|B1_ALWAYS}, {BITONE_STEPPED, 0, 1, 126, 7, B1_ALWAYS}, /* 81 upwards are bit-100 options */ {BITONE_STEPPED, 0, 1, 126, 101, 0}, {BITONE_CONTINUOUS, 0, 31, 126, 34, 0}, {BITONE_CONTINUOUS, 0, 31, 126, 35, 0}, {BITONE_CONTINUOUS, 0, 64, 0, 3, 0}, {BITONE_CONTINUOUS, 0, 63, 2, 5, 0}, {BITONE_STEPPED, 0, 1, 126, 29, 0}, {BITONE_STEPPED, 0, 1, 126, 101, 0}, {BITONE_CONTINUOUS, 0, 31, 126, 36, 0}, {BITONE_CONTINUOUS, 0, 31, 126, 37, 0}, {BITONE_CONTINUOUS, 0, 64, 1, 3, 0}, {BITONE_CONTINUOUS, 0, 63, 3, 5, 0}, {BITONE_STEPPED, 0, 1, 126, 30, 0}, {BITONE_CONTINUOUS, 0, 63, 126, 32, 0}, {BITONE_CONTINUOUS, 0, 63, 126, 33, 0}, {BITONE_STEPPED, 0, 1, 126, 101, 0}, {BITONE_STEPPED, 0, 1, 126, 101, 0}, {BITONE_STEPPED, 0, 2, 6, 4, 0}, {BITONE_CONTINUOUS, 0, 63, 126, 41, 0}, {BITONE_STEPPED, 0, 1, 126, 31, 0}, /* 100 is the extended entry deselector */ {BITONE_STEPPED, 0, 1, 0, 0, B1_NO_LOAD}, /* 101 is the writethru scratchpad */ {BITONE_STEPPED, 0, 1, 0, 0, 0}, {BITONE_STEPPED, 0, 1, 0, 0, 0}, /* LFO Sync */ {BITONE_STEPPED, 0, 1, 0, 1, 0}, {BITONE_STEPPED, 0, 1, 1, 1, 0}, /* Env rezero - 105 */ {BITONE_STEPPED, 0, 1, 7, 6, 0}, {BITONE_STEPPED, 0, 1, 9, 6, 0}, /* LFO rezero */ {BITONE_STEPPED, 0, 1, 2, 6, 0}, {BITONE_STEPPED, 0, 1, 3, 6, 0}, /* DEBUG debug Debug dbg 3 levels - 109 */ {BITONE_STEPPED, 0, 5, 126, 101, 0}, /* Channel gains - LR Mono LR Stereo, first lower then upper - 110*/ {BITONE_CONTINUOUS, 0, 99, 0, 0, 0}, {BITONE_CONTINUOUS, 0, 99, 0, 0, 0}, {BITONE_CONTINUOUS, 0, 99, 0, 0, 0}, {BITONE_CONTINUOUS, 0, 99, 0, 0, 0}, {BITONE_CONTINUOUS, 0, 99, 0, 0, 0}, {BITONE_CONTINUOUS, 0, 99, 0, 0, 0}, {BITONE_CONTINUOUS, 0, 99, 0, 0, 0}, {BITONE_CONTINUOUS, 0, 99, 0, 0, 0}, {BITONE_STEPPED, 0, 1, 126, 101, 0}, {BITONE_STEPPED, 0, 99, 126, 101, 0}, /* Channel/split/transpose coherency - holders only - 120 */ {BITONE_STEPPED, 0, 1, 126, 101, 0}, {BITONE_STEPPED, 0, 1, 126, 101, 0}, {BITONE_STEPPED, 0, 1, 126, 101, 0}, {BITONE_STEPPED, 0, 1, 126, 101, 0}, /* NRP Enable */ {BITONE_STEPPED, 0, 1, 126, 101, B1_INACTIVE}, {BITONE_STEPPED, 0, 1, 126, 101, B1_INACTIVE}, {BITONE_STEPPED, 0, 1, 126, 101, B1_INACTIVE}, {BITONE_STEPPED, 0, 1, 126, 101, B1_INACTIVE}, {BITONE_STEPPED, 0, 1, 126, 101, B1_INACTIVE}, {BITONE_STEPPED, 0, 1, 126, 101, B1_INACTIVE}, /* Search Up/Down - 130 */ {BITONE_STEPPED, 0, 1, 126, 101, B1_NO_LOAD}, {BITONE_STEPPED, 0, 1, 126, 101, B1_NO_LOAD}, /* Env conditional - 132 */ {BITONE_STEPPED, 0, 1, 7, 7, 0}, {BITONE_STEPPED, 0, 1, 9, 7, 0}, {BITONE_STEPPED, 0, 1, 2, 7, 0}, {BITONE_STEPPED, 0, 1, 3, 7, 0}, {BITONE_STEPPED, 0, 1, 10, 1, 0}, {BITONE_CONTINUOUS, 0, 63, 10, 2, 0}, {BITONE_CONTINUOUS, 0, 63, 126, 101, 0}, /* GLIDE */ {BITONE_CONTINUOUS, 0, 63, 126, 101, 0}, /* Gain */ /* Square wave - 140 */ {BITONE_CONTINUOUS, 0, 63, 4, 11, 0}, {BITONE_CONTINUOUS, 0, 63, 4, 12, 0}, {BITONE_CONTINUOUS, 0, 63, 5, 11, 0}, {BITONE_CONTINUOUS, 0, 63, 5, 12, 0}, {BITONE_STEPPED, 0, 1, 126, 101, B1_INACTIVE}, {BITONE_STEPPED, 0, 1, 126, 101, B1_INACTIVE}, {BITONE_STEPPED, 0, 1, 126, 101, B1_INACTIVE}, {BITONE_STEPPED, 0, 1, 126, 101, B1_INACTIVE}, {BITONE_STEPPED, 0, 1, 126, 101, B1_INACTIVE}, {BITONE_STEPPED, 0, 1, 126, 101, B1_INACTIVE}, /* Arpeggiator - 150 */ {BITONE_STEPPED, 0, 1, 125, BRISTOL_ARPEG_ENABLE, B1_INACTIVE}, {BITONE_STEPPED, 0, 3, 125, BRISTOL_ARPEG_DIR, B1_INACTIVE}, {BITONE_STEPPED, 0, 3, 125, BRISTOL_ARPEG_RANGE, B1_INACTIVE}, {BITONE_CONTINUOUS, 0, 99, 125, BRISTOL_ARPEG_RATE, B1_INACTIVE}, {BITONE_STEPPED, 0, 1, 125, BRISTOL_ARPEG_CLOCK, B1_INACTIVE}, {BITONE_STEPPED, 0, 1, 125, BRISTOL_ARPEG_TRIGGER, B1_INACTIVE}, {BITONE_STEPPED, 0, 1, 125, BRISTOL_ARPEG_POLY_2, B1_INACTIVE}, {BITONE_STEPPED, 0, 1, 125, BRISTOL_CHORD_ENABLE, B1_INACTIVE}, {BITONE_STEPPED, 0, 1, 125, BRISTOL_CHORD_RESEQ, B1_INACTIVE}, {BITONE_STEPPED, 0, 1, 125, BRISTOL_SEQ_ENABLE, B1_INACTIVE}, {BITONE_STEPPED, 0, 3, 125, BRISTOL_SEQ_DIR, B1_INACTIVE}, {BITONE_STEPPED, 0, 3, 125, BRISTOL_SEQ_RANGE, B1_INACTIVE}, {BITONE_CONTINUOUS, 0, 99, 125, BRISTOL_SEQ_RATE, B1_INACTIVE}, {BITONE_STEPPED, 0, 1, 125, BRISTOL_SEQ_CLOCK, B1_INACTIVE}, {BITONE_STEPPED, 0, 1, 125, BRISTOL_SEQ_TRIGGER, B1_INACTIVE}, {BITONE_STEPPED, 0, 1, 125, BRISTOL_SEQ_RESEQ, B1_INACTIVE}, /* Free 166 */ {BITONE_STEPPED, 0, 1, 126, 101, B1_INACTIVE}, {BITONE_STEPPED, 0, 1, 126, 101, B1_INACTIVE}, {BITONE_STEPPED, 0, 1, 126, 101, B1_INACTIVE}, {BITONE_STEPPED, 0, 1, 126, 101, B1_INACTIVE}, {BITONE_STEPPED, 0, 1, 126, 101, B1_INACTIVE}, {BITONE_STEPPED, 0, 1, 126, 101, B1_INACTIVE}, {BITONE_STEPPED, 0, 1, 126, 101, B1_INACTIVE}, {BITONE_STEPPED, 0, 1, 126, 101, B1_INACTIVE}, {BITONE_STEPPED, 0, 1, 126, 101, B1_INACTIVE}, {BITONE_STEPPED, 0, 1, 126, 101, B1_INACTIVE}, {BITONE_STEPPED, 0, 1, 126, 101, B1_INACTIVE}, {BITONE_STEPPED, 0, 1, 126, 101, B1_INACTIVE}, {BITONE_STEPPED, 0, 1, 126, 101, B1_INACTIVE}, {BITONE_STEPPED, 0, 1, 126, 101, B1_INACTIVE}, {BITONE_STEPPED, 0, 1, 126, 101, B1_INACTIVE}, {BITONE_STEPPED, 0, 1, 126, 101, B1_INACTIVE}, {BITONE_STEPPED, 0, 1, 126, 101, B1_INACTIVE}, {BITONE_STEPPED, 0, 1, 126, 101, B1_INACTIVE}, {BITONE_STEPPED, 0, 1, 126, 101, B1_INACTIVE}, {BITONE_STEPPED, 0, 1, 126, 101, B1_INACTIVE}, {BITONE_STEPPED, 0, 1, 126, 101, B1_INACTIVE}, {BITONE_STEPPED, 0, 1, 126, 101, B1_INACTIVE}, {BITONE_STEPPED, 0, 1, 126, 101, B1_INACTIVE}, {BITONE_STEPPED, 0, 1, 126, 101, B1_INACTIVE}, {BITONE_STEPPED, 0, 1, 126, 101, B1_INACTIVE}, {BITONE_STEPPED, 0, 1, 126, 101, B1_INACTIVE}, {BITONE_STEPPED, 0, 1, 126, 101, B1_INACTIVE}, {BITONE_STEPPED, 0, 1, 126, 101, B1_NO_LOAD}, {BITONE_STEPPED, 0, 1, 126, 101, B1_NO_LOAD}, {BITONE_STEPPED, 0, 1, 126, 101, B1_NO_LOAD}, {BITONE_STEPPED, 0, 1, 126, 101, B1_NO_LOAD}, {BITONE_STEPPED, 0, 1, 126, 101, B1_NO_LOAD}, {BITONE_STEPPED, 0, 1, 126, 101, B1_NO_LOAD}, /* This should be 199, the wheel controller for the second LFO */ {BITONE_CONTINUOUS, 0, 31, 126, 12, B1_NO_LOAD}, }; static brightonLocations locations[DEVICE_COUNT] = { /* * 100 withdrawn buttons for later use * * The first one was just to look at some stuff with use of the transparency * layer to highlight entry, exit and button click so that this panel of * parameters can be used to select data entry address selections. * * The first is a dummy here since the parameters start from '1'. */ {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, /* LFO-1 - 1 */ {"", 9, 291, S1, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 291, S1 + D1, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 291, S1 + D1 * 2, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 291, S1 + D1 * 3, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 291, S1 + D1 * 4, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 291, S1 + D1 * 5, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 362, S1, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 362, S1 + D1, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 362, S1 + D1 * 2, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 362, S1 + D1 * 3, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 362, S1 + D1 * 4, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 362, S1 + D1 * 5, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING|BRIGHTON_WITHDRAWN}, /* VCF - 13 */ {"", 9, 409, S2, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 409, S2 + D1, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 409, S2 + D1 * 2, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 409, S2 + D1 * 3, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 409, S2 + D1 * 4, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 478, S2, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 478, S2 + D1, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 478, S2 + D1 * 2, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 478, S2 + D1 * 3, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 478, S2 + D1 * 4, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 478, S2 + D1 * 5, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, /* DCO 1 - 24 */ {"", 9, 524, S3, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 524, S3 + D1, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 524, S3 + D1 * 2, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 524, S3 + D1 * 3, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 576, S3 + D1, 23, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 576, S3 + D1 * 2, 23, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 576, S3 + D1 * 3, 23, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 636, S3, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 636, S3 + D1, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 636, S3 + D1 * 2, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 636, S3 + D1 * 3, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, /* DCO 2 - 35 */ {"", 9, 524, S4, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 524, S4 + D1, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 524, S4 + D1 * 2, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 524, S4 + D1 * 3, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 576, S4, 23, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 576, S4 + D1 * 1, 23, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 576, S4 + D1 * 2, 23, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 636, S4, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 636, S4 + D1, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 636, S4 + D1 * 2, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 636, S4 + D1 * 3, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, /* VCA - 46 */ {"", 9, 681, S5, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 681, S5 + D1, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 681, S5 + D1 * 2, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 751, S5, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 751, S5 + D1, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 751, S5 + D1 * 2, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 751, S5 + D1 * 3, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, /* LFO-2 - 53 */ {"", 9, 681, S6, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 681, S6 + D1, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 681, S6 + D1 * 2, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 681, S6 + D1 * 3, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 681, S6 + D1 * 4, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 681, S6 + D1 * 5, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 751, S6, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 751, S6 + D1, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 751, S6 + D1 * 2, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 751, S6 + D1 * 3, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 751, S6 + D1 * 4, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, /* Split Double - 64 */ {"", 9, 409, S7, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 409, S7 + D1, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, /* Layer volumes */ {"", 9, 478, S7, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 478, S7 + D1, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, /* MIDI - 68 */ {"", 9, 811, S5, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 811, S5 + D1, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 811, S5 + D1 * 2, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 811, S5 + D1 * 3, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 811, S5 + D1 * 4, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 811, S5 + D1 * 5, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 811, S8, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 811, S8 + D1, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 811, S8 + D1 * 2, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, /* * Bit-99: FM 1->2,SYNC,GLIDE L/U - 77/78/79/80 */ {"", 9, 0, 0, 23, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING|BRIGHTON_WITHDRAWN}, {"", 9, 576, S4 + D1 * 3, 23, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING|BRIGHTON_WITHDRAWN}, {"", 9, 409, S7 + D1 * 2, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING|BRIGHTON_WITHDRAWN}, {"", 9, 478, S7 + D1 * 2, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING|BRIGHTON_WITHDRAWN}, /* These are unison - 81 and 82 */ {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, /* PWM DCO-2 - 83 */ {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, /* DCO harmonics - 84 */ {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, /* Dummies - 86 */ {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 9, 576, S3, 23, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING|BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, /* 196 is the split/double placeholder */ {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, /* This is 197 and may be the stereo placeholder */ {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, /* This is 198 and will be the peer layer placeholder */ {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, /* * This needed to move as it is parameter 12, not 64 - now at 199. The * withdrawn flag is only removed if the bit-99 is requested. */ {"", 9, 751, S6 + D1 * 5, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING|BRIGHTON_WITHDRAWN}, /* split double - 200 */ {"", 2, 217, 490, 15, 80, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 217, 700, 15, 80, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* Stereo - 202 */ {"", 2, 257, 490, 15, 80, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* Pot for tune */ {"", 0, 250, 150, 80, 80, 0, 1, 0, "bitmaps/knobs/knob1.xpm", 0, BRIGHTON_NOTCH}, /* * The following two are in the memory as non-visible placeholder for * combined patches upper/lower/split/layer, etc. It should use the same * peer memory logic employed by the Jupiter GUI. Moved to within first 100 */ {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, /* Two sliders for volume controls - 206 */ {"", 1, 51, 570, 10, 260, 0, 1, 0, "bitmaps/knobs/sliderblack5.xpm", 0, 0}, {"", 1, 72, 570, 10, 260, 0, 1, 0, "bitmaps/knobs/sliderblack5.xpm", 0, 0}, /* Pot for entry - 208 */ {"", 0, 54, 330, 80, 80, 0, 1, 0, "bitmaps/knobs/knob1.xpm", 0, 0}, /* Ten data entry buttons - 209 */ {"", 2, 100, 350, 15, 80, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 120, 350, 15, 80, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 140, 350, 15, 80, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 160, 350, 15, 80, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 180, 350, 15, 80, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 100, 490, 15, 80, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 120, 490, 15, 80, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 140, 490, 15, 80, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 160, 490, 15, 80, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 180, 490, 15, 80, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* Addr, lower, upper - 219 */ {"", 2, 100, 700, 15, 80, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 140, 700, 15, 80, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 180, 700, 15, 80, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* Park, Compare - 222 */ {"", 2, 217, 150, 15, 80, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 217, 320, 15, 80, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* Prog load - 224 */ {"", 2, 257, 320, 15, 80, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, /* save - 225 */ {"", 2, 257, 700, 15, 80, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, /* Two sliders for bend and mod - 226 */ {"", 1, 17, 150, 10, 280, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW|BRIGHTON_REVERSE}, {"", 1, 17, 500, 10, 280, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW|BRIGHTON_CENTER|BRIGHTON_REVERSE}, /* Inc/Dec for data entry - 228 */ {"", 2, 50, 430, 13, 60, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 70, 430, 13, 60, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, /* 8 LED displays - 230 */ {"", 8, 52, 150, 15, 80, 0, 9, 0, 0, 0, 0}, {"", 8, 67, 150, 15, 80, 0, 9, 0, 0, 0, 0}, {"", 8, 97, 150, 15, 80, 0, 9, 0, 0, 0, 0}, {"", 8, 111, 150, 15, 80, 0, 9, 0, 0, 0, 0}, {"", 8, 133, 150, 15, 80, 0, 9, 0, 0, 0, 0}, {"", 8, 148, 150, 15, 80, 0, 9, 0, 0, 0, 0}, {"", 8, 172, 150, 15, 80, 0, 9, 0, 0, 0, 0}, {"", 8, 187, 150, 15, 80, 0, 9, 0, 0, 0, 0}, /* The Bit-1 had a Unison button, not stereo - 238 */ {"", 2, 257, 490, 15, 80, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_WITHDRAWN}, }; #define SS1 155 #define SS2 580 #define SS3 240 #define SS4 253 #define S5 262 #define SS6 580 #define S7 644 #define S8 600 static brightonLocations locations100[DEVICE_COUNT] = { /* * 100 withdrawn buttons for later use * * The first one was just to look at some stuff with use of the transparency * layer to highlight entry, exit and button click so that this panel of * parameters can be used to select data entry address selections. * * The first is a dummy here since the parameters start from '1'. */ {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, /* LFO-1 - 1 */ {"", 9, 293, SS1, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 293, SS1 + D1, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 293, SS1 + D1 * 2, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 293, SS1 + D1 * 3, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 293, SS1 + D1 * 4, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 293, SS1 + D1 * 5, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 345, SS1, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 345, SS1 + D1, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 345, SS1 + D1 * 2, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 345, SS1 + D1 * 3, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 345, SS1 + D1 * 4, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 345, SS1 + D1 * 5, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING|BRIGHTON_WITHDRAWN}, /* VCF - 13 */ {"", 9, 763, SS4 + D1, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 763, SS4 + D1 * 2, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 763, SS4 + D1 * 3, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 763, SS4 + D1 * 4, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 763, SS4 + D1 * 5, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 833, SS4 + D1, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 833, SS4 + D1 * 2, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 833, SS4 + D1 * 3, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 833, SS4 + D1 * 4, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 833, SS4 + D1 * 5, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 833, SS4 + D1 * 6, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, /* DCO 1 - 24 */ {"", 9, 456, SS4 + D1 * 1, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 456, SS4 + D1 * 2, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 456, SS4 + D1 * 3, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 456, SS4 + D1 * 4, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 508, SS4 + D1 * 2, 23, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 508, SS4 + D1 * 3, 23, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 508, SS4 + D1 * 4, 23, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 568, SS4 + D1, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 568, SS4 + D1 * 2, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 568, SS4 + D1 * 3, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 568, SS4 + D1 * 4, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, /* DCO 2 - 35 */ {"", 9, 610, SS3 + D1 * 0, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 610, SS3 + D1 * 1, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 610, SS3 + D1 * 2, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 610, SS3 + D1 * 3, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 662, SS3 + D1 * 1, 23, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 662, SS3 + D1 * 2, 23, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 662, SS3 + D1 * 3, 23, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 721, SS3 + D1 * 0, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 721, SS3 + D1 * 1, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 721, SS3 + D1 * 2, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 721, SS3 + D1 * 3, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, /* VCA - 46 */ {"", 9, 876, SS3 + D1 * 2, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 876, SS3 + D1 * 3, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 876, SS3 + D1 * 4, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 946, SS3 + D1 * 2, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 946, SS3 + D1 * 3, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 946, SS3 + D1 * 4, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 946, SS3 + D1 * 5, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, /* LFO-2 - 53 */ {"", 9, 293, SS2, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 293, SS2 + D1, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 293, SS2 + D1 * 2, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 293, SS2 + D1 * 3, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 293, SS2 + D1 * 4, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 293, SS2 + D1 * 5, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 345, SS2, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 345, SS2 + D1, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 345, SS2 + D1 * 2, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 345, SS2 + D1 * 3, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 345, SS2 + D1 * 4, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, /* Split/Transpose - 64 */ {"", 9, 763, SS6 + D1 * 3, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 833, SS6 + D1 * 3, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, /* Layer volumes */ {"", 9, 833, SS6 + D1 * 2, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 50, 50 + D1 * 4, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN|BRIGHTON_TRACKING}, /* MIDI - 68 */ {"", 9, 876, SS6 + D1 * 2, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 876, SS6 + D1 * 3, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 876, SS6 + D1 * 4, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 946, SS6 + D1 * 2, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 946, SS6 + D1 * 3, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 946, SS6 + D1 * 4, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 607, SS6 + D1, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 607, SS6 + D1 * 2, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 763, SS6 + D1 * 2, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, /* * Bit-99: FM 1->2,SYNC,GLIDE L/U - 77/78/79/80 */ {"", 9, 508, SS3 + D1, 23, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 662, SS3 + D1 * 4, 23, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 763, SS6 + D1 * 4, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 833, SS6 + D1 * 4, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, /* LFO 1/2 options 81 - 92 */ {"", 9, 397, SS1 + D1 * 0, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 397, SS1 + D1 * 1, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 397, SS1 + D1 * 2, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 397, SS1 + D1 * 3, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 397, SS1 + D1 * 4, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 397, SS1 + D1 * 5, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 397, SS2 + D1 * 0, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 397, SS2 + D1 * 1, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 397, SS2 + D1 * 2, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 397, SS2 + D1 * 3, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 397, SS2 + D1 * 4, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 397, SS2 + D1 * 5, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, /* 93 ENV->PWM */ {"", 9, 456, SS4 + D1 * 5, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 610, SS3 + D1 * 4, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 568, SS4 + D1 * 5, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 721, SS3 + D1 * 4, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, /* Filter type */ {"", 9, 763, SS4 + D1 * 6, W1, 39, 0, 2, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, /* DCO-1 vol - 98 */ {"", 9, 508, SS4 + D1 * 5, 23, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, /* Noise per layer */ {"", 9, 650, SS2 + D1 * 1, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, /* LFO/ENV options - 103 */ {"", 9, 650, SS2 + D1 * 3, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 650, SS2 + D1 * 4, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 720, SS2 + D1 * 3, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 720, SS2 + D1 * 4, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 720, SS2 + D1 * 1, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 720, SS2 + D1 * 2, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, /* Volumes - 110 */ {"", 9, 525, SS6 + D1 * 3, 17, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 580, SS6 + D1 * 3, 17, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 525, SS6 + D1 * 4, 17, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 580, SS6 + D1 * 4, 17, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 525, SS6 + D1 * 1, 17, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 580, SS6 + D1 * 1, 17, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 525, SS6 + D1 * 2, 17, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 580, SS6 + D1 * 2, 17, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, /* Temperature - 118 */ {"", 9, 650, SS2 + D1 * 2, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, /* 120 */ {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, /* MEM Free Search - 130 */ {"", 9, 607, SS6 + D1 * 3, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 607, SS6 + D1 * 4, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, /* Save -1 and -99 */ {"", 9, 876, SS6 + D1 * 1, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 9, 946, SS6 + D1 * 1, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, /* 196 is the split/double placeholder */ {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, /* This is 197 and may be the stereo placeholder */ {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, /* This is 148 and will be the peer layer placeholder */ {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, /* * This needed to move as it is parameter 12, not 64 - now at 199. The * withdrawn flag is only removed if the bit-99 is requested. */ {"", 9, 345, SS6 + D1 * 5, W1, 39, 0, 1, 0, "bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm", BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING|BRIGHTON_WITHDRAWN}, /* split double - 200 */ {"", 2, 217, 490, 15, 80, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 217, 700, 15, 80, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* Stereo - 202 */ {"", 2, 257, 490, 15, 80, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* Pot for tune */ {"", 0, 250, 150, 80, 80, 0, 1, 0, "bitmaps/knobs/knob1.xpm", 0, BRIGHTON_NOTCH}, /* * The following two are in the memory as non-visible placeholder for * combined patches upper/lower/split/layer, etc. It should use the same * peer memory logic employed by the Jupiter GUI. Moved to within first 100 */ {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, /* Two sliders for volume controls - 206 */ {"", 1, 51, 570, 10, 260, 0, 1, 0, "bitmaps/knobs/sliderblack5.xpm", 0, 0}, {"", 1, 72, 570, 10, 260, 0, 1, 0, "bitmaps/knobs/sliderblack5.xpm", 0, 0}, /* Pot for entry - 208 */ {"", 0, 54, 330, 80, 80, 0, 1, 0, "bitmaps/knobs/knob1.xpm", 0, 0}, /* Ten data entry buttons - 209 */ {"", 2, 100, 350, 15, 80, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 120, 350, 15, 80, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 140, 350, 15, 80, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 160, 350, 15, 80, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 180, 350, 15, 80, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 100, 490, 15, 80, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 120, 490, 15, 80, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 140, 490, 15, 80, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 160, 490, 15, 80, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 180, 490, 15, 80, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* Addr, lower, upper - 219 */ {"", 2, 100, 700, 15, 80, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 140, 700, 15, 80, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 180, 700, 15, 80, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* Park, Compare - 222 */ {"", 2, 217, 150, 15, 80, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 217, 320, 15, 80, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* Prog load - 224 */ {"", 2, 257, 320, 15, 80, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, /* save - 225 */ {"", 2, 257, 700, 15, 80, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, /* Two sliders for bend and mod - 226 */ {"", 1, 17, 150, 10, 280, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW|BRIGHTON_REVERSE}, {"", 1, 17, 500, 10, 280, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW|BRIGHTON_CENTER|BRIGHTON_REVERSE}, /* Inc/Dec for data entry - 228 */ {"", 2, 50, 430, 13, 60, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 70, 430, 13, 60, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, /* 8 LED displays - 230 */ {"", 8, 52, 150, 15, 80, 0, 9, 0, 0, 0, 0}, {"", 8, 67, 150, 15, 80, 0, 9, 0, 0, 0, 0}, {"", 8, 97, 150, 15, 80, 0, 9, 0, 0, 0, 0}, {"", 8, 111, 150, 15, 80, 0, 9, 0, 0, 0, 0}, {"", 8, 133, 150, 15, 80, 0, 9, 0, 0, 0, 0}, {"", 8, 148, 150, 15, 80, 0, 9, 0, 0, 0, 0}, {"", 8, 172, 150, 15, 80, 0, 9, 0, 0, 0, 0}, {"", 8, 187, 150, 15, 80, 0, 9, 0, 0, 0, 0}, /* The Bit-1 had a Unison button, not stereo - 238 */ {"", 2, 257, 490, 15, 80, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_WITHDRAWN}, }; #define PSIZE 680 /* * This is a set of globals for the main window rendering. Again taken from * include/brighton.h * Hm, the bit-1 was black, and the bit 99 was in various builds including a * white one, but also a black one and a black one with wood panels. I would * like the black one with wood panels, so that will have to be the bit-1, the * bit-99 will be white with thin metal panels. */ brightonApp bitoneApp = { "bitone", 0, /* no blueprint on wood background. */ "bitmaps/textures/metal6.xpm", BRIGHTON_STRETCH, bitoneInit, bitoneConfigure, /* 3 callbacks, unused? */ midiCallback, destroySynth, {6, 100, 2, 2, 5, 520, 0, 0}, 788, 350, 0, 0, 4, /* one panel only */ { { "BitOne", "bitmaps/blueprints/bitone.xpm", "bitmaps/textures/metal6.xpm", BRIGHTON_STRETCH, /* flags */ 0, 0, bitoneCallback, 12, 4, 978, PSIZE - 3, DEVICE_COUNT, locations }, { "Keyboard", 0, "bitmaps/newkeys/kbg.xpm", /* flags */ 0x020|BRIGHTON_STRETCH, 0, 0, bitoneKeyCallback, 14, PSIZE, 1000, 1000 - PSIZE - 3, KEY_COUNT, keysprofile }, { "Wood Panel", 0, "bitmaps/textures/wood6.xpm", BRIGHTON_STRETCH, /* flags */ 0, 0, 0, 2, 4, 10, 996, 0, 0 }, { "Wood Panel", 0, "bitmaps/textures/wood6.xpm", BRIGHTON_STRETCH, /* flags */ 0, 0, 0, 991, 4, 10, 996, 0, 0 }, } }; /* * This may need some reworks to make sure the bit-1 screenprint displays * correctly. */ brightonApp bit99App = { "bit99", 0, /* no blueprint on wood background. */ "bitmaps/textures/metal6.xpm", BRIGHTON_STRETCH, bitoneInit, bitoneConfigure, /* 3 callbacks, unused? */ midiCallback, destroySynth, {6, 100, 2, 2, 5, 520, 0, 0}, 788, 350, 0, 0, 4, /* one panel only */ { { "Bit99", "bitmaps/blueprints/bit99.xpm", "bitmaps/textures/white.xpm", BRIGHTON_STRETCH, /* flags */ 0, 0, bitoneCallback, 12, 0, 978, PSIZE - 3, DEVICE_COUNT, locations }, { "Keyboard", 0, "bitmaps/newkeys/kbg.xpm", /* flags */ 0x020|BRIGHTON_STRETCH, 0, 0, bitoneKeyCallback, 12, PSIZE, 1006, 997 - PSIZE, KEY_COUNT, keysprofile }, { "Metal Panel", 0, "bitmaps/textures/metal7.xpm", BRIGHTON_STRETCH, /* flags */ 0, 0, 0, 1, 0, 8, 1000, 0, 0 }, { "Metal Panel", 0, "bitmaps/textures/metal7.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 991, 0, 7, 1000, 0, 0 }, } }; brightonApp bit100App = { "bit100", 0, /* no blueprint on wood background. */ "bitmaps/textures/metal6.xpm", BRIGHTON_STRETCH, bitoneInit, bitoneConfigure, /* 3 callbacks, unused? */ midiCallback, destroySynth, {6, 100, 2, 2, 5, 520, 0, 0}, 788, 350, 0, 0, 4, /* one panel only */ { { "BitOne", "bitmaps/blueprints/bit100.xpm", "bitmaps/textures/metal6.xpm", BRIGHTON_STRETCH, /* flags */ 0, 0, bitoneCallback, 12, 4, 978, PSIZE - 3, DEVICE_COUNT, locations100 }, { "Keyboard", 0, "bitmaps/newkeys/kbg.xpm", /* flags */ 0x020|BRIGHTON_STRETCH, 0, 0, bitoneKeyCallback, 14, PSIZE, 1000, 1000 - PSIZE - 3, KEY_COUNT, keysprofile }, { "Wood Panel", 0, "bitmaps/textures/wood6.xpm", BRIGHTON_STRETCH, /* flags */ 0, 0, 0, 2, 4, 10, 996, 0, 0 }, { "Wood Panel", 0, "bitmaps/textures/wood6.xpm", BRIGHTON_STRETCH, /* flags */ 0, 0, 0, 991, 4, 10, 996, 0, 0 }, } }; static int b1decimal(int index, float value) { return(bitoneRange[index].min + (int) (value * ((float) (bitoneRange[index].max - bitoneRange[index].min + 1)))); } static int b1debug(guiSynth *synth, int level) { if (b1decimal(109, synth->mem.param[109]) >= level) return(1); return(0); } /* * These will return just the prePark memory, not the actual synth. */ static guiSynth * b1getScratch(guiSynth *synth) { if (synth->mem.param[101] != 0) { if (entryPoint == ENTER_UPPER) return ((guiSynth *) synth->second); else return (synth); } else { if (entryPoint == ENTER_UPPER) return (&prePark[1]); else return (&prePark[0]); } } /* * Param is a float from 0 to 1.0, turn it into a value in the range of the * parameter */ static float b1GetRangeValue(guiSynth *synth, int index) { switch (bitoneRange[index].type) { default: case BITONE_CONTINUOUS: return(synth->mem.param[index]); case BITONE_STEPPED: return(bitoneRange[index].min + synth->mem.param[index] * (bitoneRange[index].max - bitoneRange[index].min + 1)); } } static void b1SetSplit(guiSynth *synth) { int lsp, usp; if (b1debug(synth, 1)) printf("setSplit: %i/%i\n", b1decimal(64, prePark[0].mem.param[64]), b1decimal(64, prePark[1].mem.param[64])); if (mode == MODE_SINGLE) /* We could consider clearing any splitpoints here as well */ return; /* * Find and apply split points * We need to consider DE-121 for multiple splits. */ if (mode == MODE_SPLIT) { if (synth->mem.param[121] != 0) { lsp = b1GetRangeValue(&prePark[0], 64) + synth->transpose; usp = b1GetRangeValue(&prePark[1], 64) + 1 + synth->transpose; } else { lsp = b1GetRangeValue(&prePark[0], 64) + synth->transpose; usp = b1GetRangeValue(&prePark[0], 64) + 1 + synth->transpose; } } else { if (synth->mem.param[121] != 0) { lsp = b1GetRangeValue(&prePark[0], 64) + synth->transpose; usp = b1GetRangeValue(&prePark[1], 64) + 1 + synth->transpose; } else { lsp = 127; usp = 0; } } if (global.libtest == 0) { bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_HIGHKEY|lsp); bristolMidiSendMsg(global.controlfd, synth->sid2, 127, 0, BRISTOL_LOWKEY|usp); } setsplit = 0.0; } /* * The next two should come out of here and go into a separate arpeggiator file * or failing that into brightonRoutines.c */ int seqInsert(arpeggiatorMemory *seq, int note, int transpose) { printf("arpeg %i + %i at %i\n", note, transpose, (int) seq->s_max); if (seq->s_max == 0) seq->s_dif = note + transpose; seq->sequence[(int) (seq->s_max)] = (float) (note + transpose - seq->s_dif); if ((seq->s_max += 1) >= BRISTOL_SEQ_MAX) { seq->s_max = BRISTOL_SEQ_MAX; return(-1); } return(0); } int chordInsert(arpeggiatorMemory *seq, int note, int transpose) { printf("chord %i + %i at %i\n", note, transpose, (int) seq->c_count); if (seq->c_count == 0) seq->c_dif = note + transpose; seq->chord[(int) (seq->c_count)] = (float) (note + transpose - seq->c_dif); if ((seq->c_count += 1) >= BRISTOL_CHORD_MAX) { seq->c_count = BRISTOL_CHORD_MAX; return(-1); } return(0); } /* * We really want to just use one midi channel and let the midi library decide * that we have multiple synths on the channel with their own split points. * The lower layer should define the midi channel, split point and transpose * of upper layer. */ static int bitoneKeyCallback(brightonWindow *win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); guiSynth *layer = b1getScratch(synth); if ((synth->mem.param[155] != 0) && (value != 0)) { if (entryPoint == ENTER_UPPER) seqInsert((arpeggiatorMemory *) synth->seq2.param, (int) index, synth->transpose); else seqInsert((arpeggiatorMemory *) synth->seq1.param, (int) index, synth->transpose); } if ((synth->mem.param[157] != 0) && (value != 0)) { if (entryPoint == ENTER_UPPER) chordInsert((arpeggiatorMemory *) synth->seq2.param, (int) index, synth->transpose); else chordInsert((arpeggiatorMemory *) synth->seq1.param, (int) index, synth->transpose); } if (global.libtest) return(0); if (b1debug(synth, 4)) printf("b1keycallback(%i, %i, %f): %i %i\n", panel, index, value, synth->transpose, global.controlfd); if (setsplit != 0.0) { if (b1debug(synth, 1)) printf("setting (1) splitpoint to %i\n", index); layer->mem.param[64] = index + synth->transpose; setsplit = 0; b1SetSplit(synth); } if ((mode == MODE_SINGLE) || (synth->mem.param[120] == 0) || (synth->midichannel == ((guiSynth *) synth->second)->midichannel)) { /* * Want to send a note event, on or off, for this index + transpose only * on the lower layer midichannel. This actually suffices for all cases * where we use a single midi channel hence the logic. */ if (value) bristolMidiSendMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_KEYON, 0, index + synth->transpose); else bristolMidiSendMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_KEYOFF, 0, index + synth->transpose); return(0); } if (b1debug(synth, 2)) printf("key event to chan %i/%i (%0.0f)\n", synth->midichannel, ((guiSynth *) synth->second)->midichannel, synth->mem.param[120]); /* * So we have a single key event and two MIDI channels. Just send the * event on both channels, no need to be difficult about it since if this * was a split configuration the library filters out the events. */ if (value) { bristolMidiSendMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_KEYON, 0, index + synth->transpose); bristolMidiSendMsg(global.controlfd, ((guiSynth *) synth->second)->midichannel, BRISTOL_EVENT_KEYON, 0, index + synth->transpose); } else { bristolMidiSendMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_KEYOFF, 0, index + synth->transpose); bristolMidiSendMsg(global.controlfd, ((guiSynth *) synth->second)->midichannel, BRISTOL_EVENT_KEYOFF, 0, index + synth->transpose); } return(0); } static void bitoneCompareOff(guiSynth *synth) { brightonEvent event; /* * If we are changing entryPoint we should first disactivate any compare * button to ensure we have the correct scratchpad, etc. */ if (synth->mem.param[COMPARE_BUTTON] != 0.0) { event.type = BRIGHTON_FLOAT; event.value = 0.0; brightonParamChange(synth->win, 0, COMPARE_BUTTON, &event); } } /* * At this point we have loaded a memory so we need to send those actual new * parameters to the engine. This is an issue for MIDI program load, perhaps * we should consider dual load above memory 74 as per the original? * * The path of least resistance here is to scan through the the memory table * incrementing the input selector and delivering the memory value to the * data entry pot..... */ static void bitoneMemoryShim(guiSynth *synth, int from) { int i, uh, lh; brightonEvent event; guiSynth *layer = synth, *scratch = b1getScratch(synth), *scratch2; /* * Clear any mem search flags. */ synth->mem.param[74] = prePark[0].mem.param[74] = prePark[1].mem.param[74] = 0; synth->mem.param[75] = prePark[0].mem.param[75] = prePark[1].mem.param[75] = 0; synth->mem.param[130] = prePark[0].mem.param[130] = prePark[1].mem.param[130] = 0; synth->mem.param[131] = prePark[0].mem.param[131] = prePark[1].mem.param[131] = 0; if (b1debug(synth, 2)) printf("bitoneMemoryShim(%i)\n", from); /* * Save the current display settings */ uh = synth->mem.param[DISPLAY_DEV + 2]; lh = synth->mem.param[DISPLAY_DEV + 3]; /* * Select layer */ event.type = BRIGHTON_FLOAT; if (entryPoint == ENTER_UPPER) { layer = (guiSynth *) synth->second; scratch2 = &prePark[0]; } else scratch2 = &prePark[1]; synth->flags |= MEM_LOADING; layer->flags |= MEM_LOADING; /* * scan through all the parameters backwards. We go backwards since the * higher numbers parameter are hidden but may actually affect the operation * of the lower ordered ones - the higher parameters may override the * default Bit features. */ for (i = from - 1; i >= 0 ; i--) { if ((bitoneRange[i].flags & B1_INACTIVE) != 0) continue; if ((bitoneRange[i].flags & B1_NO_LOAD) != 0) continue; synth->mem.param[DISPLAY_DEV + 2] = i / 10; synth->mem.param[DISPLAY_DEV + 3] = i % 10; if (i >= 100) { synth->mem.param[DISPLAY_DEV + 2] -= 10; synth->mem.param[EXTENDED_BUTTON] = 1.0; } else synth->mem.param[EXTENDED_BUTTON] = 0; /* * We really ought to consider rounding here? No, the entry pot will * do that for us, that is the whole point of dispatching these events. */ event.value = scratch->mem.param[i] = layer->mem.param[i]; /* * Check for the DC flag, then check the bitoneRange flags for whether * this parameter should be put into effect, should be inherrited from * the lower layer, etc. * * The inherit flags need to be reviewed since they depend on the * DE 120/121/122 options for dual settings..... */ if ((dc != 0) || (entryPoint == ENTER_UPPER)) { if (bitoneRange[i].flags & B1_INHERIT_PRI) { if (b1debug(synth, 2)) printf("inherrit %i\n", i); event.value = scratch->mem.param[i] = prePark[0].mem.param[i]; } if ((bitoneRange[i].flags & B1_INACTIVE_PEER) != 0) continue; if ((bitoneRange[i].flags & B1_USE_PRI) != 0) event.value = prePark[0].mem.param[i]; } brightonParamChange(synth->win, 0, ENTRY_POT, &event); } synth->flags &= ~MEM_LOADING; layer->flags &= ~MEM_LOADING; /* * Return the previous values to display. */ synth->mem.param[DISPLAY_DEV + 2] = uh; synth->mem.param[DISPLAY_DEV + 3] = lh; synth->mem.param[EXTENDED_BUTTON] = 0; /* * Since the memory was loaded with NOCALLS we have to request our * arpeggiation stuffing manually too. */ if (synth->seq1.param == NULL) { loadSequence(&synth->seq1, SYNTH_NAME, 0, 0); if (synth->seq2.param == NULL) loadSequence(&synth->seq2, SYNTH_NAME, 0, BRISTOL_SID2); } else { if (entryPoint == ENTER_UPPER) fillSequencer(synth, (arpeggiatorMemory *) synth->seq2.param, BRISTOL_SID2); else fillSequencer(synth, (arpeggiatorMemory *) synth->seq1.param, 0); } if (b1debug(synth, 2)) printf("bitoneMemoryShim done\n"); } static int midiCallback(brightonWindow *win, int controller, int value, float n) { guiSynth *synth = findSynth(global.synths, win); if (b1debug(synth, 3)) printf("midi callback: %x, %i\n", controller, value); switch(controller) { case MIDI_PROGRAM: if (synth->mem.param[71] != 0) { if (b1debug(synth, 0)) printf("midi program change not active\n"); return(0); } /* * We should accept 0..74 as lower layer and above that as dual * loading requests. */ printf("midi program: %x, %i\n", controller, value); synth->location = value; loadMemory(synth, SYNTH_NAME, 0, synth->bank * 100 + synth->location, synth->mem.active, 0, BRISTOL_NOCALLS|BRISTOL_FORCE); bitoneMemoryShim(synth, ENTRY_MAX); break; case MIDI_BANK_SELECT: if (synth->mem.param[71] != 0) { if (b1debug(synth, 0)) printf("midi program change not active\n"); return(0); } printf("midi banksel: %x, %i\n", controller, value); synth->location %= 100; synth->bank = value; loadMemory(synth, SYNTH_NAME, 0, synth->bank * 100 + synth->location, synth->mem.active, 0, BRISTOL_NOCALLS|BRISTOL_FORCE); break; } return(0); } static int bitoneUpdateDisplayDec(guiSynth *synth, int fd, int chan, int c, int o, int v) { int ho, lo, dev = DISPLAY_DEV + o; brightonEvent event; if (v < 0) { ho = lo = -10; } else { lo = v % 10; ho = v / 10; } event.type = BRIGHTON_FLOAT; event.value = (float) ho; brightonParamChange(synth->win, 0, dev, &event); event.value = (float) lo; brightonParamChange(synth->win, 0, dev + 1, &event); return(0); } static int bitoneUpdateDisplay(guiSynth *synth, int fd, int chan, int c, int o, int v) { int ho, lo, dev = DISPLAY_DEV + o; brightonEvent event; if (v < 0) { ho = lo = -10; } else { ho = v * 100 / (CONTROLLER_RANGE + 1); lo = ho % 10; ho = ho / 10; } event.type = BRIGHTON_FLOAT; event.value = (float) ho; brightonParamChange(synth->win, 0, dev, &event); event.value = (float) lo; brightonParamChange(synth->win, 0, dev + 1, &event); return(0); } /* * Double/Split has certain logical requirements. Two two buttons are mutally * exclusive, so when one goes on we have to disable the other. */ static int bitoneSplitDouble(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; guiSynth *layer = &prePark[1]; if (synth->dispatch[RADIOSET_3].other2 != 0) { synth->dispatch[RADIOSET_3].other2 = 0; return(0); } if (b1debug(synth, 4)) printf("SD %i %i\n",c,o); event.type = BRIGHTON_FLOAT; event.value = 0.0; /* * If we are going to zero and peer is zero then the operating mode is * now SINGLE. */ if ((v == 0) && (synth->mem.param[RADIOSET_3 + (1 - c)] == 0)) { mode = MODE_SINGLE; if (b1debug(synth, 1)) printf("mode single\n"); bitoneUpdateDisplay(synth, fd, chan, c, 6, -10); if (entryPoint == ENTER_UPPER) { event.value = 1.0; brightonParamChange(synth->win, 0, RADIOSET_2 + 1, &event); } /* * Actions are to mute the upper layer and revoice the lower layer to * full count, remove splits. */ bristolMidiSendMsg(fd, synth->sid2, 126, 5, 0); bristolMidiSendMsg(fd, synth->sid2, 126, 6, 0); /* Raise voices on lower layer, lower them on upper to reduce CPU */ bristolMidiSendMsg(fd, synth->sid, 126, 2, 1); bristolMidiSendMsg(fd, synth->sid2, 126, 2, 0); /* Split */ if (global.libtest == 0) { bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_HIGHKEY|127); bristolMidiSendMsg(global.controlfd, synth->sid2, 127, 0, BRISTOL_LOWKEY|126); } return(0); } if (c == 0) { float lvol, rvol; if ((synth->mem.param[RADIOSET_3 + 1] != 0) && (b1debug(synth, 3))) printf("reset peer 1 and exclude\n"); synth->dispatch[RADIOSET_3].other2 = 1; brightonParamChange(synth->win, 0, RADIOSET_3 + 1, &event); mode = MODE_SPLIT; if (b1debug(synth, 1)) printf("mode split\n"); bitoneUpdateDisplay(synth, fd, chan, c, 6, (B1display[2] + 1) * CONTROLLER_RANGE / 100); /* * Actions are to unmute the upper layer, revoice the lower layer to * half count, apply splits. The layer volumes have to take into * account the stereo button status and configured volume: * * We have issues here regarding the bit100 and its single volume * control. * * We we are a bit-100 then take the layer volumes. Other models will * take the synth volume unless otherwise denoted. */ if (synth->mem.param[118] == 0) { if (synth->mem.param[202] != 0) { /* Stereo */ lvol = prePark[0].mem.param[67] * synth->mem.param[116]; rvol = prePark[0].mem.param[67] * synth->mem.param[117]; } else { /* Mono, ie, take a stereo panned position */ lvol = prePark[0].mem.param[67] * synth->mem.param[114]; rvol = prePark[0].mem.param[67] * synth->mem.param[115]; } if (b1debug(synth, 4)) printf("split: %f %f, %f %f %f %f\n", lvol, rvol, prePark[0].mem.param[67], synth->mem.param[114], prePark[0].mem.param[67], synth->mem.param[115]); } else { if (synth->mem.param[202] != 0) { /* Stereo */ lvol = layer->mem.param[67] * synth->mem.param[116]; rvol = layer->mem.param[67] * synth->mem.param[117]; } else { /* Mono, ie, take a stereo panned position */ lvol = layer->mem.param[67] * synth->mem.param[114]; rvol = layer->mem.param[67] * synth->mem.param[115]; } if (b1debug(synth, 4)) printf("split: %f %f, %f %f %f %f\n", lvol, rvol, layer->mem.param[67], synth->mem.param[114], layer->mem.param[67], synth->mem.param[115]); } bristolMidiSendMsg(fd, synth->sid2, 126, 5, (int) (C_RANGE_MIN_1 * lvol)); bristolMidiSendMsg(fd, synth->sid2, 126, 6, (int) (C_RANGE_MIN_1 * rvol)); /* Lower voices on lower layer, raise them on upper to reduce CPU */ bristolMidiSendMsg(fd, synth->sid, 126, 2, 0); bristolMidiSendMsg(fd, synth->sid2, 126, 2, 1); if (synth->mem.param[64] == 0) setsplit = 1.0; else b1SetSplit(synth); return(0); } if (c == 1) { float lvol, rvol; if (synth->mem.param[RADIOSET_3] != 0) printf("reset peer 2 and exclude\n"); synth->dispatch[RADIOSET_3].other2 = 1; brightonParamChange(synth->win, 0, RADIOSET_3, &event); mode = MODE_LAYER; if (b1debug(synth, 1)) printf("mode layer\n"); bitoneUpdateDisplay(synth, fd, chan, c, 6, (B1display[2] + 1) * CONTROLLER_RANGE / 100); /* * Actions are to unmute the upper layer, revoice the lower layer to * half count, remove splits. */ if (synth->mem.param[118] == 0) { if (synth->mem.param[202] != 0) { /* Stereo */ lvol = prePark[0].mem.param[67] * synth->mem.param[116]; rvol = prePark[0].mem.param[67] * synth->mem.param[117]; } else { /* Mono, ie, take a stereo panned position */ lvol = prePark[0].mem.param[67] * synth->mem.param[114]; rvol = prePark[0].mem.param[67] * synth->mem.param[115]; } if (b1debug(synth, 4)) printf("split: %f %f, %f %f %f %f\n", lvol, rvol, prePark[0].mem.param[67], synth->mem.param[114], prePark[0].mem.param[67], synth->mem.param[115]); } else { if (synth->mem.param[202] != 0) { /* Stereo */ lvol = layer->mem.param[67] * synth->mem.param[116]; rvol = layer->mem.param[67] * synth->mem.param[117]; } else { /* Mono, ie, take a stereo panned position */ lvol = layer->mem.param[67] * synth->mem.param[114]; rvol = layer->mem.param[67] * synth->mem.param[115]; } if (b1debug(synth, 4)) printf("split: %f %f, %f %f %f %f\n", lvol, rvol, layer->mem.param[67], synth->mem.param[114], layer->mem.param[67], synth->mem.param[115]); } bristolMidiSendMsg(fd, synth->sid2, 126, 5, (int) (C_RANGE_MIN_1 * lvol)); bristolMidiSendMsg(fd, synth->sid2, 126, 6, (int) (C_RANGE_MIN_1 * rvol)); /* Lower voices on lower layer, raise them on upper to reduce CPU */ bristolMidiSendMsg(fd, synth->sid, 126, 2, 0); bristolMidiSendMsg(fd, synth->sid2, 126, 2, 1); /* Split */ if (global.libtest == 0) { bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_HIGHKEY|127); bristolMidiSendMsg(global.controlfd, synth->sid2, 127, 0, BRISTOL_LOWKEY|0); } } return(0); } /* * This will take a value out of the scratchpad unless it is negative. */ static void bitoneDAUpdate(guiSynth *synth) { brightonEvent event; guiSynth *layer = b1getScratch(synth); int address = 0; /* * Update the display for the given data entry point */ address = synth->mem.param[DISPLAY_DEV + 2] * 10 + synth->mem.param[DISPLAY_DEV + 3]; if (synth->mem.param[EXTENDED_BUTTON] != 0) { address += 100; event.value = synth->mem.param[address]; } else event.value = layer->mem.param[address]; event.type = BRIGHTON_FLOAT; brightonParamChange(synth->win, 0, ENTRY_POT, &event); } static int bitoneALU(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; /* * So, these are radio buttons, first force exclusion */ if (synth->dispatch[RADIOSET_2].other2) { synth->dispatch[RADIOSET_2].other2 = 0; return(0); } /* * See if we are trying to select Data Entry whilst in Split/Double without * DE 102 enabled. * * Pan that, we do need to be able to select DE but only actually edit a * few of the under control of the range flags. if ((o == 0) && (mode != MODE_SINGLE) && (synth->mem.param[102] == 0)) { synth->dispatch[RADIOSET_2].other2 = 1; event.type = BRIGHTON_FLOAT; event.value = 0.0; brightonParamChange(synth->win, 0, 219, &event); bitoneUpdateDisplay(synth, fd, chan, c, 2, -10); return(0); } */ if ((mode == MODE_SINGLE) && (o == 2)) { /* * This is 6 voice, do not allow selection of the upper layer */ event.type = BRIGHTON_FLOAT; event.value = 0.0; synth->dispatch[RADIOSET_2].other2 = 1; brightonParamChange(synth->win, 0, 221, &event); bitoneUpdateDisplay(synth, fd, chan, c, 6, -10); return(0); } bitoneCompareOff(synth); if (synth->dispatch[RADIOSET_2].other1 != -1) { synth->dispatch[RADIOSET_2].other2 = 1; event.type = BRIGHTON_FLOAT; if (synth->dispatch[RADIOSET_2].other1 != o) event.value = 0; else event.value = 1; brightonParamChange(synth->win, synth->panel, synth->dispatch[RADIOSET_2].other1 + RADIOSET_2, &event); } synth->dispatch[RADIOSET_2].other1 = o; entryPoint = o; /* * Update the data entry for the currently selected parameter plus show * the active memories */ bitoneDAUpdate(synth); bitoneUpdateDisplay(synth, fd, chan, c, 4, memLower * C_RANGE_MIN_1 / 99); if (mode == MODE_SINGLE) bitoneUpdateDisplay(synth, fd, chan, c, 6, -10); else bitoneUpdateDisplay(synth, fd, chan, c, 6, memUpper * C_RANGE_MIN_1 / 99); return(0); } /* * These are the 10 digit buttons for selecting addresses and memories */ static int bitoneEntry(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; int ho, lo; /* * So, these are radio buttons, first force exclusion */ if (synth->dispatch[RADIOSET_1].other2) { synth->dispatch[RADIOSET_1].other2 = 0; return(0); } if (synth->dispatch[RADIOSET_1].other1 != -1) { synth->dispatch[RADIOSET_1].other2 = 1; event.type = BRIGHTON_FLOAT; if (synth->dispatch[RADIOSET_1].other1 != o) event.value = 0; else event.value = 1; brightonParamChange(synth->win, synth->panel, synth->dispatch[RADIOSET_1].other1 + RADIOSET_1, &event); } synth->dispatch[RADIOSET_1].other1 = o; /* * What I want to happen here is that the numbers just rotate through those * being pressed, no effective start or endpoint. */ if (B1display[4] < 0) B1display[4] = c; else { ho = synth->mem.param[DISPLAY_DEV + entryPoint * 2 + 2] = synth->mem.param[DISPLAY_DEV + entryPoint * 2 + 3]; lo = synth->mem.param[DISPLAY_DEV + entryPoint * 2 + 3] = c; B1display[4] = ho * 10 + lo; if (entryPoint == ENTER_ADDRESS) { if (B1display[4] > ENTRY_MAX) B1display[4] = c; } else { while (B1display[4] >= 100) B1display[4] = c; } /* * Unset the compare button? */ bitoneCompareOff(synth); } B1display[entryPoint] = B1display[4]; bitoneUpdateDisplay(synth, fd, chan, c, entryPoint * 2 + 2, (B1display[4] + 1) * CONTROLLER_RANGE / 100); bitoneDAUpdate(synth); /* * This should happen early and the extended interface should take care * of all of this. if (synth->mem.param[EXTENDED_BUTTON] != 0) return(bitoneExtendedEntry(synth, fd, chan, 2, o, v)); */ return(0); } static int bitoneMidiNull(void *synth, int fd, int chan, int c, int o, int v) { if (global.libtest) printf("This is a null callback on panel 0 id 0\n"); return(0); } static void bitoneMidiShim(guiSynth *synth, int fd, int chan, int c, int o, int v) { if (b1debug(synth, 3)) printf("bitoneMidiShim(%i, %i, %i)\n", c, o, v); bristolMidiSendMsg(fd, synth->sid, c, o, v); } static int bitoneMidiSendMsg(guiSynth *synth, int fd, int chan, int c, int o, int v) { if ((c == 0) && (o == 0)) return(0); o = bitoneRange[c].cont; c = bitoneRange[c].op; if (global.libtest) { if (b1debug(synth, 3)) printf("bristolMidiSendMsg(%i, %i, %i)\n", c, o, v); return(0); } if (b1debug(synth, 4)) printf("bitoneMidiSendMsg(%i, %i, %i) %i\n", c, o, v, entryPoint); if (entryPoint == ENTER_UPPER) bristolMidiSendMsg(fd, synth->sid2, c, o, v); else bristolMidiSendMsg(fd, synth->sid, c, o, v); return(0); } static int bitoneExtendedEntry(guiSynth *synth, int fd, int chan, int c, int o, int v) { int index; float decimal; guiSynth *scratch = b1getScratch(synth); /* * If c = 0 we have come from entryPot * if c = 1 we have come from IncDec * if c = 2 we have come from entry buttons if (synth->flags & MEM_LOADING) return(0); */ index = synth->mem.param[DISPLAY_DEV + 2] * 10 + synth->mem.param[DISPLAY_DEV + 3]; if (b1debug(synth, 5)) printf("Extended 1 index %i %f (%i)\n", index, synth->mem.param[EXTENDED_BUTTON], v); if ((index == EXTENDED_BUTTON) && (v != 0) && (synth->mem.param[EXTENDED_BUTTON] != 0)) { if (b1debug(synth, 1)) printf("Exit extended data entry\n"); synth->mem.param[EXTENDED_BUTTON] = 0; synth->mem.param[NON_EXTENDED_BUTTON] = 0; scratch->mem.param[EXTENDED_BUTTON] = 0; scratch->mem.param[NON_EXTENDED_BUTTON] = 0; /* * Return second display to blank */ bitoneUpdateDisplay(synth, fd, chan, 6, 6, -10); return(0); } index += 100; /* * We have a value for the pot position and that has to be worked into * the entry range. */ decimal = bitoneRange[index].min + v * (bitoneRange[index].max - bitoneRange[index].min + 1) / CONTROLLER_RANGE; if (b1debug(synth, 5)) printf("Extended 2 index/decimal %i: %f\n", index, decimal); if (index == NON_EXTENDED_BUTTON) { if (b1debug(synth, 1)) printf("ExtendedEntry(%i, %i = %1.0f)\n", index, v, decimal); if (b1debug(synth, 5)) printf("Extended 3 index/decimal %i: %f (%i)\n", index, decimal, mode); if (mode == MODE_SINGLE) { if ((synth->mem.param[EXTENDED_BUTTON] = v) != 0.0) { brightonEvent event; if (b1debug(synth, 1)) printf("Enter extended data entry\n"); event.type = BRIGHTON_FLOAT; event.value = 10.0; /* Set last display to some value. bitoneUpdateDisplay(synth, fd, chan, 6, 6, 100 * C_RANGE_MIN_1 / 99); */ brightonParamChange(synth->win, 0, DISPLAY_DEV + 6, &event); brightonParamChange(synth->win, 0, DISPLAY_DEV + 7, &event); } } else { if ((v != 0) && (b1debug(synth, 1))) printf("Extended DE (addr=00) not in split or double\n"); synth->mem.param[EXTENDED_BUTTON] = 0; synth->mem.param[NON_EXTENDED_BUTTON] = 0; scratch->mem.param[EXTENDED_BUTTON] = 0; scratch->mem.param[NON_EXTENDED_BUTTON] = 0; v = 0; } } /* No scratchpad for compare/park with extended data sets */ synth->mem.param[index] = scratch->mem.param[index] = ((float) v) / CONTROLLER_RANGE; /* if (bitoneRange[index].type == BITONE_STEPPED) v = decimal; */ /* * We might not be able to send directly. The first 100 buttons are not * handled directly to the dispatcher but passed through to the select code. * If they had dispatchers configured they are now called here on data * entry. If none is available then I just send the parameter index/value */ if (synth->dispatch[index].routine != NULL) synth->dispatch[index].routine(synth, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, v); else bitoneMidiSendMsg(synth, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, v); if ((synth->flags & MEM_LOADING) == 0) bitoneUpdateDisplayDec(synth, fd, chan, 0, 0, decimal); return(0); } static int bitoneEntryPot(guiSynth *synth, int fd, int chan, int c, int o, int v) { int index; float decimal; guiSynth *layer = synth, *scratch = b1getScratch(synth); /* * Get the index from the second display */ index = synth->mem.param[DISPLAY_DEV + 2] * 10 + synth->mem.param[DISPLAY_DEV + 3]; if (b1debug(synth, 5)) printf("EntryPot %i, %f\n", index, synth->mem.param[EXTENDED_BUTTON]); /* * This should happen early and the extended interface should take care * of all of this. */ if ((synth->mem.param[EXTENDED_BUTTON] != 0) || (index == EXTENDED_BUTTON)) return(bitoneExtendedEntry(synth, fd, chan, 0, o, v)); if (entryPoint == ENTER_UPPER) layer = (guiSynth *) synth->second; if ((synth->mem.param[102] == 0) && (mode != MODE_SINGLE) && ((bitoneRange[index].flags & B1_ALWAYS) == 0) && ((synth->flags & MEM_LOADING) == 0)) v = scratch->mem.param[index] * CONTROLLER_RANGE; /* * We have a value for the pot position and that has to be worked into * the entry range. */ decimal = bitoneRange[index].min + v * (bitoneRange[index].max - bitoneRange[index].min + 1) / CONTROLLER_RANGE; if (bitoneRange[index].flags & B1_INACTIVE) { v = 0; decimal = 0; } if ((synth->mem.param[102] == 0) && (mode != MODE_SINGLE) && ((bitoneRange[index].flags & B1_ALWAYS) == 0) && ((synth->flags & MEM_LOADING) == 0)) { bitoneUpdateDisplayDec(synth, fd, chan, c, 0, decimal); return(0); } if (b1debug(synth, 2)) printf("entryPot(%i, %i, %i): %i %2.0f, %x\n", c, o, v, index, decimal, synth->flags); /* * What we now have to do is decide into which register to put this * parameter - upper or lower manual, and also to send the value. * * We have to be careful with Park here since this is also used to load * memories and if we don't park stuff now then we lose the load. What we * need to do is check for the MEM_LOADING flag and if set then we need to * always park the values. */ if ((synth->flags & MEM_LOADING) == 0) { bitoneUpdateDisplayDec(synth, fd, chan, c, 0, decimal); /* * We should make considerations here for some B1_INHERIT options. We * are not loading but then we have have to pass it to the primary layer * event though the layer is secondary. We just override 'scratch'. */ scratch->mem.param[index] = ((float) v) / CONTROLLER_RANGE; if (bitoneRange[index].flags & B1_INHERIT_120) { if (synth->mem.param[120] == 0) prePark[0].mem.param[index] = ((float) v) / CONTROLLER_RANGE; } else if (bitoneRange[index].flags & B1_INHERIT_121) { if (synth->mem.param[121] == 0) prePark[0].mem.param[index] = ((float) v) / CONTROLLER_RANGE; } else if (bitoneRange[index].flags & B1_INHERIT_122) { if (synth->mem.param[122] == 0) prePark[0].mem.param[index] = ((float) v) / CONTROLLER_RANGE; } else if (bitoneRange[index].flags & B1_INHERIT_SEC) prePark[0].mem.param[index] = ((float) v) / CONTROLLER_RANGE; else if (bitoneRange[index].flags & B1_INHERIT_PRI) layer->mem.param[index] = scratch->mem.param[index] = prePark[0].mem.param[index]; } else { /* * Else we are loading a memory. See if we have 'INHERIT_PRI' set * which would override this value. We cheat a little here, put the * value into the layer then see about inherit primary. If this is the * primary layer then there is little effect, if not though we will * inherit its value.... * * We also need to consider the diverse INHERIT flags here too. If we * have separate split/transpose requested then do not inherit those * flags. */ layer->mem.param[index] = scratch->mem.param[index] = ((float) v) / CONTROLLER_RANGE; if (bitoneRange[index].flags & B1_INHERIT_120) { if (synth->mem.param[120] == 0) layer->mem.param[index] = scratch->mem.param[index] = prePark[0].mem.param[index]; } else if (bitoneRange[index].flags & B1_INHERIT_121) { if (synth->mem.param[121] == 0) layer->mem.param[index] = scratch->mem.param[index] = prePark[0].mem.param[index]; } else if (bitoneRange[index].flags & B1_INHERIT_122) { if (synth->mem.param[122] == 0) layer->mem.param[index] = scratch->mem.param[index] = prePark[0].mem.param[index]; } else if (bitoneRange[index].flags & B1_INHERIT_PRI) layer->mem.param[index] = scratch->mem.param[index] = prePark[0].mem.param[index]; } if (bitoneRange[index].type == BITONE_STEPPED) v = (int) decimal; /* * We might not be able to send directly. The first 100 buttons are not * handled directly to the dispatcher but passed through to the select code. * If they had dispatchers configured they are now called here on data * entry. If none is available then I just send the parameter index/value */ if (synth->dispatch[index].routine != NULL) synth->dispatch[index].routine(synth, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, v); else bitoneMidiSendMsg(synth, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, v); return(0); } static int bitoneIncDec(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; float value = v; int index; /* * Get the index from the second display */ index = synth->mem.param[DISPLAY_DEV + 2] * 10 + synth->mem.param[DISPLAY_DEV + 3]; event.type = BRIGHTON_FLOAT; if (synth->mem.param[EXTENDED_BUTTON] != 0) index += 100; if ((v = synth->mem.param[DISPLAY_DEV + 0] * 10) < 0) v = 0; else if (v > 100) v = 0; v += synth->mem.param[DISPLAY_DEV + 1]; if (c == 0) { /* * Decrement. */ if (--v < bitoneRange[index].min) v = bitoneRange[index].min; } else { /* * Increment. */ if (++v > bitoneRange[index].max) v = bitoneRange[index].max; } if ((value = (v - bitoneRange[index].min) / (bitoneRange[index].max - bitoneRange[index].min)) > 1.0) value = 1.0; if (value < 0.0) value = 0.0; /* * This should happen early and the extended interface should take care * of all of this. if ((synth->mem.param[EXTENDED_BUTTON] != 0) || (index == EXTENDED_BUTTON)) return(bitoneExtendedEntry(synth, fd, chan, 1, c, v)); */ event.value = value; brightonParamChange(synth->win, 0, ENTRY_POT, &event); return(0); } static int bitoneSelectExtended(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; guiSynth *layer = b1getScratch(synth); if (b1debug(synth, 1)) printf("SelectExtended data entry %i %i\n", c, v); selectExtended = 100; synth->mem.param[EXTENDED_BUTTON] = 1.0; bitoneUpdateDisplay(synth, fd, chan, c - 100, 2, (c - 99) * C_RANGE_MIN_1 / 100); event.type = BRIGHTON_FLOAT; event.value = layer->mem.param[c]; brightonParamChange(synth->win, 0, ENTRY_POT, &event); return(0); } static int bitoneSelect(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; guiSynth *layer = b1getScratch(synth); if (synth->mem.param[EXTENDED_BUTTON] != 0) { if (b1debug(synth, 1)) printf("Extended data entry on address only\n"); if (selectExtended != 0) { selectExtended = 0; synth->mem.param[EXTENDED_BUTTON] = 0; } return(0); } selectExtended = 0; synth->mem.param[EXTENDED_BUTTON] = 0.0; bitoneUpdateDisplay(synth, fd, chan, c, 2, (c + 1) * CONTROLLER_RANGE / 100); event.type = BRIGHTON_FLOAT; event.value = layer->mem.param[c]; brightonParamChange(synth->win, 0, ENTRY_POT, &event); return(0); } static void bitoneSaveMemory(guiSynth *synth) { guiSynth *layer = synth; int loc, oloc = 0; /* This does not need to be initted but GCC complains */ float dbg; if (entryPoint == ENTER_UPPER) { if (synth->mem.param[102] == 0) { if (b1debug(synth, 1)) printf("No save upper layer (DE 102)\n"); return; } layer = (guiSynth *) synth->second; if ((loc = synth->mem.param[DISPLAY_DEV + 6] * 10 + synth->mem.param[DISPLAY_DEV + 7]) >= 100) oloc %= 100; if ((oloc = synth->mem.param[DISPLAY_DEV + 4] * 10 + synth->mem.param[DISPLAY_DEV + 5]) >= 100) oloc = -1; } else { if ((loc = synth->mem.param[DISPLAY_DEV + 4] * 10 + synth->mem.param[DISPLAY_DEV + 5]) >= 100) loc %= 100; if ((oloc = synth->mem.param[DISPLAY_DEV + 6] * 10 + synth->mem.param[DISPLAY_DEV + 7]) >= 100) oloc = -1; } layer->mem.param[SAVE_MODE] = mode; if (mode != MODE_SINGLE) layer->mem.param[SAVE_PEER] = oloc; else layer->mem.param[SAVE_PEER] = -1; layer->mem.param[SAVE_STEREO] = synth->mem.param[STEREO_BUTTON]; /* * Clear extended and non-extended flags, we don't want either at * startup. */ layer->mem.param[EXTENDED_BUTTON] = 0.0; layer->mem.param[74] = 0.0; layer->mem.param[75] = 0.0; layer->mem.param[130] = 0.0; layer->mem.param[131] = 0.0; layer->mem.param[NON_EXTENDED_BUTTON] = 0.0; if ((dbg = synth->mem.param[109]) != 0) printf("saving %i, peer %i\n", loc, oloc); if (b1debug(synth, 5) == 0) synth->mem.param[109] = 0; saveMemory(layer, SYNTH_NAME, 0, loc, 0); if (entryPoint == ENTER_UPPER) saveSequence(synth, SYNTH_NAME, loc, BRISTOL_SID2); else saveSequence(synth, SYNTH_NAME, loc, 0); synth->mem.param[109] = dbg; return; } int bitoneMemoryKey(guiSynth *synth, char *algo, char *name, int location, int active, int skip, int flags) { float dbgH = synth->mem.param[109]; guiSynth *layer = synth; brightonEvent event; if (entryPoint == ENTER_UPPER) { layer = (guiSynth *) synth->second; memUpper = location; } else { memLower = location; if (mode == MODE_SINGLE) memUpper = -1; } /* * Load memory - need to look at layers and selections. */ loadMemory(layer, SYNTH_NAME, 0, location, layer->mem.active, 0, BRISTOL_FORCE|BRISTOL_NOCALLS|BRISTOL_SEQLOAD|BRISTOL_SEQFORCE); if (b1debug(synth, 1)) printf("First load: %i: mode %2.0f, peer %2.0f, %i\n", location, layer->mem.param[SAVE_MODE], layer->mem.param[SAVE_PEER], entryPoint); synth->mem.param[109] = dbgH; /* call a second shim first for extended data parameters? */ if (entryPoint == ENTER_UPPER) bitoneMemoryShim(synth, ENTRY_MAX); else bitoneMemoryShim(synth, ACTIVE_DEVS - 10); bitoneDAUpdate(synth); /* * Set the stereo from the placeholder. */ event.type = BRIGHTON_FLOAT; event.value = synth->mem.param[SAVE_STEREO]; brightonParamChange(synth->win, 0, STEREO_BUTTON, &event); return(0); } static void bitoneMemory(guiSynth *synth, int fd, int chan, int c, int o, int v) { guiSynth *layer = synth, *other = (guiSynth *) synth->second; brightonEvent event; int loc; if (synth->flags & MEM_LOADING) return; if ((synth->flags & OPERATIONAL) == 0) return; /* * Saving memories requires that we take a peek at the split/double settings * and then select the memory location accordingly. These are not going to * be performance parameters so we only save a single memory at a time. */ if (c == 0) { if (brightonDoubleClick(dc) != 0) bitoneSaveMemory(synth); return; } if (c == 1) { /* * What we want to do here is have a single click load the current * layer, and a double click load the other layer IF we are in split * or double mode */ if (brightonDoubleClick(dc) == 0) { float dbgH = synth->mem.param[109]; if (entryPoint == ENTER_UPPER) { layer = (guiSynth *) synth->second; memUpper = loc = synth->mem.param[DISPLAY_DEV + 6] * 10 + synth->mem.param[DISPLAY_DEV + 7]; } else { memLower = loc = synth->mem.param[DISPLAY_DEV + 4] * 10 + synth->mem.param[DISPLAY_DEV + 5]; if (mode == MODE_SINGLE) memUpper = -1; } /* * Load memory - need to look at layers and selections. */ loadMemory(layer, SYNTH_NAME, 0, synth->bank * 100 + loc, layer->mem.active, 0, BRISTOL_FORCE|BRISTOL_NOCALLS|BRISTOL_SEQLOAD|BRISTOL_SEQFORCE); if (b1debug(synth, 1)) printf("First load: %i: mode %2.0f, peer %2.0f, %i\n", loc, layer->mem.param[SAVE_MODE], layer->mem.param[SAVE_PEER], entryPoint); synth->mem.param[109] = dbgH; /* call a second shim first for extended data parameters? */ if (entryPoint == ENTER_UPPER) bitoneMemoryShim(synth, ENTRY_MAX); else bitoneMemoryShim(synth, ACTIVE_DEVS - 10); bitoneDAUpdate(synth); /* * Set the stereo from the placeholder. */ event.type = BRIGHTON_FLOAT; event.value = synth->mem.param[SAVE_STEREO]; brightonParamChange(synth->win, 0, STEREO_BUTTON, &event); } else { int peer; if (entryPoint == ENTER_UPPER) { layer = synth; other = ((guiSynth *) synth->second); memLower = loc = ((guiSynth *) synth->second)->mem.param[SAVE_PEER]; peer = 1; } else { layer = (guiSynth *) synth->second; other = synth; memUpper = loc = synth->mem.param[SAVE_PEER]; peer = 2; } /* * See if we have a dual loadable memory: */ if ((other->mem.param[SAVE_MODE] <= 0) || (other->mem.param[SAVE_MODE] > MODE_LAYER) || (other->mem.param[SAVE_PEER] < 0)) { if (b1debug(synth, 1)) printf("not a dual loadable memory\n"); return; } if (b1debug(synth, 1)) printf("Dual load %1.0f, %1.0f: %f\n", other->mem.param[SAVE_MODE], other->mem.param[SAVE_PEER], synth->mem.param[202]); /* * Set the operative mode */ event.type = BRIGHTON_FLOAT; event.value = 1.0; brightonParamChange(synth->win, 0, RADIOSET_3 + (int) other->mem.param[SAVE_MODE] - 1, &event); /* And select a layer */ brightonParamChange(synth->win, 0, RADIOSET_2 + peer, &event); if (b1debug(synth, 1)) printf("Dual load now %i\n", entryPoint); loadMemory(layer, SYNTH_NAME, 0, synth->bank * 100 + loc, ENTRY_MAX, 0, BRISTOL_NOCALLS|BRISTOL_FORCE|BRISTOL_SEQLOAD|BRISTOL_SEQFORCE); bitoneMemoryShim(synth, ENTRY_MAX); bitoneUpdateDisplay(synth, fd, chan, c, entryPoint * 2 + 2, (loc + 1) * CONTROLLER_RANGE / 100); bitoneDAUpdate(synth); } /* * And update parameters on the display to reflect both memories and * the selected entry parameter */ } } /* * This currently (12/02/08) implements a single channel for both layers. It * needs to be extended based on DE-120 to support different channels. */ static void bitoneMidi(guiSynth *synth, int fd, int chan, int c, int o, int v) { guiSynth *layer = synth, *scratch = &prePark[0]; int newchan; if (b1debug(synth, 1)) printf("bitoneMidi(%i, %i) %i\n", b1decimal(73, prePark[0].mem.param[73]), b1decimal(73, prePark[1].mem.param[73]), entryPoint); if ((synth->flags & OPERATIONAL) == 0) return; if (entryPoint == ENTER_UPPER) { if (b1debug(synth, 5)) printf("BitOne MIDI Upper: %i, %i, %i (%i)\n", c, o, v, entryPoint); layer = (guiSynth *) synth->second; scratch = &prePark[1]; } else if (b1debug(synth, 5)) printf("BitOne MIDI Lower: %i, %i, %i (%i)\n", c, o, v, entryPoint); /* newchan = synth->mem.param[DISPLAY_DEV] * 10 + synth->mem.param[DISPLAY_DEV + 1]; */ newchan = v; /* * Logically we want to take the lower layer midi channel in all cases * except when on upper layer with DE 120 set */ if ((entryPoint == ENTER_UPPER) && (synth->mem.param[120] == 0)) newchan = b1decimal(73, prePark[0].mem.param[73]); if (newchan < 1) newchan = 1; newchan--; if (newchan < 0) newchan = 0; if (newchan > 15) newchan = 15; if (layer->mem.param[72] != 0) { layer->midichannel = newchan; if (b1debug(synth, 2)) printf("Midi channel request not active in OMNI: %i\n", newchan); return; } /* * See if we have separate MIDI channel by layer (not the default). */ if (synth->mem.param[120] == 0) { if (b1debug(synth, 2)) printf("dual send %i\n", newchan); /* * Send this to both channels. This is not always intuitive, we may * only be using one layer however we have to keep both on same channel. */ if (global.libtest == 0) { bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_MIDICHANNEL|newchan); bristolMidiSendMsg(global.controlfd, synth->sid2, 127, 0, BRISTOL_MIDICHANNEL|newchan); } } else { if (b1debug(synth, 2)) printf("single send %i on %i\n", newchan, entryPoint); /* * If we get here then we are only going to configure the channel for * the one layer and they can then be different. */ if (global.libtest == 0) { if (entryPoint == ENTER_UPPER) bristolMidiSendMsg(global.controlfd, layer->sid2, 127, 0, BRISTOL_MIDICHANNEL|newchan); else bristolMidiSendMsg(global.controlfd, layer->sid, 127, 0, BRISTOL_MIDICHANNEL|newchan); } } layer->midichannel = newchan; return; } /* * For the sake of ease of use, links have been placed here to be called * by any of the devices created. They would be better in some other file, * perhaps with this as a dispatch. * * Param refers to the device index in the locations table given below. */ static int bitoneCallback(brightonWindow * win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); int sendvalue; /* printf("bitoneCallback(%i, %f): %x\n", index, value, synth); */ if (synth == 0) return(0); if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0)) return(0); if (bitoneApp.resources[0].devlocn[index].to == 1) sendvalue = value * C_RANGE_MIN_1; else sendvalue = value; /* * See how the Split/Double is organised. If we are under the first 100 * memories and we are not split or double then we should set both synth * layers? */ if (index >= ACTIVE_DEVS) { synth->mem.param[index] = value; if (synth->dispatch[index].routine == NULL) return(0); synth->dispatch[index].routine(synth, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); } else { if (index < 100) bitoneSelect(synth, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); else bitoneSelectExtended(synth, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); } return(0); } /* * Park will first copy the scratchpads (both of them) to the synth memory * structures. A double click will save them (both?) to memories. * * I don't think we should do both at once, just the current layer..... */ static void bitonePark(guiSynth *synth, int fd, int chan, int c, int o, int v) { int i; guiSynth *scratch = &prePark[0], *layer = synth; if (brightonDoubleClick(dc) != 0) { /* * We should save and exit here. We do allow saving of the current * memory only if it is the lower layer in some circumstances. */ if ((entryPoint != ENTER_UPPER) || (synth->mem.param[102] != 0)) bitoneSaveMemory(synth); else if (b1debug(synth, 1)) printf("No save upper layers (DE 102)\n"); return; } if ((synth->mem.param[102] == 0) && (mode != MODE_SINGLE)) { if (b1debug(synth, 1)) printf("no parking layer edits (DE 102)\n"); return; } if (synth->mem.param[101] != 0) { if (b1debug(synth, 1)) printf("no park/compare scratchpad\n"); return; } if (b1debug(synth, 2)) printf("bitonePark(%i)\n", v); if (entryPoint == ENTER_UPPER) { scratch = &prePark[1]; layer = (guiSynth *) synth->second; } /* * Turn off the Compare button if lit. Oops, no, if we park when compared * then there we should revert back to the previous memory and discard the * changes - we are currently listening to the original sound, that is the * one we want to park. */ if (synth->mem.param[223] != 0) { guiSynth *p1 = &prePark[0], *p2 = &prePark[2]; if (b1debug(synth, 1)) printf("Parking with Compare, discard edits, keep original\n"); /* * Parking when compared means dump the edits we made. Copy 0->2 or * 1->3 then turn off compare. */ if (entryPoint == ENTER_UPPER) { p1 = &prePark[1]; p2 = &prePark[3]; } for (i = 0; i < ENTRY_MAX; i++) p2->mem.param[i] = p1->mem.param[i]; bitoneCompareOff(synth); } /* * Copy over respective memories. We only copy the first 100 since they are * the only ones that use the prePark cache - to compare the audio. The * Extended Entry are put directly into the synth memory bypassing the * cache. */ for (i = 0; i < ENTRY_MAX; i++) layer->mem.param[i] = scratch->mem.param[i]; } static void bitoneCompare(guiSynth *synth, int fd, int chan, int c, int o, int v) { int i; guiSynth *scratch, *scratch2, *layer; if ((synth->flags & MEM_LOADING) != 0) return; if (synth->mem.param[101] != 0) { if (b1debug(synth, 1)) printf("no park/compare scratchpad\n"); return; } if (b1debug(synth, 2)) printf("bitoneCompare(%i)\n", v); if (v != 0) { /* * We want to reactivate the loaded memory, not the scratchpad. */ if (entryPoint == ENTER_UPPER) { scratch2 = &prePark[3]; layer = (guiSynth *) synth->second; } else { scratch2 = &prePark[2]; layer = synth; } scratch = b1getScratch(synth); /* Save current scratchpad */ for (i = 0; i < ENTRY_MAX; i++) scratch2->mem.param[i] = scratch->mem.param[i]; /* Call the memory shim to activate the memory values */ bitoneMemoryShim(synth, ENTRY_MAX); bitoneDAUpdate(synth); return; } /* * Compare is going off so we want to active the layer scratchpad. * * Find the layer. * Copy layer memory to the 5th scratchpad. * Copy the layer scratch to the memory. * Shim it. * Copy 5th scratch back to memory. * Copy saved scratch back to scratch */ if (entryPoint == ENTER_UPPER) { layer = (guiSynth *) synth->second; scratch = &prePark[3]; } else { layer = synth; scratch = &prePark[2]; } scratch2 = &prePark[4]; /* Save a copy of the real memory */ for (i = 0; i < ENTRY_MAX; i++) scratch2->mem.param[i] = layer->mem.param[i]; /* Copy the layer scratch to the memory */ for (i = 0; i < ENTRY_MAX; i++) layer->mem.param[i] = scratch->mem.param[i]; /* Call the memory shim to activate this stuff */ bitoneMemoryShim(synth, ENTRY_MAX); /* Restore a copy of the real memory */ for (i = 0; i < ENTRY_MAX; i++) layer->mem.param[i] = scratch2->mem.param[i]; /* Restore a copy of original scratch */ if (entryPoint == ENTER_UPPER) scratch2 = &prePark[3]; else scratch2 = &prePark[2]; scratch = b1getScratch(synth); scratch = &prePark[0]; for (i = 0; i < ENTRY_MAX; i++) scratch->mem.param[i] = scratch2->mem.param[i]; bitoneDAUpdate(synth); } /* * The LFO waveform is exclusive and that needs to be managed here. There are * some issues related to the parking of parameters that gets kind of side- * stepped here. * * The LFO has three active waveforms, tri, ramp/saw and square. If all are * unselected I will have the LFO generate sine. */ static void bitoneLFO(guiSynth *synth, int fd, int chan, int c, int o, int v) { guiSynth *layer = b1getScratch(synth); int c0, c1, c2, c3; if (v == 0) return; /* * Now we have to form exclusions */ switch (o) { case 0: default: c0 = c < 4? 13:21; c1 = c < 4? 2:54; c2 = c < 4? 3:55; c3 = c < 4? 81:87; break; case 1: c0 = c < 4? 14:22; c1 = c < 4? 1:53; c2 = c < 4? 3:55; c3 = c < 4? 81:87; break; case 2: c0 = c < 4? 15:23; c1 = c < 4? 1:53; c2 = c < 4? 2:54; c3 = c < 4? 81:87; break; case 3: c0 = c == 81? 16:24; c1 = c == 81? 1:53; c2 = c == 81? 2:54; c3 = c == 81? 3:55; break; } bristolMidiSendMsg(fd, synth->sid, 126, c0, C_RANGE_MIN_1); layer->mem.param[c1] = 0; layer->mem.param[c2] = 0; layer->mem.param[c3] = 0; } static void bitoneStereo(guiSynth *synth, int fd, int chan, int c, int o, int v) { guiSynth *llayer = &prePark[0]; guiSynth *ulayer = &prePark[0]; int lli = 66, uli = 67; float ll, lr, ul, ur; if (b1debug(synth, 1)) printf("bitoneStereo(%i, %i, %i)\n", c, o, v); /* Intercept the requests to see if we want to rework the settings? */ if (o == 1) { /* * Stereo/Mono button */ } else { /* * Upper/Lower layer gains */ } if (synth->mem.param[118] != 0) { /* * The bit-100 flag, separate layer volumes but from the single param. */ ulayer = &prePark[1]; uli = 66; } /* * Check layer volumes and set them. The defaults will be 0.7 even panning * for Mono and hard 1.0 panning for Stereo. */ if (synth->mem.param[202] == 0) { /* * Mono panning. */ ll = llayer->mem.param[lli] * synth->mem.param[110]; lr = llayer->mem.param[lli] * synth->mem.param[111]; ul = ulayer->mem.param[uli] * synth->mem.param[114]; ur = ulayer->mem.param[uli] * synth->mem.param[115]; } else { /* * Stereo panning. */ ll = llayer->mem.param[lli] * synth->mem.param[112]; lr = llayer->mem.param[lli] * synth->mem.param[113]; ul = ulayer->mem.param[uli] * synth->mem.param[116]; ur = ulayer->mem.param[uli] * synth->mem.param[117]; } if (b1debug(synth, 3)) { printf("M: %f %f %f %f\n", synth->mem.param[110],synth->mem.param[111], synth->mem.param[114],synth->mem.param[115]); printf("S: %f %f %f %f\n", synth->mem.param[112],synth->mem.param[113], synth->mem.param[116],synth->mem.param[117]); printf("C: %f %f %f %f\n", ll, lr, ul, ur); } /* * Always send the lower layer volumes. * Send the upper layer volumes if MODE_SINGLE is not in operation */ bristolMidiSendMsg(fd, synth->sid, 126, 5, (int) (C_RANGE_MIN_1 * ll)); bristolMidiSendMsg(fd, synth->sid, 126, 6, (int) (C_RANGE_MIN_1 * lr)); if (mode != MODE_SINGLE) { if (b1debug(synth, 1)) printf("mode dual\n"); bristolMidiSendMsg(fd, synth->sid2, 126, 5, (int) (C_RANGE_MIN_1 * ul)); bristolMidiSendMsg(fd, synth->sid2, 126, 6, (int) (C_RANGE_MIN_1 * ur)); } else { if (b1debug(synth, 1)) printf("mode single\n"); bristolMidiSendMsg(fd, synth->sid2, 126, 5, 0); bristolMidiSendMsg(fd, synth->sid2, 126, 6, 0); } } /* * This is joint unison from the bit-01 controls. There are separate selectors * for the emulations per layer, control ID 80 which is consequently set here. * The value would have to be parked to be saved in memory. */ static void bitoneUnison(guiSynth *synth, int fd, int chan, int c, int o, int v) { if (v == 0) { prePark[0].mem.param[80]= 0.0; prePark[1].mem.param[80]= 0.0; } else { prePark[0].mem.param[80]= 1.0; prePark[1].mem.param[80]= 1.0; } bristolMidiSendMsg(fd, synth->sid, 126, 7, v); bristolMidiSendMsg(fd, synth->sid2, 126, 7, v); } static void bitoneDualSend(guiSynth *synth, int fd, int chan, int c, int o, int v) { bristolMidiSendMsg(fd, synth->sid, c, o, v); bristolMidiSendMsg(fd, synth->sid2, c, o, v); } static void bitoneHarmonics(guiSynth *synth, int fd, int chan, int c, int o, int v) { guiSynth *layer = b1getScratch(synth); float value; int oscIndex = 24, i; int sid = synth->sid; if (c == DCO_1_EXCLUSIVE) { c = 2; o = 0; } else if (c == DCO_2_EXCLUSIVE) { c = 2; o = 1; } if (entryPoint == 2) sid = synth->sid2; if (b1debug(synth, 2)) printf("bitoneHarmonics(%i, %i, %i)\n", c, o, v); /* * If we have the value 0 then we need to force exclusion on the different * harmonics of the DCO. */ if (c == 0) { if (b1debug(synth, 3)) printf("control\n"); /* * Select which osc to manipulate */ if (o != 0) oscIndex = 35; /* * This is the controlling boolean. If this goes to one we need to * start enforcing exclusion - take the first harmonic and clear the * rest */ if (v != 0) { value = 1.0; /* Remove all but the first harmonic */ for (i = 0;i < 4; i++) { if (layer->mem.param[oscIndex + i] != 0) { layer->mem.param[oscIndex + i] = value; /* Send event to engine */ /* Decrement the value - only the first hit will remain 1 */ if ((value -= 1.0) < 0) value = 0.0; } } } } else { int osc = 4, parm; if (b1debug(synth, 3)) printf("DCO\n"); if (c >= 35) { oscIndex = 35; osc = 5; } parm = c - oscIndex; /* * These are the harmonic selectors from the DCO. If the value is zero * just clear the harmonic, otherwise when going on we need to check * the boolean to ensure exclusion if configured. */ if (v == 0) { /* Send value to engine unless its the last one */ if ((layer->mem.param[oscIndex] == 0) && (layer->mem.param[oscIndex + 1] == 0) && (layer->mem.param[oscIndex + 2] == 0) && (layer->mem.param[oscIndex + 3] == 0)) return; bristolMidiSendMsg(fd, sid, osc, parm, v); return; } /* * Now we can turn the harmonic on */ bristolMidiSendMsg(fd, sid, osc, parm, v); /* * then we start exclusion. */ if (c >= 35) { if (layer->mem.param[DCO_2_EXCLUSIVE] == 0.0) return; oscIndex = 35; } else { if (layer->mem.param[DCO_1_EXCLUSIVE] == 0.0) return; oscIndex = 24; } value = 0.0; for (i = 0;i < 4; i++) { if ((oscIndex + i) == c) continue; if (layer->mem.param[oscIndex + i] != 0) { layer->mem.param[oscIndex + i] = 0.0; /* send value off to osc */ bristolMidiSendMsg(fd, sid, osc, i, 0); } } } } static void bitoneMod(guiSynth *synth, int fd, int chan, int c, int o, int v) { if (global.libtest) return; if (v == 0) v = 1; /* * If this is controller 0 it is the frequency control, otherwise a * generic controller 1. */ if (c == 1) { bristolMidiSendMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_PITCH, 0, (int) (v * C_RANGE_MIN_1)); if ((synth->mem.param[120] != 0) && (synth->midichannel != ((guiSynth *) synth->second)->midichannel)) bristolMidiSendMsg(global.controlfd, ((guiSynth *) synth->second)->midichannel, BRISTOL_EVENT_PITCH, 0, (int) (v * C_RANGE_MIN_1)); } else { bristolMidiControl(global.controlfd, synth->midichannel, 0, 1, ((int) (v * C_RANGE_MIN_1)) >> 7); if ((synth->mem.param[120] != 0) && (synth->midichannel != ((guiSynth *) synth->second)->midichannel)) bristolMidiControl(global.controlfd, ((guiSynth *) synth->second)->midichannel, 0, 1, ((int) (v * C_RANGE_MIN_1)) >> 7); } return; } static void bitoneGlide(guiSynth *synth, int fd, int chan, int c, int o, int v) { if (!global.libtest) { bristolMidiSendNRP(global.controlfd, synth->sid, BRISTOL_NRP_GLIDE, v); bristolMidiSendNRP(global.controlfd, synth->sid2, BRISTOL_NRP_GLIDE, v); } } static void bitoneMidiDebug(guiSynth *synth, int fd, int chan, int c, int o, int v) { if (!global.libtest) { bristolMidiSendNRP(global.controlfd, synth->sid, BRISTOL_NRP_DEBUG, v); bristolMidiSendNRP(global.controlfd, synth->sid2, BRISTOL_NRP_DEBUG, v); } } static void bitoneVelocity(guiSynth *synth, int fd, int chan, int c, int o, int v) { synth->velocity = v + 500; if (global.libtest) return; if (mode == MODE_SINGLE) { bristolMidiSendNRP(global.controlfd, synth->sid, BRISTOL_NRP_VELOCITY, synth->velocity); bristolMidiSendNRP(global.controlfd, synth->sid2, BRISTOL_NRP_VELOCITY, synth->velocity); } else { if (entryPoint == ENTER_UPPER) bristolMidiSendNRP(global.controlfd, synth->sid2, BRISTOL_NRP_VELOCITY, synth->velocity); else bristolMidiSendNRP(global.controlfd, synth->sid, BRISTOL_NRP_VELOCITY, synth->velocity); } } static void bitoneTranspose(guiSynth *synth, int fd, int chan, int c, int o, int v) { int lt = -1, ut = -1; if (b1debug(synth, 1)) printf("Transpose (%i, %f)\n", v, prePark[0].mem.param[65]); if (v > 61) /* * We have probably been given an integer from the pot range, convert * it to decimal. */ v = b1decimal(65, prePark[0].mem.param[65]); /* * We are going to request transpose to the engine. At the moment this * would cause issues with memory loading or transpose changes. The former * is avoided due to allNotesOff() when the midi channel is changed when * memories are loaded however alterations to transpose when holding notes * will need to be addressed. Resolved. * * We need to look at separate split points, this pends on the DE 121 flag. * * We either transpose just the upper layer unless we have DE 121 and we * are setting the lower layer transpose. */ if (mode == MODE_SINGLE) { lt = v; } else { if (synth->mem.param[122] != 0) { if (entryPoint == ENTER_UPPER) ut = v; else lt = v; } else ut = b1decimal(65, prePark[0].mem.param[65]); } if (b1debug(synth, 2)) printf("lt %i, ut %i\n", lt, ut); if (!global.libtest) { if (lt != -1) bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_TRANSPOSE + lt - 12); else bristolMidiSendMsg(global.controlfd, synth->sid2, 127, 0, BRISTOL_TRANSPOSE + ut - 12); } } static void bitoneOmni(guiSynth *synth, int fd, int chan, int c, int o, int v) { guiSynth *layer = b1getScratch(synth); int channel = synth->midichannel; if (v != 0) { if (b1debug(synth, 1)) printf("OMNI On Requested\n"); channel = BRISTOL_CHAN_OMNI; } else { if (b1debug(synth, 1)) printf("OMNI Off Requested\n"); } /* * See if we have separate MIDI channel by layer (not the default). */ if (layer->mem.param[120] == 0) { /* * Send this to both channels. */ if (global.libtest == 0) { bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_MIDICHANNEL|channel); bristolMidiSendMsg(global.controlfd, synth->sid2, 127, 0, BRISTOL_MIDICHANNEL|channel); } } else { /* * If we get here then we are only going to configure the channel for * the one layer and they can then be different. */ if (global.libtest == 0) { bristolMidiSendMsg(global.controlfd, layer->sid, 127, 0, BRISTOL_MIDICHANNEL|channel); } } } static void bitoneEmulationGain(guiSynth *synth, int fd, int chan, int c, int o, int v) { synth->gain = v / 16; ((guiSynth *) synth->second)->gain = v / 16; if (!global.libtest) { bristolMidiSendNRP(global.controlfd, synth->sid, BRISTOL_NRP_GAIN, v / 16); bristolMidiSendNRP(global.controlfd, synth->sid2, BRISTOL_NRP_GAIN, v / 16); } } static void bitoneNRPEnable(guiSynth *synth, int fd, int chan, int c, int o, int v) { if (!global.libtest) { bristolMidiSendNRP(global.controlfd, synth->sid, BRISTOL_NRP_ENABLE_NRP, v); bristolMidiSendNRP(global.controlfd, synth->sid2, BRISTOL_NRP_ENABLE_NRP, v); } } static void bitoneDetune(guiSynth *synth, int fd, int chan, int c, int o, int v) { int value = v / 50; if (!global.libtest) { bristolMidiSendNRP(global.controlfd, synth->sid, BRISTOL_NRP_DETUNE, value); bristolMidiSendNRP(global.controlfd, synth->sid2, BRISTOL_NRP_DETUNE, value); } } static int bitoneGetMem(guiSynth *synth, int dir) { int i = synth->location; if ((dir > 0) && (i >= 99)) i = -1; if ((dir < 0) && (i <= 0)) i = 100; while ((i += dir) != synth->location) { if (loadMemory(synth, SYNTH_NAME, 0, synth->bank * 100 + i, synth->mem.active, 0, BRISTOL_STAT) >= 0) return(i); if ((dir > 0) && (i >= 99)) i = -1; if ((dir < 0) && (i <= 0)) i = 100; } return(-1); } static int bitoneGetFreeMem(guiSynth *synth, int dir) { int i, start; start = i = synth->mem.param[DISPLAY_DEV + 4] * 10 + synth->mem.param[DISPLAY_DEV + 5]; if ((dir > 0) && (i >= 99)) i = -1; if ((dir < 0) && (i <= 0)) i = 100; while ((i += dir) != start) { if (loadMemory(synth, SYNTH_NAME, 0, synth->bank * 100 + i, synth->mem.active, 0, BRISTOL_STAT) < 0) return(i); if ((dir > 0) && (i >= 99)) i = -1; if ((dir < 0) && (i <= 0)) i = 100; } return(-1); } static int exclude = 0; static void bitoneMemSearch(guiSynth *synth, int fd, int chan, int c, int o, int v) { int i; if ((synth->flags & MEM_LOADING) != 0) return; // if ((v == 0) || (exclude != 0)) if (exclude != 0) return; /* This does not go in a memory */ synth->mem.param[c] = prePark[0].mem.param[c] = prePark[1].mem.param[c] = 0; /* * Find the next mem */ if (c == 74) { if ((i = bitoneGetMem(synth, 1)) < 0) return; } else { if ((i = bitoneGetMem(synth, -1)) < 0) return; } /* * Then stuff this into a display, exit extended and then load the memory. */ if (entryPoint == ENTER_UPPER) bitoneUpdateDisplayDec(synth, synth->sid, synth->midichannel, 0, 6, i); else bitoneUpdateDisplayDec(synth, synth->sid, synth->midichannel, 0, 4, i); synth->location = i; exclude = 1; bitoneMemory(synth, fd, chan, 1, o, 1); exclude = 0; } static void bitoneMemFreeSearch(guiSynth *synth, int fd, int chan, int c, int o, int v) { int i; if (synth->flags & MEM_LOADING) return; // if ((v == 0) || (exclude != 0)) if (exclude != 0) return; /* This does not go in a memory */ synth->mem.param[c] = prePark[0].mem.param[c] = prePark[1].mem.param[c] = 0; /* * Find a free mem */ if (c == 130) { if ((i = bitoneGetFreeMem(synth, 1)) < 0) return; } else { if ((i = bitoneGetFreeMem(synth, -1)) < 0) return; } /* * Then stuff this into a display */ if (entryPoint == ENTER_UPPER) bitoneUpdateDisplayDec(synth, synth->sid, synth->midichannel, 0, 6, i); else bitoneUpdateDisplayDec(synth, synth->sid, synth->midichannel, 0, 4, i); } static void bitoneSaveOther(guiSynth *synth, int fd, int chan, int c, int o, int v) { int i; guiSynth *scratch = b1getScratch(synth); /* * If we have extended entry and the value is zero then return. */ if ((synth->mem.param[DISPLAY_DEV + 5] * 10 + synth->mem.param[DISPLAY_DEV + 6] == 110) && (v == 0)) return; synth->mem.param[c] = 0; if (c == 193) { printf("bristol save bit-1\n"); prePark[5].location = synth->location; prePark[5].bank = synth->bank; prePark[5].win = synth->win; prePark[5].mem.active = ACTIVE_DEVS; prePark[5].resources = &bitoneApp; /* * Copy over all the parameters. */ for (i = 0; i < ACTIVE_DEVS; i++) prePark[5].mem.param[i] = scratch->mem.param[i]; for (; i < DEVICE_COUNT; i++) prePark[5].mem.param[i] = synth->mem.param[i]; /* * Clean up the ones that do not apply to this synth * * FM/Glide, etc. */ prePark[5].mem.param[72] = 1.0; /* OMNI On */ prePark[5].mem.param[77] = 0; prePark[5].mem.param[78] = 0; prePark[5].mem.param[79] = 0; prePark[5].mem.param[81] = 0; prePark[5].mem.param[82] = 0; prePark[5].mem.param[83] = 0; prePark[5].mem.param[84] = 0; prePark[5].mem.param[85] = 0; prePark[5].mem.param[86] = 1.0; /* LFO UNI */ prePark[5].mem.param[87] = 0; prePark[5].mem.param[88] = 0; prePark[5].mem.param[89] = 0; prePark[5].mem.param[90] = 0; prePark[5].mem.param[91] = 0; prePark[5].mem.param[92] = 1.0; /* LFO UNI */ prePark[5].mem.param[93] = 0.0; /* ENV PWM */ prePark[5].mem.param[94] = 0.0; /* ENV PWM */ prePark[5].mem.param[95] = 1.0; /* Restrict harmonics */ prePark[5].mem.param[96] = 1.0; /* Restrict harmonics */ prePark[5].mem.param[97] = 2.0; /* Filter */ prePark[5].mem.param[98] = 1.0; /* MIX DCO1 */ prePark[5].mem.param[99] = 1.0; /* Noise UNI */ prePark[5].mem.param[101] = 0.0; prePark[5].mem.param[102] = 0.0; prePark[5].mem.param[103] = 0.0; prePark[5].mem.param[104] = 0.0; prePark[5].mem.param[105] = 0.0; prePark[5].mem.param[106] = 0.0; prePark[5].mem.param[107] = 0.0; prePark[5].mem.param[108] = 0.0; prePark[5].mem.param[109] = 0.0; prePark[5].mem.param[110] = 0.78; prePark[5].mem.param[111] = 0.78; prePark[5].mem.param[112] = 1.0; prePark[5].mem.param[113] = 0.0; prePark[5].mem.param[114] = 0.78; prePark[5].mem.param[115] = 0.78; prePark[5].mem.param[116] = 0.0; prePark[5].mem.param[117] = 1.0; prePark[5].mem.param[118] = 0.0; for (i = 120; i < ACTIVE_DEVS; i++) prePark[5].mem.param[i] = 0; /* Carry over glide and noise settings */ prePark[5].mem.param[136] = 0.0; prePark[5].mem.param[137] = 1.0; prePark[5].mem.param[138] = synth->mem.param[138]; prePark[5].mem.param[139] = synth->mem.param[139]; } else if (c == 194) { printf("bristol save bit-99\n"); prePark[5].location = synth->location; prePark[5].bank = synth->bank; prePark[5].win = synth->win; prePark[5].resources = &bit99App; prePark[5].mem.active = ACTIVE_DEVS; /* * Copy over all the parameters. */ for (i = 0; i < ACTIVE_DEVS; i++) prePark[5].mem.param[i] = scratch->mem.param[i]; for (; i < DEVICE_COUNT; i++) prePark[5].mem.param[i] = synth->mem.param[i]; /* * Clean up the ones that do not apply to this synth */ prePark[5].mem.param[86] = 1.0; /* LFO UNI */ prePark[5].mem.param[92] = 1.0; /* LFO UNI */ prePark[5].mem.param[97] = 2.0; /* Filter */ prePark[5].mem.param[98] = 1.0; /* MIX DCO1 */ prePark[5].mem.param[99] = 1.0; /* Noise UNI */ prePark[5].mem.param[101] = 0.0; prePark[5].mem.param[102] = 0.0; prePark[5].mem.param[103] = 0.0; prePark[5].mem.param[104] = 0.0; prePark[5].mem.param[105] = 0.0; prePark[5].mem.param[106] = 0.0; prePark[5].mem.param[107] = 0.0; prePark[5].mem.param[108] = 0.0; prePark[5].mem.param[109] = 0.0; prePark[5].mem.param[118] = 0.0; for (i = 120; i < ACTIVE_DEVS; i++) prePark[5].mem.param[i] = 0; /* Carry over glide */ prePark[5].mem.param[136] = 0.0; prePark[5].mem.param[137] = 1.0; prePark[5].mem.param[138] = synth->mem.param[138]; prePark[5].mem.param[139] = synth->mem.param[139]; } else { printf("bristol save bit-100\n"); prePark[5].location = synth->location; prePark[5].bank = synth->bank; for (i = 0; i < ACTIVE_DEVS; i++) prePark[5].mem.param[i] = scratch->mem.param[i]; for (; i < DEVICE_COUNT; i++) prePark[5].mem.param[i] = synth->mem.param[i]; prePark[5].resources = &bit100App; prePark[5].win = synth->win; prePark[5].mem.active = ACTIVE_DEVS; } /* Arpeggio relearn */ prePark[5].mem.param[155] = 0; prePark[5].mem.param[157] = 0; /* * Save our 200 parameters to scratchpad, restate some of them to reflect * the configurations of the -1 or -99, save the memory then return the * scratched data. We actually just need to copy over the 100 lowest params, * the rest are defaulted. */ bitoneSaveMemory(&prePark[5]); synth->mem.param[c] = 0; } static void bitoneSeqRelearn(guiSynth *synth, int fd, int chan, int c, int o, int v) { if (b1debug(synth, 1)) printf("bitoneSeqRelearn\n"); if (synth->seq1.param == NULL) loadSequence(&synth->seq1, SYNTH_NAME, 0, 0); if (synth->seq2.param == NULL) loadSequence(&synth->seq2, SYNTH_NAME, 0, BRISTOL_SID2); /* * We need to turn off the arpeggiator to do this and reset one index */ if (v != 0) { if (entryPoint == ENTER_UPPER) { bristolMidiSendMsg(fd, synth->sid2, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_ENABLE, 0); bristolMidiSendMsg(fd, synth->sid2, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RESEQ, 1); synth->seq1.param[0] = 0; } else { bristolMidiSendMsg(fd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_ENABLE, 0); bristolMidiSendMsg(fd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RESEQ, 1); synth->seq1.param[BRISTOL_AM_SMAX] = 0; } return; } if (entryPoint == ENTER_UPPER) bristolMidiSendMsg(fd, synth->sid2, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RESEQ, 0); else bristolMidiSendMsg(fd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RESEQ, 0); } static void bitoneChordRelearn(guiSynth *synth, int fd, int chan, int c, int o, int v) { if (b1debug(synth, 1)) printf("bitoneChordRelearn\n"); if (synth->seq1.param == NULL) loadSequence(&synth->seq1, SYNTH_NAME, 0, 0); if (synth->seq2.param == NULL) loadSequence(&synth->seq2, SYNTH_NAME, 0, BRISTOL_SID2); /* * We need to turn off chording to do this and reset one index */ if (v != 0) { if (entryPoint == ENTER_UPPER) { bristolMidiSendMsg(fd, synth->sid2, BRISTOL_ARPEGGIATOR, BRISTOL_CHORD_ENABLE, 0); bristolMidiSendMsg(fd, synth->sid2, BRISTOL_ARPEGGIATOR, BRISTOL_CHORD_RESEQ, 1); synth->seq1.param[1] = 0; } else { bristolMidiSendMsg(fd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_CHORD_ENABLE, 0); bristolMidiSendMsg(fd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_CHORD_RESEQ, 1); synth->seq1.param[BRISTOL_AM_CCOUNT] = 0; } return; } if (entryPoint == ENTER_UPPER) bristolMidiSendMsg(fd, synth->sid2, BRISTOL_ARPEGGIATOR, BRISTOL_CHORD_RESEQ, 0); else bristolMidiSendMsg(fd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_CHORD_RESEQ, 0); } static void bitoneFilter(guiSynth *synth, int fd, int chan, int c, int o, int v) { if (v == 2) v = 4; if (entryPoint == ENTER_UPPER) bristolMidiSendMsg(fd, synth->sid2, 6, 4, v); else bristolMidiSendMsg(fd, synth->sid, 6, 4, v); } static void bitoneRelease(guiSynth *synth, int fd, int chan, int c, int o, int v) { if (b1debug(synth, 1)) printf("Midi Panic (%i)\n", v); if (v == 0) return; prePark[0].mem.param[76] = 0; if (!global.libtest) bristolMidiSendMsg(fd, synth->sid, 127, 0, BRISTOL_ALL_NOTES_OFF); } /* * Any location initialisation required to run the callbacks. For bristol, this * will connect to the engine, and give it some base parameters. * May need to generate some application specific menus. * Will also then make specific requests to some of the devices to alter their * rendering. */ static int bitoneInit(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); dispatcher *dispatch; int i; if (synth == 0) { synth = findSynth(global.synths, 0); if (synth == 0) { printf("cannot init\n"); return(0); } } synth->win = win; printf("Initialise the bitone link to bristol: %p\n", synth->win); synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float)); synth->mem.count = DEVICE_COUNT; synth->mem.active = ACTIVE_DEVS; synth->dispatch = (dispatcher *) brightonmalloc(DEVICE_COUNT * sizeof(dispatcher)); dispatch = synth->dispatch; synth->second = brightonmalloc(sizeof(guiSynth)); bcopy(synth, ((guiSynth *) synth->second), sizeof(guiSynth)); ((guiSynth *) synth->second)->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float)); ((guiSynth *) synth->second)->mem.count = DEVICE_COUNT; ((guiSynth *) synth->second)->mem.active = ACTIVE_DEVS; ((guiSynth *) synth->second)->dispatch = synth->dispatch; synth->synthtype = BRISTOL_BIT_ONE; ((guiSynth *) synth->second)->synthtype = BRISTOL_BIT_ONE; prePark[0].mem.param = scratchpad0; prePark[1].mem.param = scratchpad1; prePark[2].mem.param = scratchpad2; prePark[3].mem.param = scratchpad3; prePark[4].mem.param = scratchpad4; prePark[5].mem.param = scratchpad5; /* If we have a default voice count then limit it */ if (synth->voices == BRISTOL_VOICECOUNT) { synth->voices = 6; /* Uses twice the number for single mode only */ ((guiSynth *) synth->second)->voices = 3; } else ((guiSynth *) synth->second)->voices = synth->voices >> 1; /* * We really want to have three connection mechanisms. These should be * 1. Unix named sockets. * 2. UDP sockets (actually implements TCP unfortunately). * 3. MIDI pipe. */ if (!global.libtest) { int vhold = synth->voices; bcopy(&global, &manual, sizeof(guimain)); if ((synth->sid = initConnection(&global, synth)) < 0) return(-1); manual.flags |= BRISTOL_CONN_FORCE|BRIGHTON_NOENGINE; manual.host = global.host; manual.port = global.port; synth->voices = synth->voices >> 1; if ((synth->sid2 = initConnection(&manual, synth)) < 0) return(-1); global.manualfd = manual.controlfd; global.manual = &manual; manual.manual = &global; ((guiSynth *) synth->second)->sid = synth->sid2; synth->voices = vhold; } for (i = 0; i < ACTIVE_DEVS; i++) { synth->dispatch[i].controller = i; synth->dispatch[i].operator = i; } synth->dispatch[ACTIVE_DEVS - 1].controller = 12; for (; i < DEVICE_COUNT; i++) synth->dispatch[i].routine = (synthRoutine) bitoneMidiShim; synth->dispatch[0].routine = (synthRoutine) bitoneMidiNull; synth->dispatch[73].routine = (synthRoutine) bitoneMidi; /* LFO Waveform */ synth->dispatch[1].operator = 0; synth->dispatch[1].routine = (synthRoutine) bitoneLFO; synth->dispatch[2].operator = 1; synth->dispatch[2].routine = (synthRoutine) bitoneLFO; synth->dispatch[3].operator = 2; synth->dispatch[3].routine = (synthRoutine) bitoneLFO; /* LFO Waveform */ synth->dispatch[53].operator = 0; synth->dispatch[53].routine = (synthRoutine) bitoneLFO; synth->dispatch[54].operator = 1; synth->dispatch[54].routine = (synthRoutine) bitoneLFO; synth->dispatch[55].operator = 2; synth->dispatch[55].routine = (synthRoutine) bitoneLFO; /* Harmonics */ synth->dispatch[24].controller = 24; synth->dispatch[24].operator = 0; synth->dispatch[24].routine = (synthRoutine) bitoneHarmonics; synth->dispatch[25].controller = 25; synth->dispatch[25].operator = 1; synth->dispatch[25].routine = (synthRoutine) bitoneHarmonics; synth->dispatch[26].controller = 26; synth->dispatch[26].operator = 2; synth->dispatch[26].routine = (synthRoutine) bitoneHarmonics; synth->dispatch[27].controller = 27; synth->dispatch[27].operator = 3; synth->dispatch[27].routine = (synthRoutine) bitoneHarmonics; /* Harmonics */ synth->dispatch[35].controller = 35; synth->dispatch[35].operator = 0; synth->dispatch[35].routine = (synthRoutine) bitoneHarmonics; synth->dispatch[36].controller = 36; synth->dispatch[36].operator = 1; synth->dispatch[36].routine = (synthRoutine) bitoneHarmonics; synth->dispatch[37].controller = 37; synth->dispatch[37].operator = 2; synth->dispatch[37].routine = (synthRoutine) bitoneHarmonics; synth->dispatch[38].controller = 38; synth->dispatch[38].operator = 3; synth->dispatch[38].routine = (synthRoutine) bitoneHarmonics; synth->dispatch[64].routine = (synthRoutine) b1SetSplit; synth->dispatch[65].routine = (synthRoutine) bitoneTranspose; synth->dispatch[66].operator = 2; synth->dispatch[66].routine = (synthRoutine) bitoneStereo; synth->dispatch[67].operator = 2; synth->dispatch[67].routine = (synthRoutine) bitoneStereo; synth->dispatch[69].routine = (synthRoutine) bitoneVelocity; synth->dispatch[70].routine = (synthRoutine) bitoneMidiDebug; synth->dispatch[72].routine = (synthRoutine) bitoneOmni; synth->dispatch[74].routine = (synthRoutine) bitoneMemSearch; synth->dispatch[75].routine = (synthRoutine) bitoneMemSearch; synth->dispatch[76].routine = (synthRoutine) bitoneRelease; /* LFO S/H */ synth->dispatch[81].operator = 3; synth->dispatch[81].routine = (synthRoutine) bitoneLFO; synth->dispatch[87].operator = 3; synth->dispatch[87].routine = (synthRoutine) bitoneLFO; /* Filter shim */ synth->dispatch[97].routine = (synthRoutine) bitoneFilter; /* Harmonic control */ synth->dispatch[DCO_1_EXCLUSIVE].routine = (synthRoutine) bitoneHarmonics; synth->dispatch[DCO_2_EXCLUSIVE].routine = (synthRoutine) bitoneHarmonics; synth->dispatch[123].routine = (synthRoutine) bitoneNRPEnable; /* Search */ synth->dispatch[130].routine = (synthRoutine) bitoneMemFreeSearch; synth->dispatch[131].routine = (synthRoutine) bitoneMemFreeSearch; synth->dispatch[139].routine = (synthRoutine) bitoneEmulationGain; /* Split Double */ synth->dispatch[200].controller = 0; synth->dispatch[200].routine = (synthRoutine) bitoneSplitDouble; synth->dispatch[201].controller = 1; synth->dispatch[201].routine = (synthRoutine) bitoneSplitDouble; /* Stereo */ synth->dispatch[202].operator = 1; synth->dispatch[202].routine = (synthRoutine) bitoneStereo; synth->dispatch[110].operator = 1; synth->dispatch[110].routine = (synthRoutine) bitoneStereo; synth->dispatch[111].operator = 1; synth->dispatch[111].routine = (synthRoutine) bitoneStereo; synth->dispatch[112].operator = 1; synth->dispatch[112].routine = (synthRoutine) bitoneStereo; synth->dispatch[113].operator = 1; synth->dispatch[113].routine = (synthRoutine) bitoneStereo; synth->dispatch[114].operator = 1; synth->dispatch[114].routine = (synthRoutine) bitoneStereo; synth->dispatch[115].operator = 1; synth->dispatch[115].routine = (synthRoutine) bitoneStereo; synth->dispatch[116].operator = 1; synth->dispatch[116].routine = (synthRoutine) bitoneStereo; synth->dispatch[117].operator = 1; synth->dispatch[117].routine = (synthRoutine) bitoneStereo; synth->dispatch[119].routine = (synthRoutine) bitoneDetune; synth->dispatch[138].routine = (synthRoutine) bitoneGlide; synth->dispatch[158].routine = (synthRoutine) bitoneChordRelearn; synth->dispatch[165].routine = (synthRoutine) bitoneSeqRelearn; synth->dispatch[193].routine = (synthRoutine) bitoneSaveOther; synth->dispatch[194].routine = (synthRoutine) bitoneSaveOther; synth->dispatch[195].routine = (synthRoutine) bitoneSaveOther; /* Tuning */ synth->dispatch[203].controller = 126; synth->dispatch[203].operator = 1; synth->dispatch[206].controller = 126; synth->dispatch[206].operator = 3; synth->dispatch[206].routine = (synthRoutine) bitoneDualSend; synth->dispatch[207].controller = 126; synth->dispatch[207].operator = 4; synth->dispatch[207].routine = (synthRoutine) bitoneDualSend; /* Entry */ synth->dispatch[ENTRY_POT].controller = 0; synth->dispatch[ENTRY_POT].routine = (synthRoutine) bitoneEntryPot; /* Data Entry buttons */ synth->dispatch[209].controller = 1; synth->dispatch[209].operator = 0; synth->dispatch[209].routine = (synthRoutine) bitoneEntry; synth->dispatch[210].controller = 2; synth->dispatch[210].operator = 1; synth->dispatch[210].routine = (synthRoutine) bitoneEntry; synth->dispatch[211].controller = 3; synth->dispatch[211].operator = 2; synth->dispatch[211].routine = (synthRoutine) bitoneEntry; synth->dispatch[212].controller = 4; synth->dispatch[212].operator = 3; synth->dispatch[212].routine = (synthRoutine) bitoneEntry; synth->dispatch[213].controller = 5; synth->dispatch[213].operator = 4; synth->dispatch[213].routine = (synthRoutine) bitoneEntry; synth->dispatch[214].controller = 6; synth->dispatch[214].operator = 5; synth->dispatch[214].routine = (synthRoutine) bitoneEntry; synth->dispatch[215].controller = 7; synth->dispatch[215].operator = 6; synth->dispatch[215].routine = (synthRoutine) bitoneEntry; synth->dispatch[216].controller = 8; synth->dispatch[216].operator = 7; synth->dispatch[216].routine = (synthRoutine) bitoneEntry; synth->dispatch[217].controller = 9; synth->dispatch[217].operator = 8; synth->dispatch[217].routine = (synthRoutine) bitoneEntry; synth->dispatch[218].controller = 0; synth->dispatch[218].operator = 9; synth->dispatch[218].routine = (synthRoutine) bitoneEntry; /* Second radio set for address, upper and lower manual selection */ synth->dispatch[219].operator = ENTER_ADDRESS; synth->dispatch[219].controller = 6; synth->dispatch[219].routine = (synthRoutine) bitoneALU; synth->dispatch[220].operator = ENTER_LOWER; synth->dispatch[220].controller = 4; synth->dispatch[220].routine = (synthRoutine) bitoneALU; synth->dispatch[221].operator = ENTER_UPPER; synth->dispatch[221].controller = 2; synth->dispatch[221].routine = (synthRoutine) bitoneALU; synth->dispatch[222].routine = (synthRoutine) bitonePark; synth->dispatch[223].routine = (synthRoutine) bitoneCompare; synth->dispatch[224].operator = 1; synth->dispatch[224].controller = 1; synth->dispatch[224].routine = (synthRoutine) bitoneMemory; synth->dispatch[225].controller = 0; synth->dispatch[225].routine = (synthRoutine) bitoneMemory; synth->dispatch[226].controller = 0; synth->dispatch[226].routine = (synthRoutine) bitoneMod; synth->dispatch[227].controller = 1; synth->dispatch[227].routine = (synthRoutine) bitoneMod; synth->dispatch[228].controller = 0; synth->dispatch[228].routine = (synthRoutine) bitoneIncDec; synth->dispatch[229].controller = 1; synth->dispatch[229].routine = (synthRoutine) bitoneIncDec; synth->dispatch[230].routine = NULL; synth->dispatch[231].routine = NULL; synth->dispatch[232].routine = NULL; synth->dispatch[233].routine = NULL; synth->dispatch[234].routine = NULL; synth->dispatch[235].routine = NULL; synth->dispatch[236].routine = NULL; synth->dispatch[237].routine = NULL; synth->dispatch[238].routine = NULL; synth->dispatch[239].routine = NULL; /* Unison */ synth->dispatch[238].controller = 126; synth->dispatch[238].operator = 7; synth->dispatch[238].routine = (synthRoutine) bitoneUnison; /* * We need to default the LFO Envelope parameters and some other stuff. * * There are lots of defaults we need to set for the bit-1: stereo on, MIDI * channel, we need to build a method to enable disable OMNI and some of the * midi controllers such as wheel, etc. */ bitoneDualSend(synth, global.controlfd, 0, 7, 4, 16000); /* Set noise gain - reasonably low as it is going to be used for S/H also */ bitoneDualSend(synth, global.controlfd, 0, 10, 0, 1024); /* LFO Env parameters */ bitoneDualSend(synth, global.controlfd, 0, 2, 1, 12000); bitoneDualSend(synth, global.controlfd, 0, 2, 2, 16000); bitoneDualSend(synth, global.controlfd, 0, 2, 3, 1000); bitoneDualSend(synth, global.controlfd, 0, 2, 5, 0); bitoneDualSend(synth, global.controlfd, 0, 2, 8, 0); bitoneDualSend(synth, global.controlfd, 0, 3, 1, 12000); bitoneDualSend(synth, global.controlfd, 0, 3, 2, 16000); bitoneDualSend(synth, global.controlfd, 0, 3, 3, 1000); bitoneDualSend(synth, global.controlfd, 0, 3, 5, 0); bitoneDualSend(synth, global.controlfd, 0, 3, 8, 0); return(0); } /* * This will be called to make any routine specific parameters available. */ static int bitoneConfigure(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); brightonEvent event; if (synth == 0) { printf("problems going operational\n"); return(-1); } synth->bank = synth->location / 100; synth->location = synth->location % 100; if (synth->flags & OPERATIONAL) return(0); printf("going operational\n"); synth->flags |= OPERATIONAL; synth->keypanel = 1; synth->keypanel2 = -1; synth->transpose = 36; B1display[0] = 76; B1display[1] = synth->location; B1display[2] = -10; synth->mem.param[DISPLAY_DEV + 4] = synth->location / 10; synth->mem.param[DISPLAY_DEV + 5] = synth->location % 10; prePark[0].mem.param[DISPLAY_DEV + 4] = synth->location / 10; prePark[0].mem.param[DISPLAY_DEV + 5] = synth->location % 10; bitoneUpdateDisplay(synth, synth->sid, synth->midichannel, 0, 2, (B1display[0]) * CONTROLLER_RANGE / 99); bitoneUpdateDisplay(synth, synth->sid, synth->midichannel, 0, 4, (B1display[1]) * CONTROLLER_RANGE / 99); bitoneUpdateDisplay(synth, synth->sid, synth->midichannel, 0, 6, (B1display[2]) * CONTROLLER_RANGE / 99); event.type = BRIGHTON_FLOAT; /* * Ping the split button to reset the voice allocations */ event.value = 0.0; brightonParamChange(synth->win, 0, RADIOSET_3, &event); event.value = 1.0; brightonParamChange(synth->win, 0, RADIOSET_2 + 1, &event); bitoneUpdateDisplay(synth, synth->sid, synth->midichannel, 0, 2, (B1display[0]) * CONTROLLER_RANGE / 99); bitoneUpdateDisplay(synth, synth->sid, synth->midichannel, 0, 4, (B1display[1]) * CONTROLLER_RANGE / 99); bitoneUpdateDisplay(synth, synth->sid, synth->midichannel, 0, 6, (B1display[2]) * CONTROLLER_RANGE / 99); event.type = BRIGHTON_FLOAT; /* * Ping the split button to reset the voice allocations */ event.value = 0.0; brightonParamChange(synth->win, 0, RADIOSET_3, &event); event.value = 1.0; brightonParamChange(synth->win, 0, RADIOSET_2 + 1, &event); /* * Set the synth to a known state from which to start loadMemory(synth, SYNTH_NAME, 0, 0, synth->mem.active, 0, BRISTOL_FORCE|BRISTOL_NOCALLS); brightonParamChange(synth->win, 0, 224, &event); event.type = 0.0; brightonParamChange(synth->win, 0, 224, &event); */ loadMemory(synth, SYNTH_NAME, 0, synth->bank * 100 + synth->location, synth->mem.active, 0, BRISTOL_FORCE|BRISTOL_NOCALLS); bitoneMemoryShim(synth, ACTIVE_DEVS - 10); loadMemory(synth, SYNTH_NAME, 0, synth->bank * 100 + synth->location, synth->mem.active, 0, BRISTOL_FORCE|BRISTOL_NOCALLS); /* synth->mem.param[109] = 5; */ bitoneMemoryShim(synth, ACTIVE_DEVS - 10); bitoneDAUpdate(synth); /* * OK, this is a bit of a hack but it works. If the stereo pot has a * WITHDRAWN flag against it then we have a bit-1, otherwise we have been * given a bit-99 */ if (bit99App.resources[0].devlocn[STEREO_BUTTON].flags & BRIGHTON_WITHDRAWN) /* We have a bit-1 */ brightonPut(win, "bitmaps/blueprints/bitoneshade.xpm", 0, 0, win->width, win->height); else { if (strcmp("bit100", synth->resources->name) == 0) /* bit99m2/bit100 */ brightonPut(win, "bitmaps/blueprints/bitoneshade.xpm", 0, 0, win->width, win->height); else brightonPut(win, "bitmaps/blueprints/bit99shade.xpm", 0, 0, win->width, win->height); } /* * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only * occurs on first paint, so we suppress the first paint, and then request * an expose here. */ event.type = BRIGHTON_EXPOSE; event.intvalue = 1; brightonParamChange(synth->win, KEY_PANEL, -1, &event); configureGlobals(synth); event.type = BRIGHTON_FLOAT; event.value = 0.8; brightonParamChange(synth->win, 0, 206, &event); brightonParamChange(synth->win, 0, 207, &event); event.value = 1.0; brightonParamChange(synth->win, 0, 209, &event); brightonParamChange(synth->win, 0, 219, &event); event.value = 0.51; brightonParamChange(synth->win, 0, ENTRY_POT, &event); event.value = 0.5; brightonParamChange(synth->win, 0, 203, &event); dc = brightonGetDCTimer(win->dcTimeout); synth->loadMemory = (loadRoutine) bitoneMemoryKey; synth->saveMemory = (saveRoutine) bitoneSaveMemory; return(0); } bristol-0.60.11/brighton/brightonTrilogy.c0000644000175000017500000004636711746476475015471 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* * This file is just the visible presentation code for the trilogy. The stratus * was already architected to support the extra parameterisation for the trilogy * so this just now needed a different layout of a few of the parameters. * * Check String options. * * P12 String pan * P13 String harmonics * P14 String spacialisation * P15 String mod level * P16 String TBD */ #include "brighton.h" #include "brightonMini.h" extern int stratusInit(); extern int stratusConfigure(); extern int stratusCallback(brightonWindow *, int, int, float); extern int stratusModCallback(brightonWindow *, int, int, float); extern int stratusMidiCallback(brightonWindow *, int, int, float); #include "brightonKeys.h" #include "brightoninternals.h" #define DEVICE_COUNT 87 /* * This structure is for device definition. The structure is defined in * include/brighton.h, further definitions in brighton/brightonDevtable.h and * include/brightoninternals.h * * typedef int (*brightonCallback)(int, float); * typedef struct BrightonLocations { * int device; 0=rotary, 1=scale, etc. * float relx, rely; relative position with regards to 1000 by 1000 window * float relw, relh; relative height. * int from, to; * brightonCallback callback; specific to this dev * char *image; bitmap. If zero take a device default. * int flags; * } brightonLocations; * * This example is for a trilogyBristol type synth interface. */ #define S1 35 #define S2 110 #define S2b 15 #define S2c 80 #define S3 70 #define S4 600 #define BO 10 #define B2 6 #define R1 190 #define R2 560 #define R2a 545 #define R2b 685 #define D1 51 #define D2 43 #define D3 30 #define C1 26 #define C2 (C1 + D1) #define C3 (C2 + D1) #define C4 (C3 + D1) #define C5 (C4 + D1) #define C6 (C5 + D1) #define C7 (C6 + D1) #define C8 (C7 + D1) #define C9 (C8 + D1) #define C10 (C9 + D1) #define C11 (C10 + D1) #define C12 (C11 + D1) #define C13 (C12 + D1) #define C14 (C13 + D1) #define C15 (C14 + D1) #define C16 (C15 + D1) #define C17 (C16 + D1) #define C18 (C17 + D1) #define C19 (C18 + D1) #define C20 (C19 + D1) static brightonLocations trilogyLocations[DEVICE_COUNT] = { /* Organ */ {"Organ-2'", 1, C1-10, 110, 90, 40, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_VERTICAL|BRIGHTON_NOSHADOW}, {"Organ-4'", 1, C1-10, 180, 90, 40, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_VERTICAL|BRIGHTON_NOSHADOW}, {"Organ-8'", 1, C1-10, 250, 90, 40, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_VERTICAL|BRIGHTON_NOSHADOW}, {"Organ-15'", 1, C1-10, 320, 90, 40, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_VERTICAL|BRIGHTON_NOSHADOW}, /* Filter - 4 */ {"Filter-Env", 0, C3, R1, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_NOTCH}, {"Filter-Cutoff", 0, C4, R1, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"Filter-Res", 0, C5, R1, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"Filter-Pedal", 0, C6, R1, S1, S2, 0, 1.01, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_STEPPED}, /* - 8 */ {"Glide-Amout", 0, C7, R1, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"Glide-Speed", 0, C8, R1, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"Glide-Multi", 0, C9, R1, S1, S2, 0, 1.01, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_STEPPED}, {"Glide-Dir", 0, C10, R1, S1, S2, 0, 3, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_STEPPED}, /* - 12 */ {"Osc1-Tuning", 0, C11, R1, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_NOTCH}, {"Osc1-Sync", 2, C11 + (D2*1), R1, S2b+4, S2-10, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"Osc1-Octave", 2, C11 + (D2*2), R1, S2b+4, S2-10, 0, 12, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* - 15 */ {"Osc2-Trill", 2, C11 + (D2*4) - 5, R1, S2b+4, S2-10, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"Osc2-Octave", 2, C11 + (D2*3) - 3, R1, S2b+4, S2-10, 0, 12, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"Osc2-Tuning", 0, C15, R1, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_NOTCH}, /* - 18 */ {"LFO-Routing", 0, C16+5, R1, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_STEPPED|BRIGHTON_NOTCH}, {"LFO-Muli", 0, C17 + D1 / 2, R1, S1, S2, 0, 1.01, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_STEPPED}, {"LFO-Waveform", 0, C19-5, R1, S1, S2, 0, 3, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_STEPPED}, /* - 21 */ {"Mix-Synth", 0, C1-5, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"Mix-Organ", 0, C2-5, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"Mix-String", 0, C3-5, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, /* - 24 String section */ {"String-footage", 0, C4, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"String-Timbre", 0, C5, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"String-Attack", 0, C6, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"String-Decay", 0, C7, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, /* - 28 */ {"Osc-Waveform", 0, C8, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"Osc-WaveAlt", 0, C9, R2, S1, S2, 0, 1.01, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_STEPPED}, {"Osc-WaveLegato", 0, C10, R2, S1, S2, 0, 1.01, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_STEPPED}, /* - 31 */ {"LFO-Rate", 0, C16, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"LFO-Attack", 0, C17, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"LFO-Delay", 0, C18, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"LFO-Depth", 0, C19, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, /* Dummies 12 - 35 */ {"", 0, 0, 0, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, /* These are shadows for the opts parameters - 47 */ {"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, /* These are shadows for the envelope parameters from the mod panel - 66 */ {"Attack", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"Decay", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"Sustain", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"Release", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, /* Memory - 40 */ {"", 2, C11+(D3*1), R2a, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C11+(D3*2), R2a, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C11+(D3*3), R2a, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C11+(D3*4), R2a, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C11+(D3*1), R2b, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C11+(D3*2), R2b, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C11+(D3*3), R2b, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C11+(D3*4), R2b, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON}, /* Load and Save */ {"", 2, C11+(D3*5), R2a, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, C11+(D3*5), R2b, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoffo.xpm", "bitmaps/buttons/pressono.xpm", BRIGHTON_CHECKBUTTON}, /* Bank Sel */ {"", 2, C11+(D3*0), R2a, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, /* Mem search buttons Down then Up */ {"", 2, C11+(D3*6), R2b, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, C11+(D3*6), R2a, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, /* Search Free */ {"", 2, C11+(D3*0), R2b, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, /* Midi, perhaps eventually file import/export buttons */ {"", 2, C11+(D3*7), R2b, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, C11+(D3*7), R2a, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 3, C11 + 30, R2a - 90, 165, 70, 0, 1, 0, 0, "bitmaps/images/alphadisplay3.xpm", 0} }; static brightonLocations trilogyOpts[19] = { /* First one is index 47 */ {"", 0, C1, 100, 100, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm",// Master vol "bitmaps/knobs/alpharotary.xpm", BRIGHTON_NOTCH}, {"", 0, C1, 380, 100, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm", // organ pan "bitmaps/knobs/alpharotary.xpm", BRIGHTON_NOTCH}, {"", 0, C2 - 12, 380, 100, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm", // o wave "bitmaps/knobs/alpharotary.xpm", BRIGHTON_NOTCH}, {"", 0, C3, 380, 100, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm", // o space "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, C4 - 25, 470, 100, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm", // o mod "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, 285, 32, 100, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm", // SynHarm "bitmaps/knobs/alpharotary.xpm", 0}, /* 53 */ {"", 2, C1 - 15, 500, 20, 110, 0, 1, 0, // clicky "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_NOSHADOW}, {"", 0, C1 - 18, 650, 100, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm", // O tune "bitmaps/knobs/alpharotary.xpm", BRIGHTON_NOTCH}, {"", 0, C7, 380, 100, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm", // syn pan "bitmaps/knobs/alpharotary.xpm", BRIGHTON_NOTCH}, {"", 0, C7+10, 670, 100, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm", // syn tune "bitmaps/knobs/alpharotary.xpm", BRIGHTON_NOTCH}, {"", 0, 285, 606, 100, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm", // not used "bitmaps/knobs/alpharotary.xpm", 0}, /* 58 */ {"", 2, C8, 380, 20, 110, 0, 1, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_NOSHADOW}, // Env touch {"", 2, C9 + 10, 380, 20, 110, 0, 4, 0, "bitmaps/buttons/touchoff.xpm", "bitmaps/buttons/touch.xpm", BRIGHTON_NOSHADOW}, // filter type {"", 0, C10, 475, 100, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, /* 61 - string options */ {"", 0, C13+8, 190, 100, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, C13+8, 490, 100, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, C13+20, 790, 100, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, C14+18, 380, 100, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, C16-20, 450, S1, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, }; #define TRILOGY_MODCOUNT 7 static brightonLocations trilogyMods[TRILOGY_MODCOUNT] = { {"Attack", 1, 440, 180, 80, 700, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, {"Decay", 1, 580, 180, 80, 700, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, {"Sustain", 1, 720, 180, 80, 700, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, {"Release", 1, 860, 180, 80, 700, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, /* View Opts button */ {"", 2, 150, 800, 98, 170, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* Joystick */ {"", 5, 40, 160, 310, 500, 0, 1, 0, "bitmaps/images/sphere.xpm", 0, BRIGHTON_WIDE}, /* Joystick dummy */ {"", 0, 0, 0, 10, 10, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, }; /* * This is a set of globals for the main window rendering. Again taken from * include/brighton.h */ brightonApp trilogyApp = { "trilogy", 0, /* no blueprint on wood background. */ "bitmaps/textures/metal6.xpm", BRIGHTON_STRETCH, /*flags */ stratusInit, stratusConfigure, /* 3 callbacks, unused? */ stratusMidiCallback, destroySynth, {5, 100, 1, 2, 5, 520, 0, 0}, 900, 385, 0, 0, 7, /* Panel count */ { { "TRILOGY", "bitmaps/blueprints/trilogy.xpm", "bitmaps/textures/metal6.xpm", BRIGHTON_STRETCH|BRIGHTON_REVERSE, /* flags */ 0, 0, stratusCallback, 20, 100, 960, 550, DEVICE_COUNT, trilogyLocations }, { "Keyboard", 0, "bitmaps/newkeys/kbg.xpm", /* flags */ 0x020|BRIGHTON_STRETCH, 0, 0, keyCallback, 200, 690, 785, 290, KEY_COUNT, keys }, { "Mods", "bitmaps/blueprints/trilogymods.xpm", "bitmaps/blueprints/trilogymods.xpm", BRIGHTON_STRETCH, 0, 0, stratusModCallback, 30, 710, 160, 250, TRILOGY_MODCOUNT, trilogyMods }, { "Options", "bitmaps/blueprints/trilogyopts.xpm", "bitmaps/images/pcb.xpm", BRIGHTON_WITHDRAWN, 0, 0, stratusModCallback, 25, 105, 950, 540, 19, trilogyOpts }, { "Logo", "bitmaps/blueprints/trilogylogo.xpm", 0, BRIGHTON_STRETCH, /*flags */ 0, 0, 0, 20, 0, 960, 100, 0, 0 }, { "Edge", 0, "bitmaps/textures/wood.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 0, 0, 20, 1000, 0, 0 }, { "Edge", 0, "bitmaps/textures/wood.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /*flags */ 0, 0, 0, 980, 0, 20, 1000, 0, 0 }, } }; bristol-0.60.11/brighton/brightonKeyboards.h0000644000175000017500000027512611746476475015765 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* * These need to be redone. Each white key should be placed first, then the * black keys layered on top. That way we can get better graphics with shading * on the white keys for each black key. */ #ifndef BRIGHTONKEYBOARD_H #define BRIGHTONKEYBOARD_H extern guimain global; #define KEY_COUNT 61 #define KEY_COUNT_2OCTAVE 29 #define KEY_COUNT_2OCTAVE2 32 #define KEY_COUNT_3OCTAVE 44 #define KEY_COUNT_3_OCTAVE 37 #define KEY_COUNT_4OCTAVE 49 #define KEY_COUNT_PEDAL 24 #define VKEY_COUNT 48 #define KEY_COUNT_5OCTAVE KEY_COUNT #define KEY_COUNT_6_OCTAVE 73 /* * This whole definition should be moved into a separate routine, and called * for a given keyboard size - 37 note (three oct), 61 note (5 oct) or a full * 88 keys. Should also consider 73 note for a Rhodes.... */ #define KW (1000 / 36) #define FKW (995 - 35 * KW) #define KFBW ((KW * 3) / 2) #define KFWD ((KW * 3) / 4) #define KMW 20 #define KIW 28 #define KIH 666 #define KIL 334 #define KIS 0 brightonLocations keys[KEY_COUNT_5OCTAVE] = { {"", 2, 0 * KW, 0, KFWD, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteFUp.xpm", "bitmaps/newkeys/WhiteFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 0 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp4.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 1 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 1 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp4.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 2 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 3 * KW, 0, KFWD, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteFUp.xpm", "bitmaps/newkeys/WhiteFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 3 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp3.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 4 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 4 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp3.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 5 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 5 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp3.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 6 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 7 * KW, 0, KFWD, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteFUp.xpm", "bitmaps/newkeys/WhiteFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 7 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp3.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 8 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 8 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp2.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 9 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 10 * KW, 0, KFWD, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteFUp.xpm", "bitmaps/newkeys/WhiteFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 10 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp2.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 11 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 11 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp2.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 12 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 12 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp2.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 13 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 14 * KW, 0, KFWD, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteFUp.xpm", "bitmaps/newkeys/WhiteFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 14 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 15 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 15 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 16 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 17 * KW, 0, KFWD, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteFUp.xpm", "bitmaps/newkeys/WhiteFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 17 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 18 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 18 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 19 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 19 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 20 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 21 * KW, 0, KFWD, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteFUp.xpm", "bitmaps/newkeys/WhiteFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 21 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp2.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 22 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 22 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp2.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 23 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 24 * KW, 0, KFWD, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteFUp.xpm", "bitmaps/newkeys/WhiteFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 24 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp2.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 25 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 25 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp2.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 26 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 26 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp2.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 27 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 28 * KW, 0, KFWD, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteFUp.xpm", "bitmaps/newkeys/WhiteFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 28 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp2.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 29 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 29 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp3.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 30 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 31 * KW, 0, KFWD, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteFUp.xpm", "bitmaps/newkeys/WhiteFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 31 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp3.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 32 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 32 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp3.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 33 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 33 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp4.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 34 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 35 * KW, 0, KW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteLUp.xpm", "bitmaps/newkeys/WhiteLDown.xpm", BRIGHTON_NOSHADOW}, }; brightonLocations keysprofile2[KEY_COUNT_5OCTAVE] = { {"", 2, 0 * KW, 0, KW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteNHFUp.xpm", "bitmaps/newkeys/WhiteNHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 0 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 1 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 1 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 2 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 3 * KW, 0, KW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteNHFUp.xpm", "bitmaps/newkeys/WhiteNHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 3 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 4 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 4 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 5 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 5 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 6 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 7 * KW, 0, KW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteNHFUp.xpm", "bitmaps/newkeys/WhiteNHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 7 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 8 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 8 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 9 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 10 * KW, 0, KW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteNHFUp.xpm", "bitmaps/newkeys/WhiteNHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 10 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 11 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 11 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 12 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 12 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 13 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 14 * KW, 0, KW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteNHFUp.xpm", "bitmaps/newkeys/WhiteNHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 14 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 15 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 15 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 16 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 17 * KW, 0, KW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteNHFUp.xpm", "bitmaps/newkeys/WhiteNHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 17 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 18 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 18 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 19 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 19 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 20 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 21 * KW, 0, KW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteNHFUp.xpm", "bitmaps/newkeys/WhiteNHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 21 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 22 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 22 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 23 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 24 * KW, 0, KW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteNHFUp.xpm", "bitmaps/newkeys/WhiteNHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 24 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 25 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 25 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 26 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 26 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 27 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 28 * KW, 0, KW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteNHFUp.xpm", "bitmaps/newkeys/WhiteNHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 28 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 29 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 29 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 30 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 31 * KW, 0, KW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteNHFUp.xpm", "bitmaps/newkeys/WhiteNHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 31 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 32 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 32 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 33 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 33 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 34 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 35 * KW, 0, KW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteNHLUp.xpm", "bitmaps/newkeys/WhiteNHLDown.xpm", BRIGHTON_NOSHADOW}, }; /* Profiles2 */ brightonLocations keysprofile[KEY_COUNT_5OCTAVE] = { {"", 2, 0 * KW, 0, KW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteHFUp.xpm", "bitmaps/newkeys/WhiteHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 0 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp4.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 1 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 1 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp3.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 2 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 3 * KW, 0, KW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteHFUp.xpm", "bitmaps/newkeys/WhiteHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 3 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp3.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 4 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 4 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp3.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 5 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 5 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp3.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 6 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 7 * KW, 0, KW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteHFUp.xpm", "bitmaps/newkeys/WhiteHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 7 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp2.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 8 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 8 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp2.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 9 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 10 * KW, 0, KW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteHFUp.xpm", "bitmaps/newkeys/WhiteHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 10 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp2.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 11 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 11 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp2.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 12 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 12 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp2.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 13 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 14 * KW, 0, KW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteHFUp.xpm", "bitmaps/newkeys/WhiteHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 14 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 15 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 15 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 16 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 17 * KW, 0, KW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteHFUp.xpm", "bitmaps/newkeys/WhiteHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 17 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 18 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 18 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 19 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 19 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 20 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 21 * KW, 0, KW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteHFUp.xpm", "bitmaps/newkeys/WhiteHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 21 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp2.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 22 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 22 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp2.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 23 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 24 * KW, 0, KW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteHFUp.xpm", "bitmaps/newkeys/WhiteHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 24 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp2.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 25 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 25 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp2.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 26 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 26 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp2.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 27 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 28 * KW, 0, KW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteHFUp.xpm", "bitmaps/newkeys/WhiteHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 28 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp3.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 29 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 29 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp3.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 30 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 31 * KW, 0, KW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteHFUp.xpm", "bitmaps/newkeys/WhiteHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 31 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp3.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 32 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 32 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp3.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 33 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 33 * KW + KW/2, 0, KW, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp4.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 34 * KW, KIH, KW, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 35 * KW, 0, KW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteHLUp.xpm", "bitmaps/newkeys/WhiteHLDown.xpm", BRIGHTON_NOSHADOW}, }; #define K6W 1000 / 43 #define F6KW 1000 - 43 * KW #define K6FW (K6W * 3 / 4) #define K6MW 13 #define K6IW 22 #define K6IH 666 #define K6IL 334 #define K6IS 20 brightonLocations keys6octave[KEY_COUNT_6_OCTAVE] = { {"", 2, 0 * K6W, 0, K6FW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteDFUp.xpm", "bitmaps/newkeys/WhiteDFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 0 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 1 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 1 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 2 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 3 * K6W, 0, K6FW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteDFUp.xpm", "bitmaps/newkeys/WhiteDFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 3 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 4 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 4 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 5 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 5 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 6 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 7 * K6W, 0, K6FW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteDFUp.xpm", "bitmaps/newkeys/WhiteDFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 7 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 8 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 8 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 9 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 10 * K6W, 0, K6FW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteDFUp.xpm", "bitmaps/newkeys/WhiteDFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 10 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 11 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 11 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 12 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 12 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 13 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 14 * K6W, 0, K6FW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteDFUp.xpm", "bitmaps/newkeys/WhiteDFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 14 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 15 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 15 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 16 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 17 * K6W, 0, K6FW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteDFUp.xpm", "bitmaps/newkeys/WhiteDFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 17 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 18 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 18 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 19 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 19 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 20 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 21 * K6W, 0, K6FW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteDFUp.xpm", "bitmaps/newkeys/WhiteDFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 21 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 22 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 22 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 23 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 24 * K6W, 0, K6FW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteDFUp.xpm", "bitmaps/newkeys/WhiteDFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 24 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 25 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 25 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 26 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 26 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 27 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 28 * K6W, 0, K6FW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteDFUp.xpm", "bitmaps/newkeys/WhiteDFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 28 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 29 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 29 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 30 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 31 * K6W, 0, K6FW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteDFUp.xpm", "bitmaps/newkeys/WhiteDFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 31 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 32 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 32 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 33 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 33 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 34 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 35 * K6W, 0, K6FW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteDFUp.xpm", "bitmaps/newkeys/WhiteDFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 35 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 36 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 36 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 37 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 38 * K6W, 0, K6FW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteDFUp.xpm", "bitmaps/newkeys/WhiteDFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 38 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 39 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 39 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 40 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 40 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 41 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 42 * K6W, 0, K6W, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteLUp.xpm", "bitmaps/newkeys/WhiteLDown.xpm", BRIGHTON_NOSHADOW}, }; /* * These were done for the newer hammond keys but will be used elsewhere */ brightonLocations keys6hammond[KEY_COUNT_6_OCTAVE] = { {"", 2, 0 * K6W, 0, K6W, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteFRUp.xpm", "bitmaps/newkeys/WhiteFRDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 0 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackRUp.xpm", "bitmaps/newkeys/BlackRDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 1 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteRUp.xpm", "bitmaps/newkeys/WhiteRDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 1 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackRUp.xpm", "bitmaps/newkeys/BlackRDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 2 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteRUp.xpm", "bitmaps/newkeys/WhiteRDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 3 * K6W, 0, K6W, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteFRUp.xpm", "bitmaps/newkeys/WhiteFRDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 3 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackRUp.xpm", "bitmaps/newkeys/BlackRDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 4 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteRUp.xpm", "bitmaps/newkeys/WhiteRDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 4 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackRUp.xpm", "bitmaps/newkeys/BlackRDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 5 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteRUp.xpm", "bitmaps/newkeys/WhiteRDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 5 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackRUp.xpm", "bitmaps/newkeys/BlackRDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 6 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteRUp.xpm", "bitmaps/newkeys/WhiteRDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 7 * K6W, 0, K6W, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteHFUp.xpm", "bitmaps/newkeys/WhiteHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 7 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 8 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 8 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 9 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 10 * K6W, 0, K6W, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteHFUp.xpm", "bitmaps/newkeys/WhiteHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 10 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 11 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 11 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 12 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 12 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 13 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 14 * K6W, 0, K6W, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteHFUp.xpm", "bitmaps/newkeys/WhiteHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 14 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 15 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 15 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 16 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 17 * K6W, 0, K6W, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteHFUp.xpm", "bitmaps/newkeys/WhiteHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 17 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 18 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 18 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 19 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 19 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 20 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 21 * K6W, 0, K6W, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteHFUp.xpm", "bitmaps/newkeys/WhiteHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 21 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 22 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 22 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp2.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 23 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 24 * K6W, 0, K6W, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteHFUp.xpm", "bitmaps/newkeys/WhiteHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 24 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp2.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 25 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 25 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp2.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 26 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 26 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp2.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 27 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 28 * K6W, 0, K6W, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteHFUp.xpm", "bitmaps/newkeys/WhiteHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 28 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp2.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 29 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 29 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp3.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 30 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 31 * K6W, 0, K6W, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteHFUp.xpm", "bitmaps/newkeys/WhiteHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 31 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp3.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 32 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 32 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp3.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 33 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 33 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp3.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 34 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 35 * K6W, 0, K6W, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteHFUp.xpm", "bitmaps/newkeys/WhiteHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 35 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp3.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 36 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 36 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp4.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 37 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 38 * K6W, 0, K6W, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteHFUp.xpm", "bitmaps/newkeys/WhiteHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 38 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp4.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 39 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 39 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp4.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 40 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 40 * K6W + K6W/2, 0, K6W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp4.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 41 * K6W, KIH, K6W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 42 * K6W, 0, K6W, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteHLUp.xpm", "bitmaps/newkeys/WhiteHLDown.xpm", BRIGHTON_NOSHADOW}, }; #define K2W (1000 / 17) #define K2FW (K2W * 3 / 4) #define K2MW 18 #define K2IW 40 #define K2IH 600 #define K2IL 410 #define K2IS 33 brightonLocations keys2octave[KEY_COUNT_2OCTAVE] = { {"", 2, 0 * K2W, 0, K2FW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteFUp.xpm", "bitmaps/newkeys/WhiteFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 0 * K2W + K2W/2, 0, K2W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 1 * K2W, KIH, K2W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 1 * K2W + K2W/2, 0, K2W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 2 * K2W, KIH, K2W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 3 * K2W, 0, K2FW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteFUp.xpm", "bitmaps/newkeys/WhiteFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 3 * K2W + K2W/2, 0, K2W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 4 * K2W, KIH, K2W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 4 * K2W + K2W/2, 0, K2W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 5 * K2W, KIH, K2W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 5 * K2W + K2W/2, 0, K2W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 6 * K2W, KIH, K2W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 7 * K2W, 0, K2FW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteFUp.xpm", "bitmaps/newkeys/WhiteFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 7 * K2W + K2W/2, 0, K2W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 8 * K2W, KIH, K2W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 8 * K2W + K2W/2, 0, K2W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 9 * K2W, KIH, K2W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 10 * K2W, 0, K2FW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteFUp.xpm", "bitmaps/newkeys/WhiteFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 10 * K2W + K2W/2, 0, K2W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 11 * K2W, KIH, K2W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 11 * K2W + K2W/2, 0, K2W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 12 * K2W, KIH, K2W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 12 * K2W + K2W/2, 0, K2W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 13 * K2W, KIH, K2W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 14 * K2W, 0, K2FW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteFUp.xpm", "bitmaps/newkeys/WhiteFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 14 * K2W + K2W/2, 0, K2W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 15 * K2W, KIH, K2W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 15 * K2W + K2W/2, 0, K2W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 16 * K2W, KIH, K2W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, /* {"", 2, 17 * K2W, 0, K2FW, 1000, 0, 1, 0, */ /* "bitmaps/newkeys/WhiteFUp.xpm", "bitmaps/newkeys/WhiteFDown.xpm", BRIGHTON_NOSHADOW}, */ }; #define K22W (1000 / 19) #define K22FW (K22W * 3 / 4) #define K22MW 18 #define K22IW 40 #define K22IH 600 #define K22IL 410 #define K22IS 33 brightonLocations keys2octave2[KEY_COUNT_2OCTAVE2] = { {"", 2, 0 * K22W, 0, K22FW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteFUp.xpm", "bitmaps/newkeys/WhiteFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 0 * K22W + K22W/2, 0, K22W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 1 * K22W, KIH, K22W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 1 * K22W + K22W/2, 0, K22W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 2 * K22W, KIH, K22W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 2 * K22W + K22W/2, 0, K22W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 3 * K22W, KIH, K22W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 4 * K22W, 0, K22FW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteFUp.xpm", "bitmaps/newkeys/WhiteFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 4 * K22W + K22W/2, 0, K22W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 5 * K22W, KIH, K22W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 5 * K22W + K22W/2, 0, K22W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 6 * K22W, KIH, K22W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 7 * K22W, 0, K22FW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteFUp.xpm", "bitmaps/newkeys/WhiteFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 7 * K22W + K22W/2, 0, K22W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 8 * K22W, KIH, K22W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 8 * K22W + K22W/2, 0, K22W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 9 * K22W, KIH, K22W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 9 * K22W + K22W/2, 0, K22W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 10 * K22W, KIH, K22W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 11 * K22W, 0, K22FW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteFUp.xpm", "bitmaps/newkeys/WhiteFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 11 * K22W + K22W/2, 0, K22W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 12 * K22W, KIH, K22W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 12 * K22W + K22W/2, 0, K22W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 13 * K22W, KIH, K22W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 14 * K22W, 0, K22FW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteFUp.xpm", "bitmaps/newkeys/WhiteFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 14 * K22W + K22W/2, 0, K22W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 15 * K22W, KIH, K22W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 15 * K22W + K22W/2, 0, K22W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 16 * K22W, KIH, K22W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 16 * K22W + K22W/2, 0, K22W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 17 * K22W, KIH, K22W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 18 * K22W, 0, K22W, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteLUp.xpm", "bitmaps/newkeys/WhiteLDown.xpm", BRIGHTON_NOSHADOW}, }; #define K3W (1000 / 26) //#define K3FW (K3W * 3 / 4) #define K3FW K3W #define K3MW 18 #define K3IW 40 #define K3IH 650 #define K3IL 350 #define K3IS 33 brightonLocations keys3octave[KEY_COUNT_3OCTAVE] = { {"", 2, 0 * K3W, 0, K3FW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteFUp.xpm", "bitmaps/newkeys/WhiteFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 0 * K3W + K3W/2, 0, K3W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 1 * K3W, KIH, K3W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 1 * K3W + K3W/2, 0, K3W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 2 * K3W, KIH, K3W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 3 * K3W, 0, K3FW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteFUp.xpm", "bitmaps/newkeys/WhiteFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 3 * K3W + K3W/2, 0, K3W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 4 * K3W, KIH, K3W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 4 * K3W + K3W/2, 0, K3W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 5 * K3W, KIH, K3W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 5 * K3W + K3W/2, 0, K3W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 6 * K3W, KIH, K3W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 7 * K3W, 0, K3FW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteFUp.xpm", "bitmaps/newkeys/WhiteFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 7 * K3W + K3W/2, 0, K3W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 8 * K3W, KIH, K3W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 8 * K3W + K3W/2, 0, K3W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 9 * K3W, KIH, K3W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 10 * K3W, 0, K3FW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteFUp.xpm", "bitmaps/newkeys/WhiteFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 10 * K3W + K3W/2, 0, K3W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 11 * K3W, KIH, K3W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 11 * K3W + K3W/2, 0, K3W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 12 * K3W, KIH, K3W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 12 * K3W + K3W/2, 0, K3W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 13 * K3W, KIH, K3W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 14 * K3W, 0, K3FW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteFUp.xpm", "bitmaps/newkeys/WhiteFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 14 * K3W + K3W/2, 0, K3W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 15 * K3W, KIH, K3W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 15 * K3W + K3W/2, 0, K3W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 16 * K3W, KIH, K3W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 17 * K3W, 0, K3FW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteFUp.xpm", "bitmaps/newkeys/WhiteFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 17 * K3W + K3W/2, 0, K3W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 18 * K3W, KIH, K3W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 18 * K3W + K3W/2, 0, K3W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 19 * K3W, KIH, K3W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 19 * K3W + K3W/2, 0, K3W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 20 * K3W, KIH, K3W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 21 * K3W, 0, K3FW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteFUp.xpm", "bitmaps/newkeys/WhiteFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 21 * K3W + K3W/2, 0, K3W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 22 * K3W, KIH, K3W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 22 * K3W + K3W/2, 0, K3W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 23 * K3W, KIH, K3W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 24 * K3W, 0, K3FW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteFUp.xpm", "bitmaps/newkeys/WhiteFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 24 * K3W + K3W/2, 0, K3W, KIH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 25 * K3W, KIH, K3W, KIL, 0, 1, 0, "bitmaps/newkeys/WhiteUp.xpm", "bitmaps/newkeys/WhiteDown.xpm", BRIGHTON_NOSHADOW}, }; brightonLocations keys3octave2[KEY_COUNT_3OCTAVE] = { {"", 2, 0 * K3W, 0, K3FW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteNHFUp.xpm", "bitmaps/newkeys/WhiteNHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 0 * K3W + K3W/2, 0, K3W, K3IH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 1 * K3W, K3IH, K3W, K3IL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 1 * K3W + K3W/2, 0, K3W, K3IH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 2 * K3W, K3IH, K3W, K3IL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 3 * K3W, 0, K3FW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteNHFUp.xpm", "bitmaps/newkeys/WhiteNHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 3 * K3W + K3W/2, 0, K3W, K3IH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 4 * K3W, K3IH, K3W, K3IL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 4 * K3W + K3W/2, 0, K3W, K3IH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 5 * K3W, K3IH, K3W, K3IL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 5 * K3W + K3W/2, 0, K3W, K3IH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 6 * K3W, K3IH, K3W, K3IL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 7 * K3W, 0, K3FW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteNHFUp.xpm", "bitmaps/newkeys/WhiteNHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 7 * K3W + K3W/2, 0, K3W, K3IH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 8 * K3W, K3IH, K3W, K3IL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 8 * K3W + K3W/2, 0, K3W, K3IH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 9 * K3W, K3IH, K3W, K3IL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 10 * K3W, 0, K3FW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteNHFUp.xpm", "bitmaps/newkeys/WhiteNHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 10 * K3W + K3W/2, 0, K3W, K3IH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 11 * K3W, K3IH, K3W, K3IL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 11 * K3W + K3W/2, 0, K3W, K3IH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 12 * K3W, K3IH, K3W, K3IL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 12 * K3W + K3W/2, 0, K3W, K3IH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 13 * K3W, K3IH, K3W, K3IL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 14 * K3W, 0, K3FW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteNHFUp.xpm", "bitmaps/newkeys/WhiteNHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 14 * K3W + K3W/2, 0, K3W, K3IH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 15 * K3W, K3IH, K3W, K3IL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 15 * K3W + K3W/2, 0, K3W, K3IH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 16 * K3W, K3IH, K3W, K3IL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 17 * K3W, 0, K3FW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteNHFUp.xpm", "bitmaps/newkeys/WhiteNHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 17 * K3W + K3W/2, 0, K3W, K3IH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 18 * K3W, K3IH, K3W, K3IL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 18 * K3W + K3W/2, 0, K3W, K3IH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 19 * K3W, K3IH, K3W, K3IL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 19 * K3W + K3W/2, 0, K3W, K3IH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 20 * K3W, K3IH, K3W, K3IL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 21 * K3W, 0, K3FW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteNHFUp.xpm", "bitmaps/newkeys/WhiteNHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 21 * K3W + K3W/2, 0, K3W, K3IH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 22 * K3W, K3IH, K3W, K3IL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 22 * K3W + K3W/2, 0, K3W, K3IH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 23 * K3W, K3IH, K3W, K3IL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 24 * K3W, 0, K3FW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteNHFUp.xpm", "bitmaps/newkeys/WhiteNHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 24 * K3W + K3W/2, 0, K3W, K3IH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 25 * K3W, K3IH, K3W, K3IL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, }; #define K3PW (1000 / 22) //#define K3PFW (K3PW * 3 / 4) #define K3PFW K3PW #define K3PMW 18 #define K3PIW 40 #define K3PIH 630 #define K3PIL 370 #define K3PIS 33 brightonLocations keys3_octave[KEY_COUNT_3_OCTAVE] = { {"", 2, 0 * K3PW, 0, K3PFW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteNHFUp.xpm", "bitmaps/newkeys/WhiteNHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 0 * K3PW + K3PW/2, 0, K3PW, K3PIH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 1 * K3PW, K3PIH, K3PW, K3PIL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 1 * K3PW + K3PW/2, 0, K3PW, K3PIH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 2 * K3PW, K3PIH, K3PW, K3PIL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 3 * K3PW, 0, K3PFW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteNHFUp.xpm", "bitmaps/newkeys/WhiteNHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 3 * K3PW + K3PW/2, 0, K3PW, K3PIH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 4 * K3PW, K3PIH, K3PW, K3PIL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 4 * K3PW + K3PW/2, 0, K3PW, K3PIH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 5 * K3PW, K3PIH, K3PW, K3PIL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 5 * K3PW + K3PW/2, 0, K3PW, K3PIH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 6 * K3PW, K3PIH, K3PW, K3PIL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 7 * K3PW, 0, K3PFW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteNHFUp.xpm", "bitmaps/newkeys/WhiteNHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 7 * K3PW + K3PW/2, 0, K3PW, K3PIH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 8 * K3PW, K3PIH, K3PW, K3PIL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 8 * K3PW + K3PW/2, 0, K3PW, K3PIH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 9 * K3PW, K3PIH, K3PW, K3PIL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 10 * K3PW, 0, K3PFW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteNHFUp.xpm", "bitmaps/newkeys/WhiteNHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 10 * K3PW + K3PW/2, 0, K3PW, K3PIH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 11 * K3PW, K3PIH, K3PW, K3PIL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 11 * K3PW + K3PW/2, 0, K3PW, K3PIH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 12 * K3PW, K3PIH, K3PW, K3PIL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 12 * K3PW + K3PW/2, 0, K3PW, K3PIH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 13 * K3PW, K3PIH, K3PW, K3PIL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 14 * K3PW, 0, K3PFW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteNHFUp.xpm", "bitmaps/newkeys/WhiteNHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 14 * K3PW + K3PW/2, 0, K3PW, K3PIH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 15 * K3PW, K3PIH, K3PW, K3PIL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 15 * K3PW + K3PW/2, 0, K3PW, K3PIH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 16 * K3PW, K3PIH, K3PW, K3PIL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 17 * K3PW, 0, K3PFW, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteNHFUp.xpm", "bitmaps/newkeys/WhiteNHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 17 * K3PW + K3PW/2, 0, K3PW, K3PIH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 18 * K3PW, K3PIH, K3PW, K3PIL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 18 * K3PW + K3PW/2, 0, K3PW, K3PIH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 19 * K3PW, K3PIH, K3PW, K3PIL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 19 * K3PW + K3PW/2, 0, K3PW, K3PIH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 20 * K3PW, K3PIH, K3PW, K3PIL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 21 * K3PW, 0, K3PFW - 2, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteNHFUp.xpm", "bitmaps/newkeys/WhiteNHFDown.xpm", BRIGHTON_NOSHADOW}, }; #define KVW 1000 / 28 #define KVMW 18 #define KVIW 40 #define KVIH 600 #define KVIL 410 #define KVIS 33 brightonLocations vkeys[VKEY_COUNT] = { {"", 2, 0 * KVW, KVIH, KVW, KVIL, 0, 1, 0, "bitmaps/keys/wrevup.xpm", "bitmaps/keys/wrevdown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 0 * KVW, 0, KVIW + 7, KVIH, 0, 1, 0, "bitmaps/keys/brevup.xpm", "bitmaps/keys/brevdown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 1 * KVW, KVIH, KVW, KVIL, 0, 1, 0, "bitmaps/keys/wrevup.xpm", "bitmaps/keys/wrevdown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 1 * KVW + KVIS, 0, KVMW, KVIH, 0, 1, 0, "bitmaps/keys/brevmup.xpm", "bitmaps/keys/brevmdown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 2 * KVW, KVIH, KVW, KVIL, 0, 1, 0, "bitmaps/keys/wrevup.xpm", "bitmaps/keys/wrevdown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 3 * KVW, KVIH, KVW, KVIL, 0, 1, 0, "bitmaps/keys/wrevup.xpm", "bitmaps/keys/wrevdown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 3 * KVW, 0, KVIW + 10, KVIH, 0, 1, 0, "bitmaps/keys/brevup.xpm", "bitmaps/keys/brevdown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 4 * KVW, KVIH, KVW, KVIL, 0, 1, 0, "bitmaps/keys/wrevup.xpm", "bitmaps/keys/wrevdown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 4 * KVW + KVIS, 0, KVMW, KVIH, 0, 1, 0, "bitmaps/keys/brevmup.xpm", "bitmaps/keys/brevmdown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 5 * KVW, KVIH, KVW, KVIL, 0, 1, 0, "bitmaps/keys/wrevup.xpm", "bitmaps/keys/wrevdown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 5 * KVW + KVIS, 0, KVMW, KVIH, 0, 1, 0, "bitmaps/keys/brevmup.xpm", "bitmaps/keys/brevmdown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 6 * KVW, KVIH, KVW, KVIL, 0, 1, 0, "bitmaps/keys/wrevup.xpm", "bitmaps/keys/wrevdown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 7 * KVW, KVIH, KVW, KVIL, 0, 1, 0, "bitmaps/keys/wrevup.xpm", "bitmaps/keys/wrevdown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 7 * KVW, 0, KVIW + 7, KVIH, 0, 1, 0, "bitmaps/keys/brevup.xpm", "bitmaps/keys/brevdown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 8 * KVW, KVIH, KVW, KVIL, 0, 1, 0, "bitmaps/keys/wrevup.xpm", "bitmaps/keys/wrevdown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 8 * KVW + KVIS, 0, KVMW, KVIH, 0, 1, 0, "bitmaps/keys/brevmup.xpm", "bitmaps/keys/brevmdown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 9 * KVW, KVIH, KVW, KVIL, 0, 1, 0, "bitmaps/keys/wrevup.xpm", "bitmaps/keys/wrevdown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 10 * KVW, KVIH, KVW, KVIL, 0, 1, 0, "bitmaps/keys/wrevup.xpm", "bitmaps/keys/wrevdown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 10 * KVW, 0, KVIW + 10, KVIH, 0, 1, 0, "bitmaps/keys/brevup.xpm", "bitmaps/keys/brevdown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 11 * KVW, KVIH, KVW, KVIL, 0, 1, 0, "bitmaps/keys/wrevup.xpm", "bitmaps/keys/wrevdown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 11 * KVW + KVIS, 0, KVMW, KVIH, 0, 1, 0, "bitmaps/keys/brevmup.xpm", "bitmaps/keys/brevmdown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 12 * KVW, KVIH, KVW, KVIL, 0, 1, 0, "bitmaps/keys/wrevup.xpm", "bitmaps/keys/wrevdown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 12 * KVW + KVIS, 0, KVMW, KVIH, 0, 1, 0, "bitmaps/keys/brevmup.xpm", "bitmaps/keys/brevmdown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 13 * KVW, KVIH, KVW, KVIL, 0, 1, 0, "bitmaps/keys/wrevup.xpm", "bitmaps/keys/wrevdown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 14 * KVW, KVIH, KVW, KVIL, 0, 1, 0, "bitmaps/keys/wrevup.xpm", "bitmaps/keys/wrevdown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 14 * KVW, 0, KVIW + 7, KVIH, 0, 1, 0, "bitmaps/keys/brevup.xpm", "bitmaps/keys/brevdown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 15 * KVW, KVIH, KVW, KVIL, 0, 1, 0, "bitmaps/keys/wrevup.xpm", "bitmaps/keys/wrevdown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 15 * KVW + KVIS, 0, KVMW, KVIH, 0, 1, 0, "bitmaps/keys/brevmup.xpm", "bitmaps/keys/brevmdown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 16 * KVW, KVIH, KVW, KVIL, 0, 1, 0, "bitmaps/keys/wrevup.xpm", "bitmaps/keys/wrevdown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 17 * KVW, KVIH, KVW, KVIL, 0, 1, 0, "bitmaps/keys/wrevup.xpm", "bitmaps/keys/wrevdown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 17 * KVW, 0, KVIW + 10, KVIH, 0, 1, 0, "bitmaps/keys/brevup.xpm", "bitmaps/keys/brevdown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 18 * KVW, KVIH, KVW, KVIL, 0, 1, 0, "bitmaps/keys/wrevup.xpm", "bitmaps/keys/wrevdown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 18 * KVW + KVIS, 0, KVMW, KVIH, 0, 1, 0, "bitmaps/keys/brevmup.xpm", "bitmaps/keys/brevmdown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 19 * KVW, KVIH, KVW, KVIL, 0, 1, 0, "bitmaps/keys/wrevup.xpm", "bitmaps/keys/wrevdown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 19 * KVW + KVIS, 0, KVMW, KVIH, 0, 1, 0, "bitmaps/keys/brevmup.xpm", "bitmaps/keys/brevmdown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 20 * KVW, KVIH, KVW, KVIL, 0, 1, 0, "bitmaps/keys/wrevup.xpm", "bitmaps/keys/wrevdown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 21 * KVW, KVIH, KVW, KVIL, 0, 1, 0, "bitmaps/keys/wrevup.xpm", "bitmaps/keys/wrevdown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 21 * KVW, 0, KVIW + 7, KVIH, 0, 1, 0, "bitmaps/keys/brevup.xpm", "bitmaps/keys/brevdown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 22 * KVW, KVIH, KVW, KVIL, 0, 1, 0, "bitmaps/keys/wrevup.xpm", "bitmaps/keys/wrevdown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 22 * KVW + KVIS, 0, KVMW, KVIH, 0, 1, 0, "bitmaps/keys/brevmup.xpm", "bitmaps/keys/brevmdown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 23 * KVW, KVIH, KVW, KVIL, 0, 1, 0, "bitmaps/keys/wrevup.xpm", "bitmaps/keys/wrevdown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 24 * KVW, KVIH, KVW, KVIL, 0, 1, 0, "bitmaps/keys/wrevup.xpm", "bitmaps/keys/wrevdown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 24 * KVW, 0, KVIW + 10, KVIH, 0, 1, 0, "bitmaps/keys/brevup.xpm", "bitmaps/keys/brevdown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 25 * KVW, KVIH, KVW, KVIL, 0, 1, 0, "bitmaps/keys/wrevup.xpm", "bitmaps/keys/wrevdown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 25 * KVW + KVIS, 0, KVMW, KVIH, 0, 1, 0, "bitmaps/keys/brevmup.xpm", "bitmaps/keys/brevmdown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 26 * KVW, KVIH, KVW, KVIL, 0, 1, 0, "bitmaps/keys/wrevup.xpm", "bitmaps/keys/wrevdown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 26 * KVW + KVIS, 0, KVMW, KVIH, 0, 1, 0, "bitmaps/keys/brevmup.xpm", "bitmaps/keys/brevmdown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 27 * KVW, KVIH, KVW, KVIL, 0, 1, 0, "bitmaps/keys/wrevup.xpm", "bitmaps/keys/wrevdown.xpm", BRIGHTON_NOSHADOW}, }; #define K4W 1000 / 29 #define K4WB (K4W) #define K4WC (K4W) #define K4MW 18 #define K4IW 40 #define K4IH 600 #define K4IL 410 #define K4IS 33 #define K4C0 0 #define K4C1 (K4C0 + K4WB) #define K4C2 (K4C1 + K4WB) #define K4C3 (K4C2 + K4WB) #define K4C4 (K4C3 + K4WB) #define K4C5 (K4C4 + K4WB) #define K4C6 (K4C5 + K4WB) #define K4C7 (K4C6 + K4WB) #define K4C8 (K4C7 + K4WB) #define K4C9 (K4C8 + K4WB) #define K4C10 (K4C9 + K4WB) #define K4C11 (K4C10 + K4WB) #define K4C12 (K4C11 + K4WB) #define K4C13 (K4C12 + K4WB) #define K4C14 (K4C13 + K4WB) #define K4C15 (K4C14 + K4WB) #define K4C16 (K4C15 + K4WB) #define K4C17 (K4C16 + K4WB) #define K4C18 (K4C17 + K4WB) #define K4C19 (K4C18 + K4WB) #define K4C20 (K4C19 + K4WB) #define K4C21 (K4C20 + K4WB) #define K4C22 (K4C21 + K4WB) #define K4C23 (K4C22 + K4WB) #define K4C24 (K4C23 + K4WB) #define K4C25 (K4C24 + K4WB) #define K4C26 (K4C25 + K4WB) #define K4C27 (K4C26 + K4WB) #define K4C28 (K4C27 + K4WB) brightonLocations keys4octave2[KEY_COUNT_4OCTAVE] = { {"", 2, K4C0, 0, K4WC, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteNHFUp.xpm", "bitmaps/newkeys/WhiteNHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C0 + K4W/2, 0, K4WC, K4IH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C1, K4IH, K4WC, K4IL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C1 + K4W/2, 0, K4WC, K4IH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C2, K4IH, K4WC, K4IL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C3, 0, K4WC, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteNHFUp.xpm", "bitmaps/newkeys/WhiteNHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C3 + K4W/2, 0, K4WC, K4IH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C4, K4IH, K4WC, K4IL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C4 + K4W/2, 0, K4WC, K4IH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C5, K4IH, K4WC, K4IL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C5 + K4W/2, 0, K4WC, K4IH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C6, K4IH, K4WC, K4IL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C7, 0, K4WC, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteNHFUp.xpm", "bitmaps/newkeys/WhiteNHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C7 + K4W/2, 0, K4WC, K4IH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C8, K4IH, K4WC, K4IL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C8 + K4W/2, 0, K4WC, K4IH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C9, K4IH, K4WC, K4IL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C10, 0, K4WC, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteNHFUp.xpm", "bitmaps/newkeys/WhiteNHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C10 + K4W/2, 0, K4WC, K4IH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C11, K4IH, K4WC, K4IL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C11 + K4W/2, 0, K4WC, K4IH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C12, K4IH, K4WC, K4IL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C12 + K4W/2, 0, K4WC, K4IH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C13, K4IH, K4WC, K4IL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C14, 0, K4WC, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteNHFUp.xpm", "bitmaps/newkeys/WhiteNHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C14 + K4W/2, 0, K4WC, K4IH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C15, K4IH, K4WC, K4IL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C15 + K4W/2, 0, K4WC, K4IH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C16, K4IH, K4WC, K4IL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C17, 0, K4WC, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteNHFUp.xpm", "bitmaps/newkeys/WhiteNHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C17 + K4W/2, 0, K4WC, K4IH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C18, K4IH, K4WC, K4IL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C18 + K4W/2, 0, K4WC, K4IH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C19, K4IH, K4WC, K4IL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C19 + K4W/2, 0, K4WC, K4IH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C20, K4IH, K4WC, K4IL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C21, 0, K4WC, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteNHFUp.xpm", "bitmaps/newkeys/WhiteNHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C21 + K4W/2, 0, K4WC, K4IH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C22, K4IH, K4WC, K4IL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C22 + K4W/2, 0, K4WC, K4IH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C23, K4IH, K4WC, K4IL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C24, 0, K4WC, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteNHFUp.xpm", "bitmaps/newkeys/WhiteNHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C24 + K4W/2, 0, K4WC, K4IH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C25, K4IH, K4WC, K4IL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C25 + K4W/2, 0, K4WC, K4IH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C26, K4IH, K4WC, K4IL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C26 + K4W/2, 0, K4WC, K4IH, 0, 1, 0, "bitmaps/newkeys/BlackNUp.xpm", "bitmaps/newkeys/BlackNDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C27, K4IH, K4WC, K4IL, 0, 1, 0, "bitmaps/newkeys/WhiteNHUp.xpm", "bitmaps/newkeys/WhiteNHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, K4C28, 0, K4WC, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteNHLUp.xpm", "bitmaps/newkeys/WhiteNHLDown.xpm", BRIGHTON_NOSHADOW}, }; brightonLocations keys4octave[KEY_COUNT_4OCTAVE] = { {"", 2, 0 * K4W, 0, K4W, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteHFUp.xpm", "bitmaps/newkeys/WhiteHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 0 * K4W + K4W/2, 0, K4W, K4IH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 1 * K4W, K4IH, K4W, K4IL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 1 * K4W + K4W/2, 0, K4W, K4IH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 2 * K4W, K4IH, K4W, K4IL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 3 * K4W, 0, K4W, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteHFUp.xpm", "bitmaps/newkeys/WhiteHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 3 * K4W + K4W/2, 0, K4W, K4IH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 4 * K4W, K4IH, K4W, K4IL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 4 * K4W + K4W/2, 0, K4W, K4IH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 5 * K4W, K4IH, K4W, K4IL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 5 * K4W + K4W/2, 0, K4W, K4IH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 6 * K4W, K4IH, K4W, K4IL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 7 * K4W, 0, K4W, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteHFUp.xpm", "bitmaps/newkeys/WhiteHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 7 * K4W + K4W/2, 0, K4W, K4IH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 8 * K4W, K4IH, K4W, K4IL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 8 * K4W + K4W/2, 0, K4W, K4IH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 9 * K4W, K4IH, K4W, K4IL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 10 * K4W, 0, K4W, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteHFUp.xpm", "bitmaps/newkeys/WhiteHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 10 * K4W + K4W/2, 0, K4W, K4IH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 11 * K4W, K4IH, K4W, K4IL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 11 * K4W + K4W/2, 0, K4W, K4IH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 12 * K4W, K4IH, K4W, K4IL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 12 * K4W + K4W/2, 0, K4W, K4IH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 13 * K4W, K4IH, K4W, K4IL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 14 * K4W, 0, K4W, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteHFUp.xpm", "bitmaps/newkeys/WhiteHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 14 * K4W + K4W/2, 0, K4W, K4IH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 15 * K4W, K4IH, K4W, K4IL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 15 * K4W + K4W/2, 0, K4W, K4IH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 16 * K4W, K4IH, K4W, K4IL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 17 * K4W, 0, K4W, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteHFUp.xpm", "bitmaps/newkeys/WhiteHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 17 * K4W + K4W/2, 0, K4W, K4IH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 18 * K4W, K4IH, K4W, K4IL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 18 * K4W + K4W/2, 0, K4W, K4IH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 19 * K4W, K4IH, K4W, K4IL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 19 * K4W + K4W/2, 0, K4W, K4IH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 20 * K4W, K4IH, K4W, K4IL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 21 * K4W, 0, K4W, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteHFUp.xpm", "bitmaps/newkeys/WhiteHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 21 * K4W + K4W/2, 0, K4W, K4IH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 22 * K4W, K4IH, K4W, K4IL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 22 * K4W + K4W/2, 0, K4W, K4IH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 23 * K4W, K4IH, K4W, K4IL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 24 * K4W, 0, K4W, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteHFUp.xpm", "bitmaps/newkeys/WhiteHFDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 24 * K4W + K4W/2, 0, K4W, K4IH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 25 * K4W, K4IH, K4W, K4IL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 25 * K4W + K4W/2, 0, K4W, K4IH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 26 * K4W, K4IH, K4W, K4IL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 26 * K4W + K4W/2, 0, K4W, K4IH, 0, 1, 0, "bitmaps/newkeys/BlackUp.xpm", "bitmaps/newkeys/BlackDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 27 * K4W, K4IH, K4W, K4IL, 0, 1, 0, "bitmaps/newkeys/WhiteHUp.xpm", "bitmaps/newkeys/WhiteHDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 28 * K4W, 0, K4W, 1000, 0, 1, 0, "bitmaps/newkeys/WhiteHLUp.xpm", "bitmaps/newkeys/WhiteHLDown.xpm", BRIGHTON_NOSHADOW}, }; #define KPS 1000 / 29 #define KPW 1000 / 29 #define KPH 930 #define KPMW 18 #define KPIW 40 #define KPIH 600 #define KPIL 410 #define KPIS 33 brightonLocations pedalBoard[KEY_COUNT_PEDAL] = { {"", 2, 1 * KPS, 0, KPW, KPH, 0, 1, 0, "bitmaps/newkeys/PedalWUp.xpm", "bitmaps/newkeys/PedalWDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 2 * KPS, 0, KPW, KPIH, 0, 1, 0, "bitmaps/newkeys/PedalBUp.xpm", "bitmaps/newkeys/PedalBDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 3 * KPS, 0, KPW, KPH, 0, 1, 0, "bitmaps/newkeys/PedalWUp.xpm", "bitmaps/newkeys/PedalWDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 4 * KPS, 0, KPW, KPIH, 0, 1, 0, "bitmaps/newkeys/PedalBUp.xpm", "bitmaps/newkeys/PedalBDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 5 * KPS, 0, KPW, KPH, 0, 1, 0, "bitmaps/newkeys/PedalWUp.xpm", "bitmaps/newkeys/PedalWDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 7 * KPS, 0, KPW, KPH, 0, 1, 0, "bitmaps/newkeys/PedalWUp.xpm", "bitmaps/newkeys/PedalWDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 8 * KPS, 0, KPW, KPIH, 0, 1, 0, "bitmaps/newkeys/PedalBUp.xpm", "bitmaps/newkeys/PedalBDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 9 * KPS, 0, KPW, KPH, 0, 1, 0, "bitmaps/newkeys/PedalWUp.xpm", "bitmaps/newkeys/PedalWDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 10 * KPS, 0, KPW, KPIH, 0, 1, 0, "bitmaps/newkeys/PedalBUp.xpm", "bitmaps/newkeys/PedalBDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 11 * KPS, 0, KPW, KPH, 0, 1, 0, "bitmaps/newkeys/PedalWUp.xpm", "bitmaps/newkeys/PedalWDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 12 * KPS, 0, KPW, KPIH, 0, 1, 0, "bitmaps/newkeys/PedalBUp.xpm", "bitmaps/newkeys/PedalBDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 13 * KPS, 0, KPW, KPH, 0, 1, 0, "bitmaps/newkeys/PedalWUp.xpm", "bitmaps/newkeys/PedalWDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 15 * KPS, 0, KPW, KPH, 0, 1, 0, "bitmaps/newkeys/PedalWUp.xpm", "bitmaps/newkeys/PedalWDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 16 * KPS, 0, KPW, KPIH, 0, 1, 0, "bitmaps/newkeys/PedalBUp.xpm", "bitmaps/newkeys/PedalBDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 17 * KPS, 0, KPW, KPH, 0, 1, 0, "bitmaps/newkeys/PedalWUp.xpm", "bitmaps/newkeys/PedalWDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 18 * KPS, 0, KPW, KPIH, 0, 1, 0, "bitmaps/newkeys/PedalBUp.xpm", "bitmaps/newkeys/PedalBDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 19 * KPS, 0, KPW, KPH, 0, 1, 0, "bitmaps/newkeys/PedalWUp.xpm", "bitmaps/newkeys/PedalWDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 21 * KPS, 0, KPW, KPH, 0, 1, 0, "bitmaps/newkeys/PedalWUp.xpm", "bitmaps/newkeys/PedalWDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 22 * KPS, 0, KPW, KPIH, 0, 1, 0, "bitmaps/newkeys/PedalBUp.xpm", "bitmaps/newkeys/PedalBDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 23 * KPS, 0, KPW, KPH, 0, 1, 0, "bitmaps/newkeys/PedalWUp.xpm", "bitmaps/newkeys/PedalWDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 24 * KPS, 0, KPW, KPIH, 0, 1, 0, "bitmaps/newkeys/PedalBUp.xpm", "bitmaps/newkeys/PedalBDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 25 * KPS, 0, KPW, KPH, 0, 1, 0, "bitmaps/newkeys/PedalWUp.xpm", "bitmaps/newkeys/PedalWDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 26 * KPS, 0, KPW, KPIH, 0, 1, 0, "bitmaps/newkeys/PedalBUp.xpm", "bitmaps/newkeys/PedalBDown.xpm", BRIGHTON_NOSHADOW}, {"", 2, 27 * KPS, 0, KPW, KPH, 0, 1, 0, "bitmaps/newkeys/PedalWUp.xpm", "bitmaps/newkeys/PedalWDown.xpm", BRIGHTON_NOSHADOW}, }; brightonLocations mods[2] = { {"", 1, 290, 170, 97, 620, 0, 1, 0, 0, 0, BRIGHTON_CENTER|BRIGHTON_NOSHADOW}, {"", 1, 655, 170, 97, 620, 0, 1, 0, 0, 0, BRIGHTON_NOSHADOW}, }; extern int bristolMidiControl(int, int, int, int, int); int modCallback(brightonWindow *win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); /* printf("modCallback(%x, %i, %i, %f)\n", synth, panel, index, value); */ if (global.libtest) return(0); /* * If this is controller 0 it is the frequency control, otherwise a * generic controller 1. */ if (index == 0) bristolMidiSendMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_PITCH, 0, (int) (value * C_RANGE_MIN_1)); else { if (synth->flags & NO_KEYTRACK) return(0); bristolMidiControl(global.controlfd, synth->midichannel, 0, 1, ((int) (value * (C_RANGE_MIN_1 - 1))) >> 7); } return(0); } int keyCallback(brightonWindow *win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); if (global.libtest) return(0); if (global.synths->flags & REQ_MIDI_DEBUG2) printf("keycallback(%p, %i, %i, %f): %i %i - %i\n", synth, panel, index, value, synth->transpose, global.controlfd, index + synth->transpose); /* * Want to send a note event, on or off, for this index + transpose. */ if (value) bristolMidiSendMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_KEYON, 0, index + synth->transpose); else bristolMidiSendMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_KEYOFF, 0, index + synth->transpose); return(0); } #endif /* BRIGHTONKEYBOARD_H */ bristol-0.60.11/brighton/brightonVoyager.c0000644000175000017500000003076211746476475015444 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* * This is the emulator stub for the Moog Voyager Ice Blue. It has a separate * layout but then uses all the same code from the Explorer interface. It could * have been buried in the same file. */ #include "brighton.h" #include "brightonMini.h" #include "brightoninternals.h" /* static int voyagerInit(); static int voyagerCallback(brightonWindow *, int, int, float); */ static int voyagerConfigure(); extern int explorerInit(); extern int explorerConfigure(); extern int explorerCallback(brightonWindow *, int, int, float); static int midiCallback(brightonWindow *, int, int, float); extern guimain global; extern int empty; #include "brightonKeys.h" #define KEY_PANEL 1 #define FIRST_DEV 0 #define DEVICE_COUNT 77 #define ACTIVE_DEVS 56 #define MEM_START (ACTIVE_DEVS + 1) #define DISPLAY1 (DEVICE_COUNT - 2) #define DISPLAY2 (DEVICE_COUNT - 1) #define S1 85 #define B1 15 #define B2 110 #define B3 37 #define B4 42 #define R14 200 #define R24 400 #define R34 600 #define R44 800 #define R15 200 #define R25 350 #define R35 500 #define R45 650 #define R55 800 #define C1 25 #define C2 90 #define C3 155 #define C4 220 #define C5 285 #define C6 350 #define C6I 395 #define C7 615 #define C8 665 #define C9 742 #define C10 810 #define C11 875 #define C12 945 /* * This structure is for device definition. The structure is defined in * include/brighton.h, further definitions in brighton/brightonDevtable.h and * include/brightoninternals.h * * typedef int (*brightonCallback)(int, float); * typedef struct BrightonLocations { * int device; 0=rotary, 1=scale, etc. * float relx, rely; relative position with regards to 1000 by 1000 window * float relw, relh; relative height. * int from, to; * brightonCallback callback; specific to this dev * char *image; bitmap. If zero take a device default. * int flags; * } brightonLocations; * * This example is for a voyagerBristol type synth interface. */ static brightonLocations locations[DEVICE_COUNT] = { /* LFO and control */ {"LFO-Freq", 0, C1 - 7, R14 - 20, S1 + 40, S1 + 40, 0, 1, 0, 0, 0, 0}, {"LFO-Sync", 2, C1 - 5, R24 + 25, B3, B4, 0, 3, 0, "bitmaps/buttons/rockerblue.xpm", 0, 0}, {"GLOBAL TUNE", 0, C1, R34, S1, S1, 0, 1, 0, 0, 0, BRIGHTON_NOTCH}, {"Glide", 0, C1, R44, S1, S1, 0, 1, 0, 0, 0, 0}, /* Routing */ {"Mod1-Source", 0, C2, R14, S1, S1, 0, 4, 0, 0, 0, 0}, {"Mod1-Shape", 0, C2, R24, S1, S1, 0, 3, 0, 0, 0, 0}, {"Mod1-Dest", 0, C2, R34, S1, S1, 0, 5, 0, 0, 0, 0}, {"Mod1-Gain", 0, C2, R44, S1, S1, 0, 1, 0, 0, 0, 0}, {"Mod2-Source", 0, C3, R14, S1, S1, 0, 4, 0, 0, 0, 0}, {"Mod2-Shape", 0, C3, R24, S1, S1, 0, 3, 0, 0, 0, 0}, {"Mod2-Dest", 0, C3, R34, S1, S1, 0, 5, 0, 0, 0, 0}, {"Mod2-Gain", 0, C3, R44, S1, S1, 0, 1, 0, 0, 0, 0}, /* Oscillators */ {"Osc1-Transpose", 0, C4, R24, S1, S1, 0, 5, 0, 0, 0, 0}, {"Osc1-Waveform", 0, C4, R34, S1, S1, 0, 1, 0, 0, 0, 0}, {"Osc2-Tuning", 0, C5 - 7, R14 - 20, S1 + 40, S1 + 40, 0, 1, 0, 0, 0, BRIGHTON_NOTCH}, {"Osc2-Transpose", 0, C5, R24, S1, S1, 0, 5, 0, 0, 0, 0}, {"Osc2-Waveform", 0, C5, R34, S1, S1, 0, 1, 0, 0, 0, 0}, {"Osc3-Tuning", 0, C6 - 7, R14 - 20, S1 + 40, S1 + 40, 0, 1, 0, 0, 0, BRIGHTON_NOTCH}, {"Osc3-Transpose", 0, C6, R24, S1, S1, 0, 5, 0, 0, 0, 0}, {"Osc3-Waveform", 0, C6, R34, S1, S1, 0, 1, 0, 0, 0, 0}, /* Osc mod switches */ {"Sync-1/2", 2, C4, R44 + 10, B1, B2, 0, 1, 0, 0, 0, BRIGHTON_VERTICAL}, {"FM-1/3", 2, C4 + 40, R44 + 10, B1, B2, 0, 1, 0, 0, 0, BRIGHTON_VERTICAL}, {"KBD-3", 2, C4 + 95, R44 + 10, B1, B2, 0, 1, 0, 0, 0, BRIGHTON_VERTICAL}, {"Freq-3", 2, C4 + 135, R44 + 10, B1, B2, 0, 1, 0, 0, 0, BRIGHTON_VERTICAL}, /* Mixer */ {"Mix-EXT", 0, C7, R15, S1, S1, 0, 1, 0, 0, 0, 0}, {"Mix-O1", 0, C7, R25, S1, S1, 0, 1, 0, 0, 0, 0}, {"Mix-O2", 0, C7, R35, S1, S1, 0, 1, 0, 0, 0, 0}, {"Mix-O3", 0, C7, R45, S1, S1, 0, 1, 0, 0, 0, 0}, {"Mix-NSE", 0, C7, R55, S1, S1, 0, 1, 0, 0, 0, 0}, {"Mix-Ext-off", 2, C8, R15 + 25, B3, B4, 0, 1, 0, "bitmaps/buttons/rockerblue.xpm", 0, 0}, {"Mix-O1-off", 2, C8, R25 + 25, B3, B4, 0, 1, 0, "bitmaps/buttons/rockerblue.xpm", 0, 0}, {"Mix-O2-off", 2, C8, R35 + 25, B3, B4, 0, 1, 0, "bitmaps/buttons/rockerblue.xpm", 0, 0}, {"Mix-O3-off", 2, C8, R45 + 25, B3, B4, 0, 1, 0, "bitmaps/buttons/rockerblue.xpm", 0, 0}, {"Mix-Nse-off", 2, C8, R55 + 25, B3, B4, 0, 1, 0, "bitmaps/buttons/rockerblue.xpm", 0, 0}, /* Filter */ {"VCF-Cutoff", 0, C9 - 7, R15 - 25, S1 + 40, S1 + 40, 0, 1, 0, 0, 0, 0}, {"VCF-Space", 0, C9, R25, S1, S1, 0, 1, 0, 0, 0, 0}, {"VCF-Res", 0, C9, R35, S1, S1, 0, 1, 0, 0, 0, 0}, {"VCF-KBD", 0, C9, R45, S1, S1, 0, 1, 0, 0, 0, 0}, {"VCF-Mode", 2, C9, R55 + 25, B3, B4, 0, 1, 0, 0, 0, 0}, /* Filter envelope */ {"VCF-Attack", 0, C10, R15, S1, S1, 0, 1, 0, 0, 0, 0}, {"VCF-Decay", 0, C10, R25, S1, S1, 0, 1, 0, 0, 0, 0}, {"VCF-Sustain", 0, C10, R35, S1, S1, 0, 1, 0, 0, 0, 0}, {"VCF-Release", 0, C10, R45, S1, S1, 0, 1, 0, 0, 0, 0}, {"VCF-EnvLevel", 0, C10, R55, S1, S1, 0, 1, 0, 0, 0, 0}, /* Amp Envelope */ {"VCA-Attack", 0, C11, R15, S1, S1, 0, 1, 0, 0, 0, 0}, {"VCA-Decay", 0, C11, R25, S1, S1, 0, 1, 0, 0, 0, 0}, {"VCA-Sustain", 0, C11, R35, S1, S1, 0, 1, 0, 0, 0, 0}, {"VCA-Release", 0, C11, R45, S1, S1, 0, 1, 0, 0, 0, 0}, {"VCA-Veloc", 2, C11, R55 + 25, B3, B4, 0, 1, 0, 0, 0, 0}, /* Vol, on/off, glide and release */ {"Volume", 0, C12 - 7, R15 - 25 , S1 + 40, S1 + 40, 0, 1, 0, 0, 0, 0}, {"On/Off", 2, C12 - 4, R25 + 25, B3, B4, 0, 1, 0, 0, 0, 0}, {"LFO-Multi", 2, C12 - 4, R35 + 25, B3, B4, 0, 1, 0, "bitmaps/buttons/rockerwhite.xpm", 0, 0}, {"Glide-On", 2, C12 - 4, R45 + 25, B3, B4, 0, 1, 0, "bitmaps/buttons/rockerwhite.xpm", 0, 0}, {"Release-On", 2, C12 - 4, R55 + 25, B3, B4, 0, 1, 0, "bitmaps/buttons/rockerwhite.xpm", 0, 0}, {"Reserved", 5, 405, 410, 180, 518, 0, 1, 0, "bitmaps/buttons/pointer.xpm", 0, 0}, {"Reserved", 5, 405, 410, 180, 518, 0, 1, 0, "bitmaps/buttons/pointer.xpm", 0, BRIGHTON_WITHDRAWN}, /* logo */ {"", 4, 762, 1037, 240, 140, 0, 1, 0, "bitmaps/images/explorer.xpm", 0, 0}, /* memories */ {"", 2, 418, 225, 17, 78, 0, 1.01, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 436, 225, 17, 78, 0, 1.01, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 454, 225, 17, 78, 0, 1.01, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 472, 225, 17, 78, 0, 1.01, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 490, 225, 17, 78, 0, 1.01, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 418, 308, 17, 78, 0, 1.01, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 436, 308, 17, 78, 0, 1.01, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 454, 308, 17, 78, 0, 1.01, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 472, 308, 17, 78, 0, 1.01, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 490, 308, 17, 78, 0, 1.01, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 510, 228, 15, 70, 0, 1.01, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 510, 309, 15, 70, 0, 1.01, 0, "bitmaps/buttons/pressoffo.xpm", "bitmaps/buttons/pressono.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 540, 70, 16, 78, 0, 1.01, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 540, 145, 16, 78, 0, 1.01, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 540, 227, 16, 78, 0, 1.01, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 540, 308, 16, 78, 0, 1.01, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* mem up down */ {"", 2, 402, 228, 15, 70, 0, 1.01, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 402, 311, 15, 70, 0, 1.01, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, /* displays */ {"", 3, 403, 90, 128, 63, 0, 1, 0, 0, "bitmaps/images/alphadisplay3.xpm", 0}, {"", 3, 403, 150, 128, 63, 0, 1, 0, 0, 0, 0} }; /* * These are new mod controls for the Pro-1. Used here for the Explorer. */ static brightonLocations newmods[2] = { {"", BRIGHTON_MODWHEEL, 260, 200, 190, 565, 0, 1, 0, "bitmaps/knobs/modwheelblue.xpm", 0, BRIGHTON_HSCALE|BRIGHTON_NOSHADOW|BRIGHTON_CENTER|BRIGHTON_NOTCH}, {"", BRIGHTON_MODWHEEL, 610, 200, 190, 565, 0, 1, 0, "bitmaps/knobs/modwheelblue.xpm", 0, BRIGHTON_HSCALE|BRIGHTON_NOSHADOW}, }; /* * This is a set of globals for the main window rendering. Again taken from * include/brighton.h */ brightonApp voyagerApp = { "voyager", 0, /* no blueprint on wood background. */ "bitmaps/textures/voyagerpaint.xpm", 0, /* or BRIGHTON_STRETCH, default is tesselate */ explorerInit, voyagerConfigure, /* 3 callbacks, unused? */ midiCallback, destroySynth, {1, 100, 2, 2, 5, 520, 0, 0}, 817, 472, 0, 0, 7, /* one panel only */ { { "Voyager", "bitmaps/blueprints/voyager.xpm", "bitmaps/textures/black.xpm", 0, /* flags */ 0, explorerConfigure, explorerCallback, 25, 25, 950, 532, DEVICE_COUNT, locations }, { "Keyboard", 0, "bitmaps/newkeys/ekbg.xpm", /* flags */ 0x020|BRIGHTON_STRETCH, 0, 0, keyCallback, 140, 675, 840, 300, KEY_COUNT_3OCTAVE, keys3octave }, { "Mods", 0, "bitmaps/textures/voyagerpaint.xpm", /* flags */ BRIGHTON_STRETCH, 0, 0, modCallback, 15, 675, 125, 300, 2, newmods }, { "SP0", 0, "bitmaps/textures/voyagerpaint.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 930, 675, 60, 300, 0, 0 }, { "SP1", 0, "bitmaps/textures/voyagerpaint.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 0, 0, 15, 1000, 0, 0 }, { "SP2", 0, "bitmaps/textures/voyagerpaint.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 985, 0, 15, 1000, 0, 0 }, } }; /*static dispatcher dispatch[DEVICE_COUNT]; */ static int midiCallback(brightonWindow *win, int controller, int value, float n) { guiSynth *synth = findSynth(global.synths, win); printf("midi callback: %x, %i\n", controller, value); switch(controller) { case MIDI_PROGRAM: printf("midi program: %x, %i\n", controller, value); synth->location = value; loadMemory(synth, "explorer", 0, synth->bank + synth->location, synth->mem.active, FIRST_DEV, 0); break; case MIDI_BANK_SELECT: printf("midi banksel: %x, %i\n", controller, value); synth->bank = value; break; } return(0); } /* * This will be called to make any routine specific parameters available. */ static int voyagerConfigure(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); brightonEvent event; memset(&event, 0, sizeof(brightonEvent)); if (synth == 0) { printf("problems going operational\n"); return(-1); } if (synth->flags & OPERATIONAL) return(0); printf("going operational\n"); synth->flags |= OPERATIONAL; synth->keypanel = 1; synth->keypanel2 = -1; synth->transpose = 36; displayText(synth, "CHAN", synth->midichannel + 1, DISPLAY1); loadMemory(synth, "explorer", 0, synth->location, synth->mem.active, FIRST_DEV, 0); displayText(synth, "PRG", synth->location, DISPLAY2); brightonPut(win, "bitmaps/blueprints/voyagershade.xpm", 0, 0, win->width, win->height); /* * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only * occurs on first paint, so we suppress the first paint, and then request * an expose here. */ event.type = BRIGHTON_EXPOSE; event.intvalue = 1; brightonParamChange(synth->win, KEY_PANEL, -1, &event); configureGlobals(synth); return(0); } bristol-0.60.11/brighton/brightonPoly6.c0000644000175000017500000006661011746476475015042 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* Korg Poly6 UI */ /* Bend depth and modes need to be implemented. */ #include #include "brighton.h" #include "brightonMini.h" #include "brightoninternals.h" static int initmem, width; static int poly6Init(); static int poly6Configure(); static int poly6Callback(brightonWindow *, int, int, float); static int poly6ModCallback(brightonWindow *, int, int, float); static int midiCallback(brightonWindow *, int, int, float); extern guimain global; #include "brightonKeys.h" #define DEVICE_COUNT (53) #define ACTIVE_DEVS (DEVICE_COUNT - 20) #define MEM_START ACTIVE_DEVS #define MIDI_START (MEM_START + 18) #define P6_BEND 2 #define KEY_HOLD 17 #define CHORUS (32) #define RADIOSET_1 MEM_START #define RADIOSET_2 (MEM_START + 1) #define RADIOSET_3 17 /* MODE */ #define KEY_PANEL 1 /* * This structure is for device definition. The structure is defined in * include/brighton.h, further definitions in brighton/brightonDevtable.h and * include/brightoninternals.h * * typedef int (*brightonCallback)(int, float); * typedef struct BrightonLocations { * int device; 0=rotary, 1=scale, etc. * float relx, rely; relative position with regards to 1000 by 1000 window * float relw, relh; relative height. * int from, to; * brightonCallback callback; specific to this dev * char *image; bitmap. If zero take a device default. * int flags; * } brightonLocations; * * This example is for a poly6Bristol type synth interface. */ #define R0 200 #define R1 465 #define D0 8 #define D1 41 #define D2 23 #define C0 25 #define C1 (C0 + D1 + D0) #define C2 (C1 + D1 + D0) #define C3 (C2 + D1) #define C4 (C3 + D1) #define C5 (C4 + D1) #define C6 (C5 + D1) #define C7 (C6 + D1) #define C8 (C7 + D1) #define C9 (C8 + D1) #define C10 (C9 + D1) #define C11 (C10 + D1 + D0) #define C12 (C11 + D1) #define C13 (C12 + D1) #define C14 (C13 + D1) #define C15 (C14 + D1 + D0) #define C16 (C15 + D1) #define C17 (C16 + D1) #define C18 (C17 + D2) #define C19 (C18 + D2) #define C20 (C19 + D2) #define C21 (C20 + D2) #define C22 (C21 + D2) #define C23 (C22 + D2) #define C24 (C23 + D2) #define C25 (C24 + D2) #define C26 (C25 + D2 + 9) #define S1 140 #define S2 12 #define S3 180 #define S4 10 static brightonLocations locations[DEVICE_COUNT] = { {"MasterVolume", 0, C0, R0, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"MasterTuning", 0, C1, R0, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, BRIGHTON_NOTCH}, {"BendDepth", 0, C1, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, /* VCO 1 */ {"OSC-Transpose", 0, C2, R0, S1, S1, 0, 3, 0, "bitmaps/knobs/knob6.xpm", 0, BRIGHTON_STEPPED}, {"OSC-WaveForm", 0, C3, R0, S1, S1, 0, 3, 0, "bitmaps/knobs/knob6.xpm", 0, BRIGHTON_STEPPED}, {"OSC-PWM", 0, C4, R0, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"Osc-Tuning", 0, C5, R0, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"Osc-Subwave", 2, C6 - 5, R0 + 10, S4, S3, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW}, /* Noise - Mods 8 */ {"Noise", 0, C2, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"LFO-Freq", 0, C3, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"LFO-Delay", 0, C4, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"LFO-Level", 0, C5, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"LFO-Dest", 2, C6 - 5, R1 + 20, S4, S3, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW}, /* Filter 13 */ {"VCF-Freq", 0, C7, R0, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"VCF-Res", 0, C8, R0, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"VCF-Env", 0, C9, R0, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"VCF-KBD", 0, C10, R0, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, /* Mode 17 */ {"MODE Hold", 2, C8 + 8, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffw.xpm", "bitmaps/buttons/pressonw.xpm", BRIGHTON_RADIOBUTTON}, {"MODE Mono", 2, C9 + 8, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffw.xpm", "bitmaps/buttons/pressonw.xpm", BRIGHTON_RADIOBUTTON}, {"MODE Mono", 2, C10 + 8, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffw.xpm", "bitmaps/buttons/pressonw.xpm", BRIGHTON_RADIOBUTTON}, /* ENV 20 */ {"FiltEnv-Attack", 0, C11, R0, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"FiltEnv-Decay", 0, C12, R0, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"FiltEnv-Sustain", 0, C13, R0, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"FiltEnv-Relase", 0, C14, R0, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, /* ENV 24 */ {"Env-Attack", 0, C11, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"Env-Decay", 0, C12, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"Env-Sustain", 0, C13, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"Env-Release", 0, C14, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, /* Amp - Effects 28 */ {"Amp-Env/Gate", 2, C15, R0 + 20, S4, S1 - 20, 0, 1, 0, "bitmaps/buttons/sw1.xpm", "bitmaps/buttons/sw2.xpm", BRIGHTON_NOSHADOW}, {"Amp-Gain", 0, C16, R0, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, {"Chorus-Mode", 0, C15, R1, S1, S1, 0, 3, 0, "bitmaps/knobs/knob6.xpm", 0, BRIGHTON_STEPPED}, {"Chorus-Depth", 0, C16, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, /* Glide */ {"Glide", 0, C0, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0}, /* Memory - MIDI 33 */ {"", 2, C17, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffo.xpm", "bitmaps/buttons/pressono.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, C18, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C19, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C20, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C21, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C22, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C23, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C24, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C25, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C18, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C19, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C20, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C21, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C22, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C23, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C24, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C25, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, /* Load */ {"", 2, C17, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffw.xpm", "bitmaps/buttons/pressonw.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, C26, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffw.xpm", "bitmaps/buttons/pressonw.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, C26, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffw.xpm", "bitmaps/buttons/pressonw.xpm", BRIGHTON_CHECKBUTTON}, }; /* */ /* * This is a set of globals for the main window rendering. Again taken from * include/brighton.h */ brightonApp poly6App = { "poly", 0, /* no blueprint on wood background. */ "bitmaps/textures/metal6.xpm", BRIGHTON_STRETCH, poly6Init, poly6Configure, /* 3 callbacks, unused? */ midiCallback, destroySynth, {6, 100, 2, 2, 5, 520, 0, 0}, 800, 240, 0, 0, 5, /* one panel only */ { { "Poly6", "bitmaps/blueprints/poly6.xpm", "bitmaps/textures/metal4.xpm", BRIGHTON_STRETCH, /* flags */ 0, 0, poly6Callback, 12, 0, 976, 560, DEVICE_COUNT, locations }, { "Keyboard", 0, "bitmaps/newkeys/kbg.xpm", /* flags */ 0x020|BRIGHTON_STRETCH, 0, 0, keyCallback, 105, 550, 908, 435, KEY_COUNT, keys }, { "Mods", "bitmaps/blueprints/polymods.xpm", "bitmaps/textures/metal6.xpm", /* flags */ BRIGHTON_STRETCH, 0, 0, poly6ModCallback, 15, 550, 90, 435, 2, mods }, { "Edge", 0, "bitmaps/textures/metal4.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 0, 0, 15, 995, 0, 0 }, { "Edge", 0, "bitmaps/textures/metal4.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 988, 0, 12, 995, 0, 0 }, } }; static int midiCallback(brightonWindow *win, int controller, int value, float n) { guiSynth *synth = findSynth(global.synths, win); printf("midi callback: %x, %i\n", controller, value); switch(controller) { case MIDI_PROGRAM: printf("midi program: %x, %i\n", controller, value); synth->location = value; loadMemory(synth, "poly", 0, synth->bank + synth->location, synth->mem.active, 0, 0); break; case MIDI_BANK_SELECT: printf("midi banksel: %x, %i\n", controller, value); synth->bank = value; break; } return(0); } /*static dispatcher dispatch[DEVICE_COUNT]; */ static int poly6ModCallback(brightonWindow *win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); float bend = synth->mem.param[P6_BEND]; /*printf("poly6ModCallback(%x, %i, %i, %f)\n", synth, panel, index, value); */ /* * If this is controller 0 it is the frequency control, otherwise a * generic controller 1. The depth of the bend wheel is a parameter, so * we need to scale the value here. */ if (index == 0) { /* * Value is between 0 and 1 latching at 0.5. Have to scale the value * and subtrace if from the mid point */ bristolMidiSendMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_PITCH, 0, (int) (((0.5 - bend / 2) + (value * bend)) * C_RANGE_MIN_1)); } else { bristolMidiControl(global.controlfd, synth->midichannel, 0, 1, ((int) (value * C_RANGE_MIN_1)) >> 7); } return(0); } static int poly6MidiSendMsg(void *synth, int fd, int chan, int c, int o, int v) { /*printf("%i, %i, %i\n", c, o, v); */ bristolMidiSendMsg(fd, chan, c, o, v); return(0); } static void poly6Hold(guiSynth *synth) { if (((synth->flags & OPERATIONAL) == 0) || (global.libtest)) return; if (synth->mem.param[KEY_HOLD]) bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_HOLD|1); else bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_HOLD|0); } static void fixModes(guiSynth *synth, int fd, int chan, int c, int o, int v) { /* * Look into the memory at 18 and 19 to find the current mode and send it * to the engine. */ if (synth->mem.param[18] != 0) bristolMidiSendMsg(fd, chan, 126, 7, 1); else bristolMidiSendMsg(fd, chan, 126, 8, 1); poly6Hold(synth); } int poly6loadMemory(guiSynth *synth, char *algo, char *name, int location, int active, int skip, int flags) { brightonEvent event; loadMemory(synth, "poly", 0, location, synth->mem.active, 0, 0); fixModes(synth, synth->sid, synth->midichannel, 0, 0, 0); event.type = BRISTOL_FLOAT; event.value = 1; brightonParamChange(synth->win, 0, MEM_START + location / 10, &event); brightonParamChange(synth->win, 0, MEM_START+8+(location % 10), &event); return(0); } static void poly6Memory(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; if (synth->flags & MEM_LOADING) return; switch(c) { case 0: saveMemory(synth, "poly", 0, synth->bank + synth->location, 0); return; break; case 17: loadMemory(synth, "poly", 0, synth->bank + synth->location, synth->mem.active, 0, 0); fixModes(synth, fd, chan, c, o, v); return; break; case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: if (synth->dispatch[RADIOSET_1].other2) { synth->dispatch[RADIOSET_1].other2 = 0; return; } if (synth->dispatch[RADIOSET_1].other1 != -1) { synth->dispatch[RADIOSET_1].other2 = 1; if (synth->dispatch[RADIOSET_1].other1 != c) event.value = 0; else event.value = 1; brightonParamChange(synth->win, synth->panel, synth->dispatch[RADIOSET_1].other1 + MEM_START, &event); } synth->dispatch[RADIOSET_1].other1 = c; synth->bank = c * 10; break; case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: if (synth->dispatch[RADIOSET_2].other2) { synth->dispatch[RADIOSET_2].other2 = 0; return; } if (synth->dispatch[RADIOSET_2].other1 != -1) { synth->dispatch[RADIOSET_2].other2 = 1; if (synth->dispatch[RADIOSET_2].other1 != c) event.value = 0; else event.value = 1; brightonParamChange(synth->win, synth->panel, synth->dispatch[RADIOSET_2].other1 + MEM_START, &event); } synth->dispatch[RADIOSET_2].other1 = c; /* Do radio buttons */ synth->location = c - 8; break; } } static void poly6PWM(guiSynth *synth, int fd, int chan, int c, int o, int v) { /* * This has two functions, it sets the PW of the osc and also the gain * of PWM. */ bristolMidiSendMsg(fd, chan, 0, 0, v); bristolMidiSendMsg(fd, chan, 126, 4, v); } static void poly6Waveform(guiSynth *synth, int fd, int chan, int c, int o, int v) { if (c == 1) { /* * Subosc 2 == off */ if (v == 2) bristolMidiSendMsg(fd, chan, 1, 6, 0); if (v == 1) { bristolMidiSendMsg(fd, chan, 1, 1, 1); bristolMidiSendMsg(fd, chan, 1, 6, 1); } if (v == 0) { bristolMidiSendMsg(fd, chan, 1, 1, 0); bristolMidiSendMsg(fd, chan, 1, 6, 1); } return; } switch(v) { case 0: /* * Ramp off, square off, tri on */ bristolMidiSendMsg(fd, chan, 0, 4, 0); bristolMidiSendMsg(fd, chan, 0, 6, 0); bristolMidiSendMsg(fd, chan, 0, 5, 1); bristolMidiSendMsg(fd, chan, 126, 5, 0); break; case 1: bristolMidiSendMsg(fd, chan, 0, 5, 0); bristolMidiSendMsg(fd, chan, 0, 6, 0); bristolMidiSendMsg(fd, chan, 0, 4, 1); bristolMidiSendMsg(fd, chan, 126, 5, 0); break; case 2: bristolMidiSendMsg(fd, chan, 0, 4, 0); bristolMidiSendMsg(fd, chan, 0, 5, 0); bristolMidiSendMsg(fd, chan, 0, 6, 1); bristolMidiSendMsg(fd, chan, 126, 5, 0); break; case 3: bristolMidiSendMsg(fd, chan, 0, 4, 0); bristolMidiSendMsg(fd, chan, 0, 5, 0); bristolMidiSendMsg(fd, chan, 0, 6, 1); bristolMidiSendMsg(fd, chan, 126, 5, 1); break; } } static int poly6Midi(guiSynth *synth, int fd, int chan, int c, int o, int v) { int newchan; if ((synth->flags & OPERATIONAL) == 0) return(0); if (c == 1) { if ((newchan = synth->midichannel - 1) < 0) { synth->midichannel = 0; return(0); } } else { if ((newchan = synth->midichannel + 1) >= 15) { synth->midichannel = 15; return(0); } } if (global.libtest == 0) { bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_MIDICHANNEL|newchan); } synth->midichannel = newchan; return(0); } /* * For the sake of ease of use, links have been placed here to be called * by any of the devices created. They would be better in some other file, * perhaps with this as a dispatch. * * Param refers to the device index in the locations table given below. */ static int poly6Callback(brightonWindow * win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); int sendvalue; /* printf("poly6Callback(%i, %f): %x\n", index, value, synth); */ if (synth == 0) return(0); if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0)) return(0); if (poly6App.resources[0].devlocn[index].to == 1) sendvalue = value * C_RANGE_MIN_1; else sendvalue = value; synth->mem.param[index] = value; if ((!global.libtest) || (index >= ACTIVE_DEVS)) synth->dispatch[index].routine(synth, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #define DEBUG #ifdef DEBUG else printf("dispatch[%p,%i](%i, %i, %i, %i, %i)\n", synth, index, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #endif return(0); } static void poly6Gain(guiSynth *synth, int fd, int chan, int c, int o, int v) { switch (c) { case 6: case 101: /* * Gain controls */ bristolMidiSendMsg(global.controlfd, synth->sid, 6, 4, ((int) (synth->mem.param[0] * synth->mem.param[29] * C_RANGE_MIN_1))); break; case 100: /* * This is the attentuator switch, 1 == gate. */ if (synth->mem.param[28]) { /* * Configure a gate. */ bristolMidiSendMsg(global.controlfd, synth->sid, 6, 0, 512); bristolMidiSendMsg(global.controlfd, synth->sid, 6, 1, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 6, 2, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 6, 3, 512); } else { /* * Configure the env */ bristolMidiSendMsg(global.controlfd, synth->sid, 6, 0, (int) (synth->mem.param[24] * C_RANGE_MIN_1)); bristolMidiSendMsg(global.controlfd, synth->sid, 6, 1, (int) (synth->mem.param[25] * C_RANGE_MIN_1)); bristolMidiSendMsg(global.controlfd, synth->sid, 6, 2, (int) (synth->mem.param[26] * C_RANGE_MIN_1)); bristolMidiSendMsg(global.controlfd, synth->sid, 6, 3, (int) (synth->mem.param[27] * C_RANGE_MIN_1)); } break; case 99: if (synth->mem.param[28] == 0) bristolMidiSendMsg(global.controlfd, synth->sid, 6, o, v); bristolMidiSendMsg(global.controlfd, synth->sid, 8, 3, v); break; } } static int poly6Mode(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; if (synth->flags & MEM_LOADING) return(0); if (synth->dispatch[RADIOSET_3].other2) return(synth->dispatch[RADIOSET_3].other2 = 0); if (synth->dispatch[RADIOSET_3].other1 != -1) { synth->dispatch[RADIOSET_3].other2 = 1; if (synth->dispatch[RADIOSET_3].other1 != c) event.value = 0; else event.value = 1; brightonParamChange(synth->win, synth->panel, synth->dispatch[RADIOSET_3].other1, &event); } synth->dispatch[RADIOSET_3].other1 = c; /* bristolMidiSendMsg(global.controlfd, synth->sid, 126, o, v); */ poly6Hold(synth); switch (c) { case 18: bristolMidiSendMsg(global.controlfd, synth->sid, 126, 7, 1); break; case 19: bristolMidiSendMsg(global.controlfd, synth->sid, 126, 8, 1); break; } return(0); } /* * Any location initialisation required to run the callbacks. For bristol, this * will connect to the engine, and give it some base parameters. * May need to generate some application specific menus. * Will also then make specific requests to some of the devices to alter their * rendering. */ static int poly6Init(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); dispatcher *dispatch; int i; if (synth == 0) { synth = findSynth(global.synths, 0); if (synth == 0) { printf("cannot init\n"); return(0); } } if ((initmem = synth->location) == 0) initmem = 11; synth->win = win; printf("Initialise the poly6 link to bristol: %p\n", synth->win); synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float)); synth->mem.count = DEVICE_COUNT; synth->mem.active = ACTIVE_DEVS; synth->dispatch = (dispatcher *) brightonmalloc(DEVICE_COUNT * sizeof(dispatcher)); dispatch = synth->dispatch; /* * We really want to have three connection mechanisms. These should be * 1. Unix named sockets. * 2. UDP sockets. * 3. MIDI pipe. */ if (synth->voices == BRISTOL_VOICECOUNT) synth->voices = 6; if (!global.libtest) if ((synth->sid = initConnection(&global, synth)) < 0) return(-1); for (i = 0; i < DEVICE_COUNT; i++) synth->dispatch[i].routine = poly6MidiSendMsg; /* Vol tune bend - NOT FINNISHED */ dispatch[0].controller = 6; dispatch[0].operator = 4; dispatch[0].routine = (synthRoutine) poly6Gain; dispatch[1].controller = 126; dispatch[1].operator = 1; dispatch[2].controller = 126; dispatch[2].operator = 2; /* VCO */ dispatch[3].controller = 0; dispatch[3].operator = 1; dispatch[4].controller = 0; dispatch[4].operator = 50; dispatch[4].routine = (synthRoutine) poly6Waveform; dispatch[5].controller = 0; dispatch[5].operator = 0; dispatch[5].routine = (synthRoutine) poly6PWM; dispatch[6].controller = 10; dispatch[6].operator = 0; /* Subosc */ dispatch[7].controller = 1; dispatch[7].operator = 0; dispatch[7].routine = (synthRoutine) poly6Waveform; /* Noise */ dispatch[8].controller = 7; dispatch[8].operator = 0; /* Mods */ dispatch[9].controller = 2; dispatch[9].operator = 0; dispatch[10].controller = 8; dispatch[10].operator = 0; dispatch[11].controller = 8; dispatch[11].operator = 4; dispatch[12].controller = 126; dispatch[12].operator = 6; /* Filter */ dispatch[13].controller = 3; dispatch[13].operator = 0; dispatch[14].controller = 3; dispatch[14].operator = 1; dispatch[15].controller = 3; dispatch[15].operator = 2; dispatch[16].controller = 3; dispatch[16].operator = 3; /* MODE NOT DONE */ /* * Hold - no key off events * Mono - unison * Poly - poly */ dispatch[17].controller = 17; dispatch[17].operator = 1; dispatch[18].controller = 18; dispatch[18].operator = 7; dispatch[19].controller = 19; dispatch[19].operator = 8; dispatch[17].routine = dispatch[18].routine = dispatch[19].routine = (synthRoutine) poly6Mode; /* Filter Env */ dispatch[20].controller = 4; dispatch[20].operator = 0; dispatch[21].controller = 4; dispatch[21].operator = 1; dispatch[22].controller = 4; dispatch[22].operator = 2; dispatch[23].controller = 4; dispatch[23].operator = 3; /* Env */ dispatch[24].controller = 99; /* Will be 6, but interpreted */ dispatch[24].operator = 0; dispatch[25].controller = 99; dispatch[25].operator = 1; dispatch[26].controller = 99; dispatch[26].operator = 2; dispatch[27].controller = 99; dispatch[27].operator = 3; /* VCA NOT DONE */ dispatch[28].controller = 100; dispatch[28].operator = 0; dispatch[29].controller = 101; dispatch[29].operator = 1; dispatch[28].routine = dispatch[29].routine = dispatch[24].routine = dispatch[25].routine = dispatch[26].routine = dispatch[27].routine = (synthRoutine) poly6Gain; /* Effect */ dispatch[30].controller = 100; dispatch[30].operator = 0; dispatch[31].controller = 100; dispatch[31].operator = 1; dispatch[32].controller = 126; dispatch[32].operator = 0; dispatch[MEM_START + 0].controller = 0; dispatch[MEM_START + 1].controller = 1; dispatch[MEM_START + 2].controller = 2; dispatch[MEM_START + 3].controller = 3; dispatch[MEM_START + 4].controller = 4; dispatch[MEM_START + 5].controller = 5; dispatch[MEM_START + 6].controller = 6; dispatch[MEM_START + 7].controller = 7; dispatch[MEM_START + 8].controller = 8; dispatch[MEM_START + 9].controller = 9; dispatch[MEM_START + 10].controller = 10; dispatch[MEM_START + 11].controller = 11; dispatch[MEM_START + 12].controller = 12; dispatch[MEM_START + 13].controller = 13; dispatch[MEM_START + 14].controller = 14; dispatch[MEM_START + 15].controller = 15; dispatch[MEM_START + 16].controller = 16; dispatch[MEM_START + 17].controller = 17; dispatch[MEM_START + 0].routine = dispatch[MEM_START + 1].routine = dispatch[MEM_START + 2].routine = dispatch[MEM_START + 3].routine = dispatch[MEM_START + 4].routine = dispatch[MEM_START + 5].routine = dispatch[MEM_START + 6].routine = dispatch[MEM_START + 7].routine = dispatch[MEM_START + 8].routine = dispatch[MEM_START + 9].routine = dispatch[MEM_START + 10].routine = dispatch[MEM_START + 11].routine = dispatch[MEM_START + 12].routine = dispatch[MEM_START + 13].routine = dispatch[MEM_START + 14].routine = dispatch[MEM_START + 15].routine = dispatch[MEM_START + 16].routine = dispatch[MEM_START + 17].routine = (synthRoutine) poly6Memory; dispatch[RADIOSET_1].other1 = -1; dispatch[RADIOSET_2].other1 = -1; dispatch[RADIOSET_3].other1 = -1; dispatch[MIDI_START].controller = 1; dispatch[MIDI_START + 1].controller = 2; dispatch[MIDI_START].routine = dispatch[MIDI_START + 1].routine = (synthRoutine) poly6Midi; /* Put in diverse defaults settings */ /* Gain on filter env */ bristolMidiSendMsg(global.controlfd, synth->sid, 4, 4, C_RANGE_MIN_1); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 4, 4); /* Waveform subosc */ bristolMidiSendMsg(global.controlfd, synth->sid, 1, 0, C_RANGE_MIN_1); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 6, C_RANGE_MIN_1); /* LFO Env parameters. */ bristolMidiSendMsg(global.controlfd, synth->sid, 8, 1, 12000); bristolMidiSendMsg(global.controlfd, synth->sid, 8, 2, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 8, 3, 0); bristolMidiSendMsg(global.controlfd, synth->sid, 8, 4, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 8, 5, 0); return(0); } /* * This will be called to make any routine specific parameters available. */ static int poly6Configure(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); brightonEvent event; if (synth == 0) { printf("problems going operational\n"); return(-1); } if (synth->flags & OPERATIONAL) return(0); printf("going operational\n"); synth->flags |= OPERATIONAL; synth->keypanel = 1; synth->keypanel2 = -1; synth->transpose = 36; brightonPut(win, "bitmaps/blueprints/poly6shade.xpm", 0, 0, win->width, win->height); width = win->width; if (synth->location == 0) { synth->bank = 10; synth->location = 1; } else { synth->bank = (synth->location % 100) / 10 * 10; synth->location = synth->location % 10; } event.type = BRISTOL_FLOAT; event.value = 1; brightonParamChange(synth->win, synth->panel, MEM_START + synth->bank / 10, &event); brightonParamChange(synth->win, synth->panel, MEM_START+8+synth->location, &event); /* Poly */ brightonParamChange(synth->win, synth->panel, 19, &event); loadMemory(synth, "poly", 0, initmem, synth->mem.active, 0, 0); fixModes(synth, synth->sid, synth->midichannel, 0, 0, 0); /* * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only * occurs on first paint, so we suppress the first paint, and then request * an expose here. */ event.type = BRIGHTON_EXPOSE; event.intvalue = 1; brightonParamChange(synth->win, KEY_PANEL, -1, &event); event.type = BRIGHTON_FLOAT; event.value = 0.1; brightonParamChange(synth->win, 2, 1, &event); configureGlobals(synth); synth->loadMemory = (loadRoutine) poly6loadMemory; return(0); } bristol-0.60.11/brighton/brightonMS20.c0000644000175000017500000010127611746476475014510 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include #include "brighton.h" #include "brightonMini.h" #include "brightoninternals.h" static int ms20Init(); static int ms20Configure(); static int ms20Callback(brightonWindow *, int, int, float); extern guimain global; #include "brightonKeys.h" #define KEY_PANEL 1 #define FIRST_DEV 0 /* 36 controllers, 4 idle, 35 patches, 5 idle, then memory. */ #define DEVICE_COUNT 98 #define ACTIVE_DEVS 79 /* 35 of 40 jack connectors active. */ #define MEM_START (ACTIVE_DEVS + 1) #define MS20_OUTPUTS 20 #define MS20_INPUTS 20 #define OUTPUT_START 40 #define INPUT_START 60 #define DISPLAY1 (DEVICE_COUNT - 2) #define DISPLAY2 (DEVICE_COUNT - 1) #define S1 60 #define S2 74 #define R1 150 #define R2 383 #define R3 616 #define R4 800 #define RD1 ((R4 - R1) / 4) #define RR1 R1 #define RR2 (RR1 + RD1) #define RR3 (RR2 + RD1) #define RR4 (RR3 + RD1) #define RR5 R4 #define CD1 67 #define C1 17 #define C2 (C1 + CD1) #define C3 (C2 + CD1) #define C4 (C3 + CD1 + 1) #define C5 (C4 + CD1 - 1) #define C6 (C5 + CD1 + 1) #define C7 (C6 + CD1) #define C8 (C7 + CD1) #define C9 (C8 + CD1 + 4) #define C10 (C9 + CD1 + 1) #define C11 (C10 + CD1 + 3) #define C12 (C11 + CD1) #define C13 (C12 + CD1) #define C14 (C13 + CD1) static int oselect; static struct { int input; int id; /* From graphical interface. */ } links[MS20_OUTPUTS]; /* * This structure is for device definition. The structure is defined in * include/brighton.h, further definitions in brighton/brightonDevtable.h and * include/brightoninternals.h * * typedef int (*brightonCallback)(int, float); * typedef struct BrightonLocations { * int device; 0=rotary, 1=scale, etc. * float relx, rely; relative position with regards to 1000 by 1000 window * float relw, relh; relative height. * int from, to; * brightonCallback callback; specific to this dev * char *image; bitmap. If zero take a device default. * int flags; * } brightonLocations; * * This example is for a ms20Bristol type synth interface. */ static brightonLocations locations[DEVICE_COUNT] = { /* LFO and control */ {"", 0, C1 - 1, R1 - 12, S2, S2, 0, 3, 0, "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW}, {"", 0, C1, R2 - 30, S1, S1, 0, 1, 0, "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW}, {"", 0, C1 - 1, R3 - 72, S2, S2, 0, 3, 0, "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW}, {"", 0, C1, R4, S1, S1, 0, 1, 0, "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW}, {"", 0, C2 - 5, R1 - 12, S2, S2, 0, 3, 0, "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW}, {"", 0, C2, R2 - 30, S1, S1, 0, 1, 0, "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW}, {"", 0, C2 - 5, R3 - 72, S2, S2, 0, 3, 0, "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW}, {"", 0, C2, R4, S1, S1, 0, 1, 0, "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW}, {"", 0, C3, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW}, {"", 0, C3, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW}, {"", 0, C3, RR4, S1, S1, 0, 1, 0, "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW}, {"", 0, C3, RR5, S1, S1, 0, 1, 0, "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW}, {"", 0, C4 - 3, R1 + 3, S2, S2, 0, 1, 0, "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW}, {"", 0, C4, R2 + 6, S1, S1, 0, 1, 0, "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW}, {"", 0, C4, RR4 + 6, S1, S1, 0, 1, 0, "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW}, {"", 0, C4, RR5 + 6, S1, S1, 0, 1, 0, "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW}, {"", 0, C5 - 3, R1 + 3, S2, S2, 0, 1, 0, "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW}, {"", 0, C5, R2 + 6, S1, S1, 0, 1, 0, "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW}, {"", 0, C5, RR4 + 6, S1, S1, 0, 1, 0, "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW}, {"", 0, C5, RR5 + 6, S1, S1, 0, 1, 0, "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW}, {"", 0, C6, RR4 + 5, S1, S1, 0, 1, 0, "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW}, {"", 0, C6, RR5 + 5, S1, S1, 0, 1, 0, "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW}, {"", 0, C7, RR3 + 5, S1, S1, 0, 1, 0, "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW}, {"", 0, C7, RR4 + 5, S1, S1, 0, 1, 0, "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW}, {"", 0, C7, RR5 + 5, S1, S1, 0, 1, 0, "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW}, {"", 0, C8, RR1 + 5, S1, S1, 0, 1, 0, "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW}, {"", 0, C8, RR2 + 5, S1, S1, 0, 1, 0, "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW}, {"", 0, C8, RR3 + 5, S1, S1, 0, 1, 0, "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW}, {"", 0, C8, RR4 + 5, S1, S1, 0, 1, 0, "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW}, {"", 0, C8, RR5 + 5, S1, S1, 0, 1, 0, "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW}, {"", 0, C9, R4 + 6, S1, S1, 0, 1, 0, "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW}, {"", 0, C10, R4 + 6, S1, S1, 0, 1, 0, "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW}, {"", 0, C11 - 2, R4 + 4, S1, S1, 0, 1, 0, "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW}, {"", 0, C12 - 1, R4 + 2, S1, S1, 0, 1, 0, "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW}, {"", 0, C13, R4, S1, S1, 0, 1, 0, "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW}, {"", 0, C14 + 2, R1 - 30, S2, S2, 0, 1, 0, "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW}, /* Dummies */ {"", 0, C10, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_WITHDRAWN}, {"", 0, C11, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_WITHDRAWN}, {"", 0, C12, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_WITHDRAWN}, {"", 0, C13, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_WITHDRAWN}, /* * First the Outputs. Start with clocks at 40. */ {"", 2, 549, 297, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", BRIGHTON_NOSHADOW}, {"", 2, 627, 297, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", BRIGHTON_NOSHADOW}, /* Env-1 out */ {"", 2, 680, 297, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", BRIGHTON_NOSHADOW}, {"", 2, 680, 401, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", BRIGHTON_NOSHADOW}, /* Env-2 rev out */ {"", 2, 849, 297, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", BRIGHTON_NOSHADOW}, /* KBD CV and TRIG out */ {"", 2, 964, 297, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", BRIGHTON_NOSHADOW}, {"", 2, 964, 401, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", BRIGHTON_NOSHADOW}, /* S&H Out */ {"", 2, 627, 527, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", BRIGHTON_NOSHADOW}, {"", 2, 756, 527, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", BRIGHTON_NOSHADOW}, {"", 2, 798, 527, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", BRIGHTON_NOSHADOW}, {"", 2, 877, 527, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", BRIGHTON_NOSHADOW}, /* Ext Sig Proc outputs */ {"", 2, 627, 690, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", BRIGHTON_NOSHADOW}, {"", 2, 735, 690, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", BRIGHTON_NOSHADOW}, {"", 2, 820, 690, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", BRIGHTON_NOSHADOW}, {"", 2, 923, 690, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", BRIGHTON_NOSHADOW}, {"", 2, 964, 690, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", BRIGHTON_NOSHADOW}, /* Dummies */ {"", 2, 900, 900, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", BRIGHTON_WITHDRAWN}, {"", 2, 900, 900, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", BRIGHTON_WITHDRAWN}, {"", 2, 900, 900, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", BRIGHTON_WITHDRAWN}, {"", 2, 900, 900, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", BRIGHTON_WITHDRAWN}, /* * Then the inputs. The primary is a dummy. I will put in 15 inputs and * 25 outputs, there are 353 in total with some dummies and a couple that * are not active. */ {"", 2, 900, 900, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_WITHDRAWN}, /* The top line */ {"", 2, 549, 180, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, {"", 2, 611, 180, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, {"", 2, 664, 180, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, {"", 2, 725, 180, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, {"", 2, 777, 180, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, {"", 2, 832, 180, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, /* Control and trig */ {"", 2, 735, 401, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, {"", 2, 797, 401, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, /* KBD Control and trig */ {"", 2, 923, 297, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, {"", 2, 923, 401, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, {"", 2, 885, 347, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, /* S&H and its clock, VCA */ {"", 2, 586, 412, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_NOSHADOW}, {"", 2, 549, 527, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, {"", 2, 680, 527, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, /* Wheels */ {"", 2, 923, 527, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, {"", 2, 964, 527, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, /* Sig In */ {"", 2, 549, 690, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, /* Dummy ins */ {"", 2, 900, 900, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_WITHDRAWN}, {"", 2, 900, 900, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_WITHDRAWN}, /* memories */ #define MH1 53 #define MH2 50 #define MW1 11 #define MW2 10 #define MR1 225 #define MR2 308 #define MCD 14 #define MC1 338 #define MC2 (MC1 + MCD) #define MC3 (MC2 + MCD) #define MC4 (MC3 + MCD) #define MC5 (MC4 + MCD) #define MC6 (MC5 + MCD) #define MC7 (MC6 + MCD) #define MC8 (MC7 + MCD + MCD) /* Should be put into parameters, fixed values does not work... */ {"", 2, MC2, MR1, MW1, MH1, 0, 1.01, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, MC3, MR1, MW1, MH1, 0, 1.01, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, MC4, MR1, MW1, MH1, 0, 1.01, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, MC5, MR1, MW1, MH1, 0, 1.01, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, MC6, MR1, MW1, MH1, 0, 1.01, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, MC2, MR2, MW1, MH1, 0, 1.01, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, MC3, MR2, MW1, MH1, 0, 1.01, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, MC4, MR2, MW1, MH1, 0, 1.01, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, MC5, MR2, MW1, MH1, 0, 1.01, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, MC6, MR2, MW1, MH1, 0, 1.01, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, MC1, MR1, MW2, MH2, 0, 1.01, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, MC1, MR2, MW2, MH2, 0, 1.01, 0, "bitmaps/buttons/pressoffo.xpm", "bitmaps/buttons/pressono.xpm", BRIGHTON_CHECKBUTTON}, /* mem up down */ {"", 2, MC7, MR1, MW2, MH2, 0, 1.01, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, MC7, MR2, MW2, MH2, 0, 1.01, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, /* MIDI up down */ {"", 2, MC8, MR1, MW2, MH2, 0, 1.01, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, MC8, MR2, MW2, MH2, 0, 1.01, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, /* displays */ {"", 3, 343, 90, 110, 45, 0, 1, 0, 0, "bitmaps/images/alphadisplay3.xpm", 0}, {"", 3, 343, 132, 110, 45, 0, 1, 0, 0, 0, 0} }; /* * These are new mod controls for the Pro-1. Used here for the MS-20. */ static brightonLocations newmods[2] = { {"", BRIGHTON_MODWHEEL, 280, 180, 140, 550, 0, 1, 0, "bitmaps/knobs/modwheel.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE|BRIGHTON_NOSHADOW|BRIGHTON_CENTER|BRIGHTON_NOTCH}, {"", BRIGHTON_MODWHEEL, 620, 180, 140, 550, 0, 1, 0, "bitmaps/knobs/modwheel.xpm", 0, BRIGHTON_REVERSE|BRIGHTON_HSCALE|BRIGHTON_NOSHADOW}, }; /* * This is a set of globals for the main window rendering. Again taken from * include/brighton.h */ brightonApp ms20App = { "ms20", 0, "bitmaps/textures/metal7.xpm", BRIGHTON_STRETCH|BRIGHTON_REVERSE, /* default is tesselate */ ms20Init, ms20Configure, /* 3 callbacks, unused? */ 0, destroySynth, {1, 100, 2, 2, 5, 520, 0, 0}, 865, 440, 0, 0, 5, /* one panel only */ { { "ms-20", "bitmaps/blueprints/ms20.xpm", "bitmaps/textures/metal6.xpm", BRIGHTON_STRETCH|BRIGHTON_REVERSE, /* flags */ 0, ms20Configure, ms20Callback, 12, 25, 980, 677, DEVICE_COUNT, locations }, { "Keyboard", 0, "bitmaps/newkeys/ekbg.xpm", /* flags */ 0x020|BRIGHTON_STRETCH, 0, 0, keyCallback, 140, 700, 840, 300, KEY_COUNT_3OCTAVE, keys3octave }, { "Mods", 0, //"bitmaps/blueprints/mods.xpm", "bitmaps/textures/metal7.xpm", /* flags */ BRIGHTON_STRETCH, 0, 0, modCallback, 12, 700, 128, 300, 2, newmods }, { "SP1", 0, "bitmaps/images/rhodes.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 0, 0, 12, 1000, 0, 0 }, { "SP2", 0, "bitmaps/images/rhodes.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 988, 0, 12, 1000, 0, 0 }, } }; /*static dispatcher dispatch[DEVICE_COUNT]; */ static int ms20MidiSendMsg(void *synth, int fd, int chan, int c, int o, int v) { bristolMidiSendMsg(fd, chan, c, o, v); return(0); } static int ms20Memory(guiSynth *synth, int fd, int chan, int c, int o, int v) { /* printf("ms20Memory(%i %i %i %i %i)\n", fd, chan, c, o, v); */ if (synth->flags & MEM_LOADING) return(0); if ((synth->flags & OPERATIONAL) == 0) return(0); if (synth->dispatch[MEM_START].other2) { synth->dispatch[MEM_START].other2 = 0; return(0); } switch (c) { default: case 0: if (synth->dispatch[MEM_START].other1 != -1) { brightonEvent event; synth->dispatch[MEM_START].other2 = 1; if (synth->dispatch[MEM_START].other1 != c) event.value = 0; else event.value = 1; brightonParamChange(synth->win, synth->panel, synth->dispatch[MEM_START].other1, &event); } synth->dispatch[MEM_START].other1 = c; synth->location = synth->location * 10 + o; if (synth->location >= 1000) synth->location = o; if (loadMemory(synth, "ms20", 0, synth->location, synth->mem.active, FIRST_DEV, BRISTOL_STAT) < 0) displayText(synth, "FRE", synth->location, DISPLAY1); else displayText(synth, "PRG", synth->location, DISPLAY1); break; case 1: if (loadMemory(synth, "ms20", 0, synth->location, synth->mem.active, FIRST_DEV, 0) < 0) displayText(synth, "FRE", synth->location, DISPLAY2); else displayText(synth, "PRG", synth->location, DISPLAY2); /* synth->location = 0; */ break; case 2: saveMemory(synth, "ms20", 0, synth->location, FIRST_DEV); displayText(synth, "PRG", synth->location, DISPLAY2); /* synth->location = 0; */ break; case 3: while (loadMemory(synth, "ms20", 0, ++synth->location, synth->mem.active, FIRST_DEV, 0) < 0) { if (synth->location > 999) synth->location = -1; } displayText(synth, "PRG", synth->location, DISPLAY2); break; case 4: while (loadMemory(synth, "ms20", 0, --synth->location, synth->mem.active, FIRST_DEV, 0) < 0) { if (synth->location < 0) synth->location = 999; } displayText(synth, "PRG", synth->location, DISPLAY2); break; } return(0); } /* * For the sake of ease of use, links have been placed here to be called * by any of the devices created. They would be better in some other file, * perhaps with this as a dispatch. * * Param refers to the device index in the locations table given below. */ static int ms20Callback(brightonWindow * win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); int sendvalue; /* printf("ms20Callback(%i, %i, %f): %i %x\n", panel, index, value, synth); */ if (synth == 0) return(0); if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0)) return(0); if (index >= DEVICE_COUNT) return(0); if (ms20App.resources[0].devlocn[index].to == 1.0) sendvalue = value * (CONTROLLER_RANGE - 1); else sendvalue = value; synth->mem.param[index] = value; /* if ((!global.libtest) || (index >= ACTIVE_DEVS)) */ if ((!global.libtest) || (index >= 40)) synth->dispatch[index].routine(synth, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); else printf("dispatch[%p,%i](%i, %i, %i, %i, %i)\n", synth, index, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); return(0); } static void ms20Midi(guiSynth *synth, int fd, int chan, int c, int o, int v) { printf("ms20Midi(%i %i %i %i %i)\n", fd, chan, c, o, v); if ((synth->flags & OPERATIONAL) == 0) return; if (synth->dispatch[MEM_START + 14].other1 == MEM_START + 14) { int newchan; if (c == 1) { if ((newchan = synth->midichannel - 1) < 0) { synth->midichannel = 0; return; } } else { if ((newchan = synth->midichannel + 1) >= 16) { synth->midichannel = 15; return; } } if (global.libtest == 0) { bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_MIDICHANNEL|newchan); } synth->midichannel = newchan; displayText(synth, "CHAN", synth->midichannel + 1, DISPLAY1); } else { if (c == 1) { while (locations[--synth->dispatch[MEM_START + 15].other2].name[0] == '\0') { if (synth->dispatch[MEM_START + 15].other2 < 0) synth->dispatch[MEM_START + 15].other2 = 49; } } else { while (locations[++synth->dispatch[MEM_START + 15].other2].name[0] == '\0') { if (synth->dispatch[MEM_START + 15].other2 >= 49) synth->dispatch[MEM_START + 15].other2 = 0; } } displayText(synth, locations[synth->dispatch[MEM_START + 15].other2].name, synth->dispatch[MEM_START + 15].other2, DISPLAY2); if (synth->dispatch[MEM_START + 15].other1 == 1) { /*printf("PANEL X SELECTOR %i %i = %i %i\n", */ /*synth->dispatch[MEM_START + 15].other1, */ /*synth->dispatch[MEM_START + 15].other2, */ /*synth->dispatch[synth->dispatch[MEM_START + 15].other2].controller, */ /*synth->dispatch[synth->dispatch[MEM_START + 15].other2].operator); */ synth->dispatch[54].controller = synth->dispatch[ synth->dispatch[MEM_START + 15].other2].controller; synth->dispatch[54].operator = synth->dispatch[ synth->dispatch[MEM_START + 15].other2].operator; } else { /*printf("PANEL Y SELECTOR %i %i = %i %i\n", */ /*synth->dispatch[MEM_START + 15].other1, */ /*synth->dispatch[MEM_START + 15].other2, */ /*synth->dispatch[synth->dispatch[MEM_START + 15].other2].controller, */ /*synth->dispatch[synth->dispatch[MEM_START + 15].other2].operator); */ synth->dispatch[55].controller = synth->dispatch[ synth->dispatch[MEM_START + 15].other2].controller; synth->dispatch[55].operator = synth->dispatch[ synth->dispatch[MEM_START + 15].other2].operator; } } } static void ms20PanelSelect(guiSynth *synth, int fd, int chan, int c, int o, int v) { /* printf("ms20PanelSelect(%x, %i, %i, %i, %i, %i\n", */ /* synth, fd, chan, c, o, v); */ /* dispatch[MEM_START + 14] = dispatch[MEM_START + 15] */ if (synth->dispatch[MEM_START + 14].other2) { synth->dispatch[MEM_START + 14].other2 = 0; return; } if (synth->dispatch[MEM_START + 14].other1 != -1) { brightonEvent event; synth->dispatch[MEM_START + 14].other2 = 1; if (synth->dispatch[MEM_START + 14].other1 != c) event.value = 0; else event.value = 1; brightonParamChange(synth->win, synth->panel, synth->dispatch[MEM_START + 14].other1, &event); } displayText(synth, "CHAN", synth->midichannel + 1, DISPLAY1); if (c == MEM_START + 15) { if (synth->dispatch[MEM_START + 15].other1 > 1) synth->dispatch[MEM_START + 15].other1 = 0; switch (synth->dispatch[MEM_START + 15].other1) { case 0: default: displayText(synth, "PAN-X", synth->dispatch[MEM_START + 15].other2, DISPLAY1); break; case 1: displayText(synth, "PAN-Y", synth->dispatch[MEM_START + 15].other2, DISPLAY1); break; } synth->dispatch[MEM_START + 15].other1++; } synth->dispatch[MEM_START + 14].other1 = c; } static void ms20IOSelect(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; /* printf("ms20IOSelect(%i, %i, %i)\n", c, o, v); */ if ((synth->flags & OPERATIONAL) == 0) return; event.command = BRIGHTON_PARAMCHANGE; /* * We have quite a lot of work here, we need to mark any output that is * selected, if an input is selected then we should mark active the previous * output to link them up and draw the desired layer item. We should keep * all this in some structure such that it can be deconfigured, ie, patches * can be removed. * * The structure we need should have an input and output list, this should * give the true co-ords for the start and endpoint since it will be used * to evaluate the transforms for the patch source to the on-screen dest * bitmaps. * * There should also be a sanity check that clears any wayward output * selections, required before saveMemory() can be called. * * We will probably need a selection of bitmaps so that we can simplify * the stretch algorithm. If we only have one bitmaps then we need a more * complex transform since the end points should not be stretched, only * the intermittant cabling: * cable source is 146bits, 3 for each end. * Target length is 725 for example * the 3 start and end pixels get copied, * the middle 140 bits must be scaled to 719. * The result should then be rotated into position. */ if (c == 1) { if (v > 0) oselect = o; else oselect = -1; /* * If we select an output that is assigned then clear it. */ if (links[o].input > 0) { bristolMidiSendMsg(global.controlfd, synth->sid, 101, o, links[o].input); links[o].input = 0; event.type = BRIGHTON_UNLINK; event.intvalue = links[o].id; brightonParamChange(synth->win, 0, OUTPUT_START + o, &event); } } else if (c == 2) { int i; if (oselect >= 0) { for (i = 0; i < MS20_OUTPUTS; i++) { if ((links[i].input > 0) && (links[i].input == o)) { int hold; /* event.intvalue = links[i].id; */ /* event.type = BRIGHTON_UNLINK; */ /* brightonParamChange(synth->win, 0, OUTPUT_START+ i, &event); */ hold = oselect; event.type = BRIGHTON_PARAMCHANGE; event.value = 0; brightonParamChange(synth->win, 0, OUTPUT_START+ i, &event); oselect = hold; } } synth->mem.param[OUTPUT_START + oselect] = o; links[oselect].input = o; /* * Need to request the drawing of a link. We need to send a message * that the library will interpret as a connection request. * All we have is brighton param change. We should consider sending * one message with each key click on an output, and another on * each input - this is the only way we can get two panel numbers * across, something we will eventually require. brightonParamChange(synth->win, 1, INPUT_START + oselect, &event); */ bristolMidiSendMsg(global.controlfd, synth->sid, 100, oselect, o); event.type = BRIGHTON_LINK; event.intvalue = INPUT_START + o; links[oselect].id = brightonParamChange(synth->win, 0, OUTPUT_START + oselect, &event); } else { /* * See if this input is connected, if so clear it. */ for (i = 0; i < MS20_OUTPUTS; i++) { if ((links[i].input > 0) && (links[i].input == o)) { /* * What I need to do is send an event to the output device * turning it off. */ event.type = BRIGHTON_PARAMCHANGE; event.value = 0; brightonParamChange(synth->win, 0, OUTPUT_START+i, &event); } } } oselect = -1; } } /* * Any location initialisation required to run the callbacks. For bristol, this * will connect to the engine, and give it some base parameters. * May need to generate some application specific menus. * Will also then make specific requests to some of the devices to alter their * rendering. */ static int ms20Init(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); dispatcher *dispatch; int i; if (synth == 0) { synth = findSynth(global.synths, 0); if (synth == 0) { printf("cannot init\n"); return(0); } } synth->win = win; printf("Initialise the ms20 link to bristol: %p\n", synth->win); synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float)); synth->mem.count = DEVICE_COUNT; synth->mem.active = ACTIVE_DEVS; synth->dispatch = (dispatcher *) brightonmalloc(DEVICE_COUNT * sizeof(dispatcher)); dispatch = synth->dispatch; /* * We really want to have three connection mechanisms. These should be * 1. Unix named sockets. * 2. UDP sockets. * 3. MIDI pipe. */ if (!global.libtest) if ((synth->sid = initConnection(&global, synth)) < 0) return(-1); /* for (i = 0; i < DEVICE_COUNT; i++) */ /* synth->dispatch[i].routine = ms20MidiSendMsg; */ for (i = 0; i < DEVICE_COUNT; i++) { /* * This sets up the input and output code. */ if (i >= MEM_START) { synth->dispatch[i].controller = 0; } else if (i >= INPUT_START) { /* Inputs */ synth->dispatch[i].controller = 2; synth->dispatch[i].operator = i - INPUT_START; synth->dispatch[i].routine = (synthRoutine) ms20IOSelect; } else if (i >= OUTPUT_START) { /* Outputs */ synth->dispatch[i].controller = 1; synth->dispatch[i].operator = i - OUTPUT_START; synth->dispatch[i].routine = (synthRoutine) ms20IOSelect; } else synth->dispatch[i].routine = ms20MidiSendMsg; } /* memory */ dispatch[MEM_START].operator = 0; dispatch[MEM_START].controller = MEM_START; dispatch[MEM_START + 1].operator = 1; dispatch[MEM_START + 1].controller = MEM_START + 1; dispatch[MEM_START + 2].operator = 2; dispatch[MEM_START + 2].controller = MEM_START + 2; dispatch[MEM_START + 3].operator = 3; dispatch[MEM_START + 3].controller = MEM_START + 3; dispatch[MEM_START + 4].operator = 4; dispatch[MEM_START + 4].controller = MEM_START + 4; dispatch[MEM_START + 5].operator = 5; dispatch[MEM_START + 5].controller = MEM_START + 5; dispatch[MEM_START + 6].operator = 6; dispatch[MEM_START + 6].controller = MEM_START + 6; dispatch[MEM_START + 7].operator = 7; dispatch[MEM_START + 7].controller = MEM_START + 7; dispatch[MEM_START + 8].operator = 8; dispatch[MEM_START + 8].controller = MEM_START + 8; dispatch[MEM_START + 9].operator = 9; dispatch[MEM_START + 9].controller = MEM_START + 9; dispatch[MEM_START + 10].controller = 1; dispatch[MEM_START + 11].controller = 2; dispatch[MEM_START + 16].controller = 3; dispatch[MEM_START + 17].controller = 4; dispatch[MEM_START + 0].routine = dispatch[MEM_START + 1].routine = dispatch[MEM_START + 2].routine = dispatch[MEM_START + 3].routine = dispatch[MEM_START + 4].routine = dispatch[MEM_START + 5].routine = dispatch[MEM_START + 6].routine = dispatch[MEM_START + 7].routine = dispatch[MEM_START + 8].routine = dispatch[MEM_START + 9].routine = dispatch[MEM_START + 10].routine = dispatch[MEM_START + 11].routine = dispatch[MEM_START + 16].routine = dispatch[MEM_START + 17].routine = (synthRoutine) ms20Memory; /* midi */ dispatch[MEM_START + 12].controller = 2; dispatch[MEM_START + 13].controller = 1; dispatch[MEM_START + 12].routine = dispatch[MEM_START + 13].routine = (synthRoutine) ms20Midi; /* midi/panel selectors */ dispatch[MEM_START + 14].controller = MEM_START + 14; dispatch[MEM_START + 15].controller = MEM_START + 15; dispatch[MEM_START + 14].routine = dispatch[MEM_START + 15].routine = (synthRoutine) ms20PanelSelect; return(0); } /* * This will be called to make any routine specific parameters available. */ static int ms20Configure(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); brightonEvent event; if (synth == 0) { printf("problems going operational\n"); return(-1); } if (synth->flags & OPERATIONAL) return(0); printf("going operational\n"); synth->flags |= OPERATIONAL; synth->keypanel = 1; synth->keypanel2 = -1; synth->transpose = 36; displayText(synth, "CHAN", synth->midichannel + 1, DISPLAY1); loadMemory(synth, "ms20", 0, synth->location, synth->mem.active, FIRST_DEV, 0); displayText(synth, "PRG", synth->location, DISPLAY2); brightonPut(win, "bitmaps/blueprints/ms20shade.xpm", 0, 0, win->width, win->height); /* * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only * occurs on first paint, so we suppress the first paint then request * an expose here. */ event.type = BRIGHTON_EXPOSE; event.intvalue = 1; brightonParamChange(synth->win, KEY_PANEL, -1, &event); return(0); } bristol-0.60.11/brighton/brightonBME700.c0000644000175000017500000011365011746476475014660 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* * Mods: * * LFO sync, Multi each 4 - 4 switches * Osc detune and ramp 2, multithread option - 2 knob 1 switch * Noise pink/multi - switch knob * Envelope velocity, retrig, gain both 6 - 4 switches 2 knob * Resonance res and mix high/low 4 (algo select for each?) 4 knob * Filter mix, kbd tracking? 2 knob * * More signal into the filters, less out DONE * Multiplying mods * LFO/Env gain gives droning, mono mode * Oscillator is dull SOME - multiple strands * Load opts only once, or when double click load button DONE * * Remixed oscillators are also pretty dull, the only net effect appears to be * a volume gain. Rework the code for add/subtract of different poles and/or * add/sub different remix poles also. */ #include #include "brighton.h" #include "brightonMini.h" #include "brightoninternals.h" static int BME700Init(); static int BME700Configure(); static int BME700Callback(brightonWindow *, int, int, float); static int BME700ModCallback(brightonWindow *, int, int, float); static int midiCallback(brightonWindow *, int, int, float); static int BME700KeyCallback(brightonWindow *, int, int, float); extern guimain global; #include "brightonKeys.h" #define SYNTH_NAME synth->resources->name #define OPTS_START 43 #define OPTS_COUNT 32 #define ACTIVE_DEVS (OPTS_START + OPTS_COUNT) #define MEM_MGT ACTIVE_DEVS #define MIDI_MGT (MEM_MGT + 12) #define MODS_COUNT 12 #define DEVICE_COUNT (ACTIVE_DEVS + 2) #define KEY_PANEL 1 #define MODS_PANEL 2 #define DISPLAY_DEV (OPTS_COUNT - 6) static int dc; static int shade_id; /* * This structure is for device definition. The structure is defined in * include/brighton.h, further definitions in brighton/brightonDevtable.h and * include/brightoninternals.h * * typedef int (*brightonCallback)(int, float); * typedef struct BrightonLocations { * int device; 0=rotary, 1=scale, etc. * float relx, rely; relative position with regards to 1000 by 1000 window * float relw, relh; relative height. * int from, to; * brightonCallback callback; specific to this dev * char *image; bitmap. If zero take a device default. * int flags; * } brightonLocations; * * This example is for a BME700Bristol type synth interface. */ #define SPW 50 #define SPH 110 #define R1 110 #define R1b (R1 + SPH / 4) #define R2 330 #define R2b (R2 + SPH / 4) #define R3 575 #define R3b (R3 + SPH / 4) #define R4 795 #define R4b (R4 + SPH / 4) #define D1 65 #define C1 36 #define C1b (C1 + SPW/3) #define C2 (C1 + D1) #define C2b (C2 + D1 / 2) #define C3 (C2 + D1) #define C3b (C3 + SPW/3) #define C4 (C3 + D1) #define C4b (C4 + SPW/3) #define C10 401 #define C10b (C10 + SPW/3) #define C20 570 #define C20b (C20 + SPW/3) #define C21 (C20 + D1) #define C21b (C21 + SPW/3) #define C22 (C21 + D1) #define C30 810 #define C30b (C30 + SPW/3) #define C31 (C30 + D1) #define C32 (C31 + D1) static brightonLocations locations[DEVICE_COUNT] = { /* 0 */ {"Mod1 Tri/Square", 2, C1b, R1b, 10, 60, 0, 1.01, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, {"Mod1 Rate", 0, C2, R1, SPW, SPH, 0, 1, 0, "bitmaps/knobs/yellowknob.xpm", 0, 0}, {"Mod2 Rate", 0, C3, R1, SPW, SPH, 0, 1, 0, "bitmaps/knobs/yellowknob.xpm", 0, 0}, {"Mod2 Tri/Square", 2, C4b, R1b, 10, 60, 0, 1.01, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, /* 4 */ {"Mod1/Env", 2, C1b + 35, R2b, 10, 60, 0, 1.01, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, {"ModMix", 0, C2b, R2, SPW, SPH, 0, 1, 0,"bitmaps/knobs/yellowknob.xpm", 0, 0}, {"Single/Double", 2, C4, R2b, 10, 60, 0, 1.01, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, {"Tri/Square", 2, C4b + 12, R2b, 10, 60, 0, 1.01, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, /* 8 */ {"VCO Glide", 0, C1, R3, SPW, SPH, 0, 1, 0, "bitmaps/knobs/yellowknob.xpm", 0, 0}, {"VCO PW", 0, C2, R3, SPW, SPH, 0, 1, 0, "bitmaps/knobs/yellowknob.xpm", 0, 0}, {"VCO Vibrato", 0, C3, R3, SPW, SPH, 0, 1, 0, "bitmaps/knobs/yellowknob.xpm", 0, 0}, {"VCO Shape", 0, C3, R4, SPW, SPH, 0, 1, 0, "bitmaps/knobs/yellowknob.xpm", 0, 0}, {"Glide On/Off", 2, C1b, R4b, 10, 60, 0, 1.01, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, {"PW Man/Auto", 2, C2 - 1, R4b, 10, 60, 0, 1.01, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, {"PW Env/Mod", 2, C2b, R4b, 10, 60, 0, 1.01, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, {"VCO 8'", 2, C4, R4b, 10, 60, 0, 1.01, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, {"VCO 16'/4'", 2, C4b + 12, R4b, 10, 60, 0, 1.01, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, /* 17 */ {"Mix Noise/VCO", 0, C10, R1, SPW, SPH, 0, 1, 0,"bitmaps/knobs/yellowknob.xpm", 0, 0}, {"Res #/b", 2, C10b, R3b, 10, 60, 0, 1.01, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, /* 19 */ {"Res 1", 2, C10b - 60, R4b, 10, 60, 0, 1.01, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, {"Res 2", 2, C10b - 30, R4b, 10, 60, 0, 1.01, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, {"Res 4", 2, C10b, R4b, 10, 60, 0, 1.01, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, {"Res 8", 2, C10b + 30, R4b, 10, 60, 0, 1.01, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, {"Res 16", 2, C10b + 60, R4b, 10, 60, 0, 1.01, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, /* 24 */ {"Env1 ASR/AR", 2, C20b, R1b, 10, 60, 0, 1.01, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, {"Attack", 0, C21, R1, SPW, SPH, 0, 1, 0,"bitmaps/knobs/yellowknob.xpm", 0, 0}, {"Decay", 0, C22, R1, SPW, SPH, 0, 1, 0,"bitmaps/knobs/yellowknob.xpm", 0, 0}, {"Env2 ASR/AR", 2, C30b, R1b, 10, 60, 0, 1.01, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, {"Attack", 0, C31, R1, SPW, SPH, 0, 1, 0,"bitmaps/knobs/yellowknob.xpm", 0, 0}, {"Decay", 0, C32, R1, SPW, SPH, 0, 1, 0,"bitmaps/knobs/yellowknob.xpm", 0, 0}, /* 30 */ {"VCF Env Mix", 0, C21, R2, SPW, SPH, 0, 1, 0,"bitmaps/knobs/yellowknob.xpm", 0, 0}, {"VCA Env Mix", 0, C31, R2, SPW, SPH, 0, 1, 0,"bitmaps/knobs/yellowknob.xpm", 0, 0}, /* 32 */ {"Filt Resonace", 0, C20, R3, SPW, SPH, 0, 1, 0,"bitmaps/knobs/yellowknob.xpm", 0, 0}, {"Filt Cutoff", 0, C21, R3, SPW, SPH, 0, 1, 0,"bitmaps/knobs/yellowknob.xpm", 0, 0}, {"Filt Env", 0, C22, R3, SPW, SPH, 0, 1, 0,"bitmaps/knobs/yellowknob.xpm", 0, 0}, {"Filt ModMix", 0, C22, R4, SPW, SPH, 0, 1, 0,"bitmaps/knobs/yellowknob.xpm", 0, 0}, {"F-Mod Tri/Sqr", 2, C20b, R4b, 10, 60, 0, 1.01, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, {"F-Mod1/Mod2", 2, C21 - 7, R4b, 10, 60, 0, 1.01, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, {"F-KBD/Mod", 2, C21b + 12, R4b, 10, 60, 0, 1.01, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, /* 39 */ {"Mix VCF/Res", 0, C30, R3, SPW, SPH, 0, 1, 0,"bitmaps/knobs/yellowknob.xpm", 0, 0}, {"VCA ModMix", 0, C32, R3, SPW, SPH, 0, 1, 0,"bitmaps/knobs/yellowknob.xpm", 0, 0}, {"VCA Mod Mod1/Mod2", 2, C30b + 36, R4b, 10, 60, 0, 1.01, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, {"VCA Mod Tri/Sqr", 2, C30b + 101, R4b, 10, 60, 0, 1.01, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, /* 43 - 32 dummies masking opts */ {"", 0, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, /* 59 Tuning, moved out of active devs */ {"Tuning", 0, C4, R3, SPW, SPH, 0, 1, 0, "bitmaps/knobs/yellowknob.xpm", 0, BRIGHTON_NOTCH}, /* 60 Global volume, moved out of active devs */ {"Volume", 0, C31, R3, SPW, SPH, 0, 1, 0,"bitmaps/knobs/yellowknob.xpm", 0, 0}, /* Done */ }; /* * Memory panel, keep it simple - 8 memories, load save, up, down. Uses cs80 backlit buttons */ static brightonLocations bme700mods[MODS_COUNT] = { /* LOAD */ {"", 2, 190, 700, 100, 100, 0, 1, 0, "bitmaps/buttons/touchnlo.xpm", "bitmaps/buttons/touchnlO.xpm", BRIGHTON_CHECKBUTTON}, /* MEMORY SELECT */ {"", 2, 190, 200, 100, 100, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlW.xpm", 0}, {"", 2, 390, 200, 100, 100, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlW.xpm", 0}, {"", 2, 590, 200, 100, 100, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlW.xpm", 0}, {"", 2, 790, 200, 100, 100, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlW.xpm", 0}, {"", 2, 190, 450, 100, 100, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlW.xpm", 0}, {"", 2, 390, 450, 100, 100, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlW.xpm", 0}, {"", 2, 590, 450, 100, 100, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlW.xpm", 0}, {"", 2, 790, 450, 100, 100, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlW.xpm", 0}, /* SAVE */ {"", 2, 390, 700, 100, 100, 0, 1, 0, "bitmaps/buttons/touchnlr.xpm", "bitmaps/buttons/touchnlR.xpm", BRIGHTON_CHECKBUTTON}, /* * UP/DOWN was memory but could be midi channel. Withdrawn for now since I want to keep * this panel uncluttered */ {"", 2, 590, 700, 100, 100, 0, 1, 0, "bitmaps/buttons/touchnlg.xpm", "bitmaps/buttons/touchnlG.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 790, 700, 100, 100, 0, 1, 0, "bitmaps/buttons/touchnlo.xpm", "bitmaps/buttons/touchnlO.xpm", 0}, }; static brightonLocations bme700opts[OPTS_COUNT] = { {"", 2, C1b, R1b, 10, 60, 0, 1.00, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, {"", 2, C1b + 50, R1b, 10, 60, 0, 1.0, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, {"", 2, C4b - 50, R1b, 10, 60, 0, 1.0, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, {"", 2, C4b, R1b, 10, 60, 0, 1.00, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, {"", 0, 0, 0, SPW, SPH, 0, 1, 0, "bitmaps/knobs/yellowknob.xpm", 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, C2, R3, SPW, SPH, 0, 1, 0, "bitmaps/knobs/yellowknob.xpm", 0, 0}, {"", 2, C1b, R3b, 10, 60, 0, 1.00, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, /* Noise Pink + filter */ {"", 2, C10-5, R1b, 10, 60, 0, 1.00, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, {"", 0, C10+40, R1, SPW, SPH, 0, 1, 0,"bitmaps/knobs/yellowknob.xpm", 0, 0}, {"", 0, C10-40, R3, SPW, SPH, 0, 1, 0,"bitmaps/knobs/yellowknob.xpm", 0, 0}, {"", 0, C10+40, R3, SPW, SPH, 0, 1, 0,"bitmaps/knobs/yellowknob.xpm", 0, 0}, {"", 0, C10-40, R4, SPW, SPH, 0, 1, 0,"bitmaps/knobs/yellowknob.xpm", 0, 0}, {"", 0, C10+40, R4, SPW, SPH, 0, 1, 0,"bitmaps/knobs/yellowknob.xpm", 0, 0}, {"", 2, C20b, R1b, 10, 60, 0, 1.00, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, {"", 2, C21+12, R1b, 10, 60, 0, 1.00, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, {"", 0, C22, R1, SPW, SPH, 0, 1, 0,"bitmaps/knobs/yellowknob.xpm", 0, 0}, {"", 2, C30b, R1b, 10, 60, 0, 1.00, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, {"", 2, C31+12, R1b, 10, 60, 0, 1.00, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, {"", 0, C32, R1, SPW, SPH, 0, 1, 0,"bitmaps/knobs/yellowknob.xpm", 0, 0}, {"", 0, C20, R3, SPW, SPH, 0, 1, 0,"bitmaps/knobs/yellowknob.xpm", 0, 0}, {"", 0, C21, R3, SPW, SPH, 0, 1, 0,"bitmaps/knobs/yellowknob.xpm", 0, 0}, /* Noise Multi */ {"", 2, C10-45, R1b, 10, 60, 0, 1.00, 0, "bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL}, {"", 0, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, }; /* * This is a set of globals for the main window rendering. Again taken from * include/brighton.h */ brightonApp bme700App = { "BME700", 0, /* no blueprint on wood background. */ "bitmaps/textures/metal6.xpm", BRIGHTON_STRETCH, BME700Init, BME700Configure, /* 3 callbacks, unused? */ midiCallback, destroySynth, {1, 100, 2, 2, 5, 520, 0, 0}, 800, 417, 0, 0, 7, { { "Bme700", "bitmaps/blueprints/BME700.xpm", "bitmaps/textures/metal5.xpm", 0, /* flags */ 0, 0, BME700Callback, 22, 0, 956, 600, DEVICE_COUNT, locations }, { "Keyboard", 0, "bitmaps/newkeys/tkbg.xpm", 0x020|BRIGHTON_STRETCH, 0, 0, BME700KeyCallback, 172, 600, 800, 350, KEY_COUNT_3_OCTAVE, keys3_octave }, { "Bme700Mods", "bitmaps/blueprints/BME700mods.xpm", "bitmaps/textures/bme700bg.xpm", BRIGHTON_STRETCH, /* flags */ 0, 0, BME700ModCallback, 22, 600, 150, 350, MODS_COUNT, bme700mods }, { "Bme700Opts", "bitmaps/blueprints/BME700opts.xpm", "bitmaps/textures/metal5.xpm", BRIGHTON_WITHDRAWN, /* flags */ 0, 0, BME700Callback, 22, 0, 956, 600, OPTS_COUNT, bme700opts }, { "SP2", 0, "bitmaps/textures/wood.xpm", BRIGHTON_STRETCH, /* flags */ 0, 0, 0, 23, 955, 954, 44, 0, 0 }, { "SP2", 0, "bitmaps/textures/wood.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 0, 0, 22, 1000, 0, 0 }, { "SP2", 0, "bitmaps/textures/wood.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 978, 0, 22, 1000, 0, 0 }, } }; /* * We really want to just use one midi channel and let the midi library decide * that we have multiple synths on the channel with their own split points. * The lower layer should define the midi channel, split point and transpose * of upper layer. */ static int BME700KeyCallback(brightonWindow *win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); if (global.libtest) return(0); /* * So we have a single key event and two MIDI channels. Just send the * event on both channels, no need to be difficult about it since if this * was a split configuration the library filters out the events. */ if (value) { bristolMidiSendMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_KEYON, 0, index + synth->transpose); } else { bristolMidiSendMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_KEYOFF, 0, index + synth->transpose); } return(0); } static void optsShim(guiSynth *synth) { int i; brightonEvent event; event.type = BRISTOL_FLOAT; for (i = 0; i < OPTS_COUNT; i++) { event.value = synth->mem.param[i + OPTS_START]; brightonParamChange(synth->win, 3, i, &event); } } static void panelSwitch(brightonWindow *win, guiSynth *synth, float value) { brightonEvent event; /* * If the sendvalue is zero, then withdraw the opts window, draw the * slider window, and vice versa. */ if (value == 0) { event.type = BRIGHTON_EXPOSE; event.intvalue = 0; brightonParamChange(synth->win, 3, -1, &event); event.intvalue = 1; brightonParamChange(synth->win, 0, -1, &event); shade_id = brightonPut(synth->win, "bitmaps/blueprints/BME700shade.xpm", 0, 0, synth->win->width, synth->win->height); } else { event.type = BRIGHTON_EXPOSE; event.intvalue = 0; brightonParamChange(synth->win, 0, -1, &event); event.intvalue = 1; brightonParamChange(synth->win, 3, -1, &event); brightonRemove(synth->win, shade_id); } } static int midiCallback(brightonWindow *win, int controller, int value, float n) { guiSynth *synth = findSynth(global.synths, win); switch(controller) { case MIDI_PROGRAM: if (synth->mem.param[87] == 0) return(0); /* * We should accept 0..74 as lower layer and above that as dual * loading requests. */ printf("midi program: %x, %i\n", controller, value); synth->location = value; loadMemory(synth, SYNTH_NAME, 0, synth->bank + synth->location, OPTS_START, 0, BRISTOL_FORCE); optsShim(synth); break; case MIDI_BANK_SELECT: printf("midi banksel: %x, %i\n", controller, value); synth->bank = value; synth->location = value; loadMemory(synth, SYNTH_NAME, 0, synth->bank + synth->location, OPTS_START, 0, BRISTOL_FORCE); break; } return(0); } static void BME700MidiShim(guiSynth *synth, int fd, int chan, int c, int o, int v) { bristolMidiSendMsg(fd, synth->sid, c, o, v); } static int BME700ModCallback(brightonWindow *win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); brightonEvent event; int start = synth->location; if (global.libtest) printf("BME700ModCallback(%i, %f)\n", index, value); if (synth->dispatch[ACTIVE_DEVS].other2) { synth->dispatch[ACTIVE_DEVS].other2 = 0; return(0); } switch (index) { case 0: /* Load */ if (brightonDoubleClick(dc) != 0) { loadMemory(synth, SYNTH_NAME, 0, synth->bank + synth->location, synth->mem.active, 0, BRISTOL_FORCE); optsShim(synth); } else printf("%i %i\n", synth->bank, synth->location); loadMemory(synth, SYNTH_NAME, 0, synth->bank + synth->location, OPTS_START, 0, BRISTOL_FORCE); break; case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: /* * Radiobutton memory selectors, doubleclick should load */ if (synth->dispatch[ACTIVE_DEVS].other1 != -1) { synth->dispatch[ACTIVE_DEVS].other2 = 1; if (synth->dispatch[ACTIVE_DEVS].other1 != index) event.value = 0; else event.value = 1; brightonParamChange(synth->win, panel, synth->dispatch[ACTIVE_DEVS].other1, &event); } synth->dispatch[ACTIVE_DEVS].other1 = index; synth->location = index; if (brightonDoubleClick(dc) != 0) { loadMemory(synth, SYNTH_NAME, 0, synth->bank + synth->location, OPTS_START, 0, BRISTOL_FORCE); /* optsShim(synth); */ } break; case 9: /* * Save on doubleclick */ if (brightonDoubleClick(dc) != 0) saveMemory(synth, SYNTH_NAME, 0, synth->bank + synth->location, 0); break; case 10: /* * Up */ while (++synth->location != start) { if (synth->location > 8) synth->location = 1; if (loadMemory(synth, synth->resources->name, 0, synth->bank + synth->location, synth->mem.active, 0, BRISTOL_STAT) >= 0) break; } loadMemory(synth, SYNTH_NAME, 0, synth->bank + synth->location, synth->mem.active, 0, BRISTOL_FORCE); /* optsShim(synth); */ event.type = BRISTOL_FLOAT; event.value = 1; brightonParamChange(synth->win, MODS_PANEL, synth->location, &event); break; case 12: /* * Down */ while (--synth->location != start) { if (synth->location < 1) synth->location = 8; if (loadMemory(synth, synth->resources->name, 0, synth->bank + synth->location, synth->mem.active, 0, BRISTOL_STAT) >= 0) break; } loadMemory(synth, SYNTH_NAME, 0, synth->bank + synth->location, OPTS_START, 0, BRISTOL_FORCE); /* optsShim(synth); */ event.type = BRISTOL_FLOAT; event.value = 1; brightonParamChange(synth->win, MODS_PANEL, synth->location, &event); break; case 11: /* * Show Opts panel */ panelSwitch(win, synth, value); break; } return(0); } /* * For the sake of ease of use, links have been placed here to be called * by any of the devices created. They would be better in some other file, * perhaps with this as a dispatch. * * Param refers to the device index in the locations table given below. */ static int BME700Callback(brightonWindow *win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); int sendvalue; if (global.libtest) printf("BME700Callback(%i, %f)\n", index, value); if (synth == 0) return(0); if ((index >= OPTS_START) && (index < ACTIVE_DEVS)) return(0); if (panel == 3) index += OPTS_START; // if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0)) if (index >= DEVICE_COUNT) return(0); if (bme700App.resources[0].devlocn[index].to == 1) sendvalue = value * C_RANGE_MIN_1; else sendvalue = value; synth->mem.param[index] = value; // if ((!global.libtest) || (index >= ACTIVE_DEVS)) synth->dispatch[index].routine(synth, global.controlfd, synth->sid, synth->dispatch[index].operator, synth->dispatch[index].controller, sendvalue); return(0); } static void envelope(guiSynth *synth, int fd, int chan, int c, int o, int v) { switch (o) { case 0: /* Mode selector - sustain level */ bristolMidiSendMsg(fd, synth->sid, c, 2, v == 0? 0:C_RANGE_MIN_1); break; case 1: /* Attack */ bristolMidiSendMsg(fd, synth->sid, c, 0, v); break; case 2: /* Decay/release */ bristolMidiSendMsg(fd, synth->sid, c, 1, v); bristolMidiSendMsg(fd, synth->sid, c, 3, v); break; } } static void pwm(guiSynth *synth, int fd, int chan, int c, int o, int v) { float pw = 0.5; int source = 0; int man = 0; /* * Params are * 9 = PW rotary * 13 = auto/man * 14 = env/mod */ if (synth->mem.param[13] != 0) { pw = synth->mem.param[9] * 0.5; man = 1; } if (synth->mem.param[14] != 0) source = 1; bristolMidiSendMsg(fd, synth->sid, 2, 13, (int) (pw * C_RANGE_MIN_1)); bristolMidiSendMsg(fd, synth->sid, 126, 29, (int) (synth->mem.param[9] * 0.9 * C_RANGE_MIN_1)); bristolMidiSendMsg(fd, synth->sid, 126, 16, man); bristolMidiSendMsg(fd, synth->sid, 126, 17, source); } static void lfofreq(guiSynth *synth, int fd, int chan, int c, int o, int v) { bristolMidiSendMsg(fd, synth->sid, c, o, C_RANGE_MIN_1 - v); } static void filterTracking(guiSynth *synth, int fd, int chan, int c, int o, int v) { bristolMidiSendMsg(fd, synth->sid, 4, 3, v == 0? 0: (int) (synth->mem.param[62] * C_RANGE_MIN_1)); bristolMidiSendMsg(fd, synth->sid, 126, 22, v); } static void footage(guiSynth *synth, int fd, int chan, int c, int o, int v) { if (synth->mem.param[49] != 0) { int f16 = 0, f8 = C_RANGE_MIN_1, f4 = 0, detune = 0; if (synth->mem.param[15] == 0) { detune = (synth->mem.param[48] * synth->mem.param[48] * C_RANGE_MIN_1); if (synth->mem.param[16] == 0) /* 4' */ f4 = f8; else /* 16' */ f16 = f8; } /* Mix in separate strands */ bristolMidiSendMsg(fd, synth->sid, 2, 2, 12); bristolMidiSendMsg(fd, synth->sid, 2, 3, detune); bristolMidiSendMsg(fd, synth->sid, 2, 4, f16); bristolMidiSendMsg(fd, synth->sid, 2, 5, f8); bristolMidiSendMsg(fd, synth->sid, 2, 6, f4); } else { /* Transpose the oscillator */ int transp = 12; if (synth->mem.param[15] == 0) { if (synth->mem.param[16] == 0) /* 4' */ transp = 24; else /* 16' */ transp = 0; } /* 8' only */ bristolMidiSendMsg(fd, synth->sid, 2, 2, transp); bristolMidiSendMsg(fd, synth->sid, 2, 3, 0); bristolMidiSendMsg(fd, synth->sid, 2, 4, 0); bristolMidiSendMsg(fd, synth->sid, 2, 5, C_RANGE_MIN_1); bristolMidiSendMsg(fd, synth->sid, 2, 6, 0); } } static void resFilter(guiSynth *synth, int fd, int chan, int c, int o, int v) { float cutoff, lower = 0.10, upper = 0.90; int algorithm = 4; /* This was 1, 12db/oct, now just 24dB with remix */ float res, mix; if (synth->mem.param[18] != 0) { algorithm = 4; res = synth->mem.param[52]; mix = synth->mem.param[53]; } else { res = synth->mem.param[54]; mix = synth->mem.param[55]; } bristolMidiSendMsg(fd, synth->sid, 3, 4, algorithm); /* * Otherwise we have 5 switches covering frequence. I will assume we are * going to go full range. This is perhaps a bad idea, we should have a * lower cutoff, a higher cutoff, and then the switches give 32 steps * between the two. if ((cutoff = 0.0312500 + (synth->mem.param[19] == 0? 0: 0.0312500) + (synth->mem.param[20] == 0? 0: 0.062500) + (synth->mem.param[21] == 0? 0: 0.12500) + (synth->mem.param[22] == 0? 0: 0.2500) + (synth->mem.param[23] == 0? 0: 0.500)) > 1.0) cutoff = 1.0; */ cutoff = (synth->mem.param[19] == 0? 0: 0.0312500) + (synth->mem.param[20] == 0? 0: 0.062500) + (synth->mem.param[21] == 0? 0: 0.12500) + (synth->mem.param[22] == 0? 0: 0.2500) + (synth->mem.param[23] == 0? 0: 0.500); cutoff = lower + (upper - lower) * cutoff; bristolMidiSendMsg(fd, synth->sid, 3, 0, (int) (cutoff * C_RANGE_MIN_1)); bristolMidiSendMsg(fd, synth->sid, 3, 1, (int) (res * C_RANGE_MIN_1)); bristolMidiSendMsg(fd, synth->sid, 3, 7, (int) (mix * C_RANGE_MIN_1)); } /* * Any location initialisation required to run the callbacks. For bristol, this * will connect to the engine, and give it some base parameters. * May need to generate some application specific menus. * Will also then make specific requests to some of the devices to alter their * rendering. */ static int BME700Init(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); dispatcher *dispatch; int i; if (synth == 0) { synth = findSynth(global.synths, 0); if (synth == 0) { printf("cannot init\n"); return(0); } } synth->win = win; printf("Initialise the BME700 link to bristol: %p\n", synth->win); synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float)); synth->mem.count = DEVICE_COUNT; synth->mem.active = ACTIVE_DEVS; synth->dispatch = (dispatcher *) brightonmalloc(DEVICE_COUNT * sizeof(dispatcher)); dispatch = synth->dispatch; /* * We really want to have three connection mechanisms. These should be * 1. Unix named sockets. * 2. UDP sockets (actually implements TCP unfortunately). * 3. MIDI pipe. */ if (!global.libtest) { if ((synth->sid = initConnection(&global, synth)) < 0) return(-1); } for (i = 0; i < DEVICE_COUNT; i++) { synth->dispatch[i].operator = 126; synth->dispatch[i].controller = 101; synth->dispatch[i].routine = (synthRoutine) BME700MidiShim; } /* LFO */ synth->dispatch[0].operator = 126; synth->dispatch[0].controller = 11; synth->dispatch[1].operator = 0; synth->dispatch[1].controller = 0; synth->dispatch[2].operator = 1; synth->dispatch[2].controller = 0; synth->dispatch[1].routine = synth->dispatch[2].routine = (synthRoutine) lfofreq; synth->dispatch[3].operator = 126; synth->dispatch[3].controller = 12; /* Vib Env */ synth->dispatch[4].operator = 126; synth->dispatch[4].controller = 10; synth->dispatch[5].operator = 126; synth->dispatch[5].controller = 27; /* PWM double, wave */ synth->dispatch[6].operator = 126; synth->dispatch[6].controller = 14; synth->dispatch[7].operator = 126; synth->dispatch[7].controller = 13; /* Glide */ synth->dispatch[8].operator = 126; synth->dispatch[8].controller = 0; synth->dispatch[12].operator = 126; synth->dispatch[12].controller = 15; /* Signal */ synth->dispatch[11].operator = 2; synth->dispatch[11].controller = 14; /* Vibrato */ synth->dispatch[10].operator = 126; synth->dispatch[10].controller = 28; /* PWM Source */ synth->dispatch[9].operator = 126; synth->dispatch[9].controller = 101; synth->dispatch[13].operator = 126; synth->dispatch[13].controller = 102; synth->dispatch[14].operator = 126; synth->dispatch[14].controller = 103; synth->dispatch[9].routine = synth->dispatch[13].routine = synth->dispatch[14].routine = (synthRoutine) pwm; /* Footage */ synth->dispatch[15].operator = 126; synth->dispatch[15].controller = 18; synth->dispatch[16].operator = 126; synth->dispatch[16].controller = 19; synth->dispatch[15].routine = synth->dispatch[16].routine = (synthRoutine) footage; /* Noise/VCO mix */ synth->dispatch[17].operator = 126; synth->dispatch[17].controller = 3; /* ResFilter - type, then frequency */ synth->dispatch[18].operator = 3; synth->dispatch[18].controller = 0; synth->dispatch[19].operator = 3; synth->dispatch[19].controller = 1; synth->dispatch[20].operator = 3; synth->dispatch[20].controller = 2; synth->dispatch[21].operator = 3; synth->dispatch[21].controller = 3; synth->dispatch[22].operator = 3; synth->dispatch[22].controller = 4; synth->dispatch[23].operator = 3; synth->dispatch[23].controller = 5; synth->dispatch[18].routine = synth->dispatch[19].routine = synth->dispatch[20].routine = synth->dispatch[21].routine = synth->dispatch[22].routine = synth->dispatch[23].routine = (synthRoutine) resFilter; /* Env-1 */ synth->dispatch[24].operator = 6; synth->dispatch[24].controller = 0; synth->dispatch[25].operator = 6; synth->dispatch[25].controller = 1; synth->dispatch[26].operator = 6; synth->dispatch[26].controller = 2; /* Env-2 */ synth->dispatch[27].operator = 7; synth->dispatch[27].controller = 0; synth->dispatch[28].operator = 7; synth->dispatch[28].controller = 1; synth->dispatch[29].operator = 7; synth->dispatch[29].controller = 2; synth->dispatch[24].routine = synth->dispatch[25].routine = synth->dispatch[26].routine = synth->dispatch[27].routine = synth->dispatch[28].routine = synth->dispatch[29].routine = (synthRoutine) envelope; /* Env Mix */ synth->dispatch[30].operator = 126; synth->dispatch[30].controller = 5; synth->dispatch[31].operator = 126; synth->dispatch[31].controller = 6; /* VCF */ synth->dispatch[32].operator = 4; synth->dispatch[32].controller = 1; synth->dispatch[33].operator = 4; synth->dispatch[33].controller = 0; synth->dispatch[34].operator = 4; synth->dispatch[34].controller = 2; synth->dispatch[35].operator = 126; synth->dispatch[35].controller = 25; /* Filter mod */ synth->dispatch[36].operator = 126; synth->dispatch[36].controller = 20; synth->dispatch[37].operator = 126; synth->dispatch[37].controller = 21; synth->dispatch[38].operator = 126; synth->dispatch[38].controller = 22; synth->dispatch[38].routine = (synthRoutine) filterTracking; /* filter mix */ synth->dispatch[39].operator = 126; synth->dispatch[39].controller = 4; /* Amp mod */ synth->dispatch[40].operator = 126; synth->dispatch[40].controller = 26; synth->dispatch[41].operator = 126; synth->dispatch[41].controller = 23; synth->dispatch[42].operator = 126; synth->dispatch[42].controller = 24; /* Options LFO */ synth->dispatch[43].operator = 126; synth->dispatch[43].controller = 7; synth->dispatch[44].operator = 0; synth->dispatch[44].controller = 1; synth->dispatch[45].operator = 126; synth->dispatch[45].controller = 8; synth->dispatch[46].operator = 1; synth->dispatch[46].controller = 1; /* Test the LFO limits */ synth->dispatch[47].operator = 0; synth->dispatch[47].controller = 4; synth->dispatch[48].operator = 0; synth->dispatch[48].controller = 5; /* Footage */ synth->dispatch[49].operator = 126; synth->dispatch[49].controller = 101; synth->dispatch[49].routine = synth->dispatch[48].routine = (synthRoutine) footage; /* Noise */ synth->dispatch[50].operator = 5; synth->dispatch[50].controller = 1; synth->dispatch[51].operator = 5; synth->dispatch[51].controller = 2; synth->dispatch[64].operator = 126; synth->dispatch[64].controller = 9; /* Resonator */ synth->dispatch[52].operator = 3; synth->dispatch[52].controller = 1; synth->dispatch[53].operator = 3; synth->dispatch[53].controller = 7; synth->dispatch[54].operator = 3; synth->dispatch[54].controller = 1; synth->dispatch[55].operator = 3; synth->dispatch[55].controller = 7; synth->dispatch[52].routine = synth->dispatch[53].routine = synth->dispatch[54].routine = synth->dispatch[55].routine = (synthRoutine) resFilter; /* Env */ synth->dispatch[56].operator = 6; synth->dispatch[56].controller = 5; synth->dispatch[57].operator = 6; synth->dispatch[57].controller = 6; synth->dispatch[58].operator = 6; synth->dispatch[58].controller = 4; synth->dispatch[59].operator = 7; synth->dispatch[59].controller = 5; synth->dispatch[60].operator = 7; synth->dispatch[60].controller = 6; synth->dispatch[61].operator = 7; synth->dispatch[61].controller = 4; /* VCF */ synth->dispatch[62].operator = 4; synth->dispatch[62].controller = 3; synth->dispatch[62].routine = (synthRoutine) filterTracking; synth->dispatch[63].operator = 4; synth->dispatch[63].controller = 7; /* Global tuning, volume */ synth->dispatch[75].operator = 126; synth->dispatch[75].controller = 1; synth->dispatch[76].operator = 126; synth->dispatch[76].controller = 2; /* Both LFO upper and lower limits */ bristolMidiSendMsg(global.controlfd, synth->sid, 0, 4, C_RANGE_MIN_1 / 20); bristolMidiSendMsg(global.controlfd, synth->sid, 0, 5, C_RANGE_MIN_1 / 2); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 4, C_RANGE_MIN_1 / 20); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 5, C_RANGE_MIN_1 / 2); /* Osc settings */ bristolMidiSendMsg(global.controlfd, synth->sid, 2, 0, 8192); bristolMidiSendMsg(global.controlfd, synth->sid, 2, 1, 8192); bristolMidiSendMsg(global.controlfd, synth->sid, 2, 15, 1); /* Mix square 8' levels only */ bristolMidiSendMsg(global.controlfd, synth->sid, 2, 3, 0); bristolMidiSendMsg(global.controlfd, synth->sid, 2, 4, 0); bristolMidiSendMsg(global.controlfd, synth->sid, 2, 5, C_RANGE_MIN_1); bristolMidiSendMsg(global.controlfd, synth->sid, 2, 6, 0); bristolMidiSendMsg(global.controlfd, synth->sid, 2, 9, C_RANGE_MIN_1); /* Env settings: Gain */ bristolMidiSendMsg(global.controlfd, synth->sid, 6, 4, C_RANGE_MIN_1); bristolMidiSendMsg(global.controlfd, synth->sid, 7, 4, C_RANGE_MIN_1); /* Filter settings */ bristolMidiSendMsg(global.controlfd, synth->sid, 3, 7, 12000); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 5, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 4, 7, 12000); bristolMidiSendMsg(global.controlfd, synth->sid, 4, 4, 3); bristolMidiSendMsg(global.controlfd, synth->sid, 4, 5, 16383); dispatch[ACTIVE_DEVS].other1 = -1; return(0); } /* * This will be called to make any routine specific parameters available. */ static int BME700Configure(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); brightonEvent event; if (synth == 0) { printf("problems going operational\n"); return(-1); } else if (synth->location == 0) { synth->bank = 0; synth->location = 1; } else if (synth->location > 0) { synth->bank = ((synth->location / 10) * 10) % 100; if (((synth->location = synth->location % 10) == 0) || (synth->location > 8)) synth->location = 1; } if (synth->flags & OPERATIONAL) return(0); printf("going operational\n"); synth->flags |= OPERATIONAL; synth->keypanel = 1; synth->keypanel2 = -1; synth->transpose = 36; shade_id = brightonPut(win, "bitmaps/blueprints/BME700shade.xpm", 0, 0, win->width, win->height); /* * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only * occurs on first paint, so we suppress the first paint, and then request * an expose here. */ event.type = BRIGHTON_EXPOSE; event.intvalue = 1; brightonParamChange(synth->win, KEY_PANEL, -1, &event); configureGlobals(synth); brightonParamChange(synth->win, MODS_PANEL, synth->location, &event); loadMemory(synth, SYNTH_NAME, 0, synth->bank + synth->location, synth->mem.active, 0, BRISTOL_FORCE); optsShim(synth); /* * Volume, tuning, bend event.value = 0.822646; brightonParamChange(synth->win, MODS_PANEL, 10, &event); */ event.type = BRIGHTON_FLOAT; event.value = 0.5; brightonParamChange(synth->win, 0, 75, &event); event.value = 0.7; brightonParamChange(synth->win, 0, 76, &event); dc = brightonGetDCTimer(synth->win->dcTimeout); return(0); } bristol-0.60.11/brighton/brightonOBXa.c0000644000175000017500000021564511746476475014626 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include #include "brighton.h" #include "bristol.h" #include "bristolmidi.h" #include "brightonMini.h" #include "brightoninternals.h" static int initmem; extern void *brightonmalloc(); static int splitPoint = -1, width = 0; static int obxaInit(); static int obxaConfigure(); static int obxaCallback(brightonWindow *, int, int, float); static int obxaModCallback(brightonWindow *, int, int, float); static int obxaKeyCallback(brightonWindow *, int, int, float); static void obxaCopyLayer(guiSynth *); static int obxaMidiCallback(brightonWindow *, int, int, float); static void obxaSetMode(guiSynth *); static int seqLearn = 0, chordLearn = 0; extern guimain global; /* * These have to be integrated into the synth private structures, since we may * have multiple invocations of any given synth. */ static guimain manual; #include "brightonKeys.h" #define FIRST_DEV 0 #define DEVICE_COUNT 80 #define ACTIVE_DEVS 45 #define OBX_DEVS 50 /* Have to account for the manual options. */ #define MEM_START (OBX_DEVS) #define MIDI_START (MEM_START + 18) #define MOD_START (DEVICE_COUNT + ACTIVE_DEVS) #define RADIOSET_1 MEM_START #define RADIOSET_2 (MEM_START + 1) #define RADIOSET_3 (MEM_START + 2) /* Transpose radio set */ #define RADIOSET_4 (MOD_START + 10) #define FUNCTION 71 #define HOLD_KEY 48 #define SEQ_MODE 72 #define SEQ_SEL (72 + 3) #define OCTAVE_MODE (72 + 4) #define LAYER_SWITCH 70 #define KEY_PANEL 1 /* * This structure is for device definition. The structure is defined in * include/brighton.h, further definitions in brighton/brightonDevtable.h and * include/brightoninternals.h * * typedef int (*brightonCallback)(int, float); * typedef struct BrightonLocations { * int device; 0=rotary, 1=scale, etc. * float relx, rely; relative position with regards to 1000 by 1000 window * float relw, relh; relative height. * int from, to; * brightonCallback callback; specific to this dev * char *image; bitmap. If zero take a device default. * int flags; * } brightonLocations; * * This example is for a obxaBristol type synth interface. */ #define S1 110 #define S2 17 #define S3 70 #define BO 10 #define B2 6 #define R1 200 #define R2 440 #define R2a 315 #define R3 625 #define R3b 600 #define R3c 470 #define R4 805 #define C1 30 #define C2 56 #define C3 100 #define C4 175 #define C5 242 #define C6 300 #define C7 354 #define C8 415 #define C9 475 #define C10 535 #define C11 590 #define C12 650 #define C13 710 #define C11b 750 #define C12b 800 #define C13b 850 #define C14 775 #define C15 825 #define C16 875 #define C17 925 /* memories */ #define MD 18 #define C20 (C10 + MD + MD/2) #define C21 (C20 + MD) #define C22 (C21 + MD) #define C23 (C22 + MD) #define C24 (C23 + MD) #define C25 (C24 + MD) #define C26 (C25 + MD) #define C27 (C26 + MD) #define C28 (C27 + MD + MD/2) #define C29 (C28 + MD) #define C30 (C29 + MD) #define C31 (C30 + MD) #define C32 (C31 + MD) #define C33 (C32 + MD) #define C34 (C33 + MD) #define C35 (C34 + MD) #define C36 (C35 + MD + MD/2) #define C1a (29) #define C2a (C1a + 29) #define C3a (C2a + 29) #define C4a (C3a + 29) static brightonLocations locations[DEVICE_COUNT] = { /* 0 Control */ {"Glide", 0, C4, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"Unison", 2, C4 + B2, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"Osc2-Detune", 0, C4, R3b, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, /* 3 Modulation */ {"LFO-Rate", 0, C5, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"LFO-Sine", 2, C5 + B2, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"LFO-Square", 2, C5 + B2, R3, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"LFO-S/H", 2, C5 + B2, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"Mod-FM-Gain", 0, C6, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"Mod-FM-Osc1", 2, C6 + B2, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"Mod-FM-Osc2", 2, C6 + B2, R3, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"Mod-FM-Filt", 2, C6 + B2, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"Mod-PWM-Gain", 0, C7, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"Mod-PWM-Osc1", 2, C7 + B2, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"Mod-PWM-Osc2", 2, C7 + B2, R3, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* 14 Oscillators */ {"Osc1-Transpose", 0, C8, R1, S1, S1, 0, 5, 0, "bitmaps/knobs/knob5.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"Osc-PW-CLI!", 0, C9, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"Osc2-Frequency", 0, C10, R1, S1, S1, 0, 47, 0, "bitmaps/knobs/knob5.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"Osc1-Saw", 2, C8 - 8, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"Osc1-Pulse", 2, C8 + 17, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"Osc1-Env", 2, C9 - 8, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"Osc1-2-Sync", 2, C9 + 17, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"Osc2-Saw", 2, C10 - 8, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"Osc2-Pulse", 2, C10 + 17, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* 23 Filter */ {"VCF-12/24", 2, C13 + 17, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"VCF-Cutoff", 0, C11, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"VCF-Resonance", 0, C12, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"VCF-Mod", 0, C13, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"VCF-Mix-Osc1", 2, C11 - 8, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"VCF-KBD", 2, C11 + 17, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"VCF-Mix-O1-1", 2, C12 - 8, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"VCF-Mix-O1-2", 2, C12 + 17, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"VCF-Mix-Noise", 2, C13 - 8, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* 32 Envelopes */ {"VCF-Attack", 0, C14, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"VCF-Decay", 0, C15, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"VCF-Sustain", 0, C16, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"VCF-Release", 0, C17, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"VCA-Attack", 0, C14, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"VCA-Decay", 0, C15, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"VCA-Sustain", 0, C16, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"VCA-Release", 0, C17, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, /* 40 Manual - vol, reset, balance */ /* According to the original, these are not saved. Volume/balance will be. */ {"MasterVolume", 0, C1, R1 - 100, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"Reset", 2, C3 + BO, R2a, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* This is the Tremelo modifier */ {"LFO-Mod-VCA", 2, C7 + B2, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"Balance", 0, C3, R1 - 100, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, /* Master tune */ {"Master-Tune", 0, C1, R3c, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_NOTCH}, /* 45 Poly, Split, Layer */ {"Mode-Poly", 2, C8 - 8, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"Mode-Split", 2, C8 + 22, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"Mode-Layer", 2, C9 - 8, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* 48 Hold/Auto - Up to now was 46 active devs */ {"Hold", 2, C2 + BO * 3/2, R2a, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* AutoTune */ {"", 2, C1, R2a, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, /* 50 Programmer */ {"", 2, C10, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, C20, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, C21, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, C22, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, C23, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, C24, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, C25, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, C26, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, C27, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* 59 */ {"", 2, C28, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, C29, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, C30, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, C31, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, C32, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, C33, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, C34, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, C35, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, C36, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, C17 - 10, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, C17 + MD, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, {"LayerSelect", 2, C9 + 20, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* Sequence and stuff - Fn, U, D, Hold - 71 */ {"", 2, C1a, R4 - 110, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, C2a, R4 - 110, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, C3a, R4 - 110, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, C4a, R4 - 110, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* SEQ and Octaves */ {"", 2, C1a, R4 + 00, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, C2a, R4 + 00, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, C3a, R4 + 00, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, C4a, R4 + 00, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 0, C3, R3c, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_NOTCH}, }; #define OB_MODCOUNT 14 static brightonLocations obxaMods[OB_MODCOUNT] = { {"", 0, 70, 100, 180, 180, 0, 1, 0, "bitmaps/knobs/knob5.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 2, 525, 100, 130, 140, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 380, 100, 130, 140, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 0, 760, 100, 180, 180, 0, 1, 0, "bitmaps/knobs/knob5.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 1, 385, 280, 100, 450, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, BRIGHTON_CENTER}, {"", 1, 520, 280, 100, 450, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, {"", 2, 25, 750, 130, 140, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 170, 750, 130, 140, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 380, 750, 130, 140, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 525, 750, 130, 140, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 715, 750, 130, 140, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 860, 750, 130, 140, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* Multi LFO */ {"", 2, 115, 465, 110, 130, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, /* Layer copy functions */ {"", 2, 800, 465, 110, 130, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, }; /* * This is a set of globals for the main window rendering. Again taken from * include/brighton.h */ brightonApp obxaApp = { "obxa", 0, /* no blueprint on wood background. */ "bitmaps/textures/metal6.xpm", BRIGHTON_STRETCH, /*flags */ obxaInit, obxaConfigure, /* 3 callbacks, unused? */ obxaMidiCallback, destroySynth, {10, 100, 2, 2, 5, 520, 55, 0}, 770, 350, 0, 0, 6, /* panel count */ { { "OBXaPanel", "bitmaps/blueprints/obxa.xpm", "bitmaps/textures/metal4.xpm", BRIGHTON_STRETCH, /* flags */ 0, 0, obxaCallback, 15, 130, 970, 520, DEVICE_COUNT, locations }, { "Keyboard", 0, "bitmaps/newkeys/kbg.xpm", /* flags */ 0x020|BRIGHTON_STRETCH, 0, 0, obxaKeyCallback, 155, 690, 854, 290, KEY_COUNT, keys }, { "OBXaMods", "bitmaps/blueprints/obxamod.xpm", "bitmaps/textures/metal5.xpm", /* flags */ 0, 0, 0, obxaModCallback, 17, 690, 136, 290, OB_MODCOUNT, obxaMods }, { "Logo", "bitmaps/blueprints/obxalogo.xpm", 0, BRIGHTON_STRETCH, /*flags */ 0, 0, 0, 15, 0, 970, 130, 0, 0 }, { "Wood", 0, "bitmaps/textures/wood4.xpm", 0, /* flags */ 0, 0, 0, 0, 0, 15, 1000, 0, 0 }, { "Wood", 0, "bitmaps/textures/wood4.xpm", 0, /*flags */ 0, 0, 0, 985, 0, 15, 1000, 0, 0 }, } }; static void obxaPanelSwitch(guiSynth *synth, int dummy, int chan, int c, int o, int v) { brightonEvent event; int i; /*printf("obxaPanelSwitch(%x, %i, %i, %i, %i, %1.0f)\n", */ /*synth, fd, chan, c, o, global.synths->mem.param[LAYER_SWITCH]); */ /* * Prevent param changes when we are switching panels. */ synth->flags |= SUPPRESS; /* * Go through all the active devices, and force the GUI to represent * the new value. */ if (synth->mem.param[LAYER_SWITCH] == 0) { /* * Go through all the params, and request an update to the GUI */ for (i = 0; i < ACTIVE_DEVS; i++) { event.type = BRIGHTON_FLOAT; event.value = synth->mem.param[i] + 1; brightonParamChange(synth->win, 0, i, &event); event.value = synth->mem.param[i]; brightonParamChange(synth->win, 0, i, &event); } } else { for (i = 0; i < ACTIVE_DEVS; i++) { event.type = BRIGHTON_FLOAT; /* event.value = ((guiSynth *) synth->second)->mem.param[i] + 1; brightonParamChange(synth->win, 0, i, &event); event.value = ((guiSynth *) synth->second)->mem.param[i]; brightonParamChange(synth->win, 0, i, &event); */ event.value = synth->mem.param[DEVICE_COUNT + i] + 1; brightonParamChange(synth->win, 0, i, &event); event.value = synth->mem.param[DEVICE_COUNT + i]; brightonParamChange(synth->win, 0, i, &event); } } synth->flags &= ~SUPPRESS; } /* * We need our own load and save routines as these are non standard memories. * Am going to use the normal 'loadMemory' to set most of the parameters for * the second layer, then explicit read/write the second layer. */ static void obxaLoadMemory(guiSynth *synth, char *name, char *d, int loc, int o, int x, int y) { char path[256]; int fd, i, pSel; brightonEvent event; float pw[4]; /* * Memory loading should be a few phases. Firstly see which layer is visible * and if it is not the first then display the first panel and load the mem. * After that display the upper panel and load the next set of memories. * Finally return to the original panel. */ if ((pSel = synth->mem.param[LAYER_SWITCH]) != 0) { synth->mem.param[LAYER_SWITCH] = 0; /* * We should consider actually sending the button change action */ obxaPanelSwitch(synth, global.controlfd, synth->midichannel, 0, 0, 0); } /* * We cannot really use this due to the added complexity of the dual PW * controller as it removes any relationship between the value of the dial * and what it controls. We can do it with 'NOCALLS' though. */ loadMemory(synth, name, d, loc, o, x, BRISTOL_NOCALLS); /* * Save our PW */ pw[0] = synth->mem.param[15]; event.type = BRIGHTON_FLOAT; for (i = 0; i < synth->mem.active; i++) { event.value = synth->mem.param[i]; brightonParamChange(synth->win, 0, i, &event); } /* * Now we need to consider the second layer. */ if ((name != 0) && (name[0] == '/')) { sprintf(synth->mem.algo, "%s", name); sprintf(path, "%s", name); } else { sprintf(path, "%s/memory/%s/%s%i.mem", getBristolCache("midicontrollermap"), name, name, loc); sprintf(synth->mem.algo, "%s", name); if (name == NULL) sprintf(synth->mem.name, "no name"); else sprintf(synth->mem.name, "%s", name); } if ((fd = open(path, O_RDONLY, 0770)) < 0) { sprintf(path, "%s/memory/%s/%s%i.mem", global.home, name, name, loc); if ((fd = open(path, O_RDONLY, 0770)) < 0) { synth->flags &= ~MEM_LOADING; return; } } lseek(fd, DEVICE_COUNT * sizeof(float), SEEK_SET); if (read(fd, &synth->mem.param[DEVICE_COUNT], DEVICE_COUNT * sizeof(float)) < 0) printf("read failed for 2nd layer\n"); close(fd); pw[1] = synth->mem.param[MOD_START + OB_MODCOUNT + 3]; pw[2] = synth->mem.param[DEVICE_COUNT + 15]; pw[3] = synth->mem.param[MOD_START + OB_MODCOUNT + 4]; /* * The parameters for the second layer are now set, but we need to set up * the upper layer. */ printf("loading second layer: %s\n", path); synth->mem.param[LAYER_SWITCH] = 1.0f; obxaPanelSwitch(synth, global.controlfd, synth->midichannel, 0, 0, 0); /* * We now have to call the GUI to configure all these values. The GUI * will then call us back with the parameters to send to the synth. */ event.type = BRIGHTON_FLOAT; for (i = 0; i < synth->mem.active; i++) { event.value = synth->mem.param[DEVICE_COUNT + i]; brightonParamChange(synth->win, 0, i, &event); } synth->flags &= ~MEM_LOADING; synth->mem.param[LAYER_SWITCH] = pSel; obxaPanelSwitch(synth, global.controlfd, synth->midichannel, 0, 0, 0); /* * At this point we have to have a good look at the poly/split/layer * selection, and force it to the correct value. * The fix is to send an event to set the button state..... */ event.value = 1.0; if (synth->mem.param[MOD_START + OB_MODCOUNT + 0]) brightonParamChange(synth->win, synth->panel, 45, &event); else if (synth->mem.param[MOD_START + OB_MODCOUNT + 1]) { brightonParamChange(synth->win, synth->panel, 46, &event); splitPoint = synth->mem.param[MOD_START + OB_MODCOUNT + 5]; } else if (synth->mem.param[MOD_START + OB_MODCOUNT + 2]) brightonParamChange(synth->win, synth->panel, 47, &event); /* printf("Load %f %f %f %f\n", pw[0], pw[1], pw[2], pw[3]); * We now need to force the PW of the two oscillators, both layers. */ bristolMidiSendMsg(global.controlfd, synth->sid, 0, 0, (int) (pw[0])); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 0, (int) (pw[1])); bristolMidiSendMsg(global.controlfd, synth->sid2, 0, 0, (int) (pw[2])); bristolMidiSendMsg(global.controlfd, synth->sid2, 1, 0, (int) (pw[3])); synth->flags |= MEM_LOADING; /* * Finally we need to look at the mods. There are two we do not want to * look at, the two wheels - 4 and 5, the rest need to be set. */ for (i = 0; i < OB_MODCOUNT; i++) { if ((i == 4) || (i == 5)) continue; event.value = synth->mem.param[MOD_START + i]; brightonParamChange(synth->win, 2, i, &event); } synth->flags &= ~MEM_LOADING; /* * Finally load and push the sequence information for this memory. */ loadSequence(&synth->seq1, "obxa", synth->bank*10 + synth->location, 0); fillSequencer(synth, (arpeggiatorMemory *) synth->seq1.param, 0); } static int obxaMidiCallback(brightonWindow *win, int controller, int value, float n) { guiSynth *synth = findSynth(global.synths, win); printf("midi callback: %x, %i\n", controller, value); switch(controller) { case MIDI_PROGRAM: printf("midi program: %x, %i\n", controller, value); synth->location = value; obxaLoadMemory(synth, "obxa", 0, synth->bank * 10 + synth->location, synth->mem.active, FIRST_DEV, 0); break; case MIDI_BANK_SELECT: printf("midi banksel: %x, %i\n", controller, value); synth->bank = value; break; } return(0); } static int obxaKeyCallback(brightonWindow *win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); /* printf("obxaKeycallback(%x, %i, %i, %f): %i %i - %i\n", (size_t) synth, panel, index, value, synth->transpose, global.controlfd, index + synth->transpose); */ if ((seqLearn == 1) && (value != 0)) seqInsert((arpeggiatorMemory *) synth->seq1.param, (int) index, synth->transpose); if ((chordLearn == 1) && (value != 0)) chordInsert((arpeggiatorMemory *) synth->seq1.param, (int) index, synth->transpose); if (splitPoint == -2) { printf("setting split point: %i\n", index); splitPoint = index; obxaSetMode(synth); synth->mem.param[MOD_START + OB_MODCOUNT + 5] = index; return(0); } /* Don't send MIDI messages if we are testing */ if (global.libtest) return(0); /* * Want to send a note event, on or off, for this index + transpose. * Look at the Mode options. If we are layer then send two events, one for * each channel. If split then check the key we have selected, and if * poly send to each voice in turn. * * Take the tranpose out of here. */ if (value) bristolMidiSendMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_KEYON, 0, index + synth->transpose); else bristolMidiSendMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_KEYOFF, 0, index + synth->transpose); return(0); } /* static void obxadestroy(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); bristolMidiSendMsg(manual.controlfd, synth->sid2, 127, 0, BRISTOL_EXIT_ALGO); bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_EXIT_ALGO); } */ static void obxaSeqRate(guiSynth *synth, int fd, int chan, int c, int o, int v) { bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RATE, v); bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_RATE, v); } static int obxaModCallback(brightonWindow *cid, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, cid); int sendvalue; /* printf("obxaModCallback(%x, %i, %i, %f)\n", (size_t)synth, panel, index, value); */ /* * These may eventually be saved with the memories. Location is above the * second voice memories. */ synth->mem.param[MOD_START + index] = value; /* * If this is controller 0 it is the frequency control, otherwise a * generic controller 1. */ switch (index) { case 0: /* Rate pot - Second LFO */ sendvalue = value * C_RANGE_MIN_1; /* * This is a monolithic LFO, applies to both layers via preops */ bristolMidiSendMsg(global.controlfd, synth->sid, 8, 0, sendvalue); bristolMidiSendMsg(global.controlfd, synth->sid2, 8, 0, sendvalue); break; case 1: /* Lower - Apply mods to given layer */ if (value != 0) { if (synth->mem.param[MOD_START + 6] != 0.0) bristolMidiSendMsg(global.controlfd, synth->sid2, 126, 25, 1); else bristolMidiSendMsg(global.controlfd, synth->sid2, 126, 25, 0); if (synth->mem.param[MOD_START + 7] != 0.0) bristolMidiSendMsg(global.controlfd, synth->sid2, 126, 27, 1); else bristolMidiSendMsg(global.controlfd, synth->sid2, 126, 27, 0); if (synth->mem.param[MOD_START + 8] != 0.0) bristolMidiSendMsg(global.controlfd, synth->sid2, 126, 29, 1); else bristolMidiSendMsg(global.controlfd, synth->sid2, 126, 29, 0); } else { bristolMidiSendMsg(global.controlfd, synth->sid2, 126, 25, 0); bristolMidiSendMsg(global.controlfd, synth->sid2, 126, 27, 0); bristolMidiSendMsg(global.controlfd, synth->sid2, 126, 29, 0); } break; case 2: /* Upper - Apply mods to given layer */ if (value != 0.0) { if (synth->mem.param[MOD_START + 6] != 0.0) bristolMidiSendMsg(global.controlfd, synth->sid, 126, 25, 1); else bristolMidiSendMsg(global.controlfd, synth->sid, 126, 25, 0); if (synth->mem.param[MOD_START + 7] != 0.0) bristolMidiSendMsg(global.controlfd, synth->sid, 126, 27, 1); else bristolMidiSendMsg(global.controlfd, synth->sid, 126, 27, 0); if (synth->mem.param[MOD_START + 8] != 0.0) bristolMidiSendMsg(global.controlfd, synth->sid, 126, 29, 1); else bristolMidiSendMsg(global.controlfd, synth->sid, 126, 29, 0); } else { bristolMidiSendMsg(global.controlfd, synth->sid, 126, 25, 0); bristolMidiSendMsg(global.controlfd, synth->sid, 126, 27, 0); bristolMidiSendMsg(global.controlfd, synth->sid, 126, 29, 0); } break; case 3: /* Depth pot - Of LFO, affected by mod wheel */ if (synth->mem.param[MOD_START + 9] == 0) sendvalue = value * C_RANGE_MIN_1; else sendvalue = C_RANGE_MIN_1 / 2 + (int) (((value - 0.5) / 3) * C_RANGE_MIN_1); /* * This is a monolithic LFO, applies to both layers via preops */ bristolMidiSendMsg(global.controlfd, synth->sid, 126, 26, sendvalue); bristolMidiSendMsg(global.controlfd, synth->sid2, 126, 26, sendvalue); break; case 4: /* Freq wheel */ if (synth->mem.param[MOD_START + 9] == 0) sendvalue = value * C_RANGE_MIN_1; else sendvalue = C_RANGE_MIN_1 / 2 + (int) (((value - 0.5) / 3) * C_RANGE_MIN_1); /* Check on Layer switch and Osc settings */ if (synth->mem.param[MOD_START + 1] != 0) bristolMidiSendMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_PITCH, 0, sendvalue); if (synth->mem.param[MOD_START + 2] != 0) bristolMidiSendMsg(global.controlfd, synth->midichannel + 1, BRISTOL_EVENT_PITCH, 0, sendvalue); break; case 5: /* Mod wheel */ if (synth->mem.param[MOD_START + 9] == 0) sendvalue = value * C_RANGE_MIN_1; else sendvalue = value * C_RANGE_MIN_1 / 4; /* Check on Layer switches */ bristolMidiControl(global.controlfd, synth->midichannel, 0, 1, ((int) (value * C_RANGE_MIN_1)) >> 7); bristolMidiControl(global.controlfd, synth->midichannel + 1, 0, 1, ((int) (value * C_RANGE_MIN_1)) >> 7); break; case 6: /* Mod O1 - Apply Mod to Osc 1 */ if (value != 0) { if (synth->mem.param[MOD_START + 1] != 0.0) bristolMidiSendMsg(global.controlfd, synth->sid2, 126, 25, 1); else bristolMidiSendMsg(global.controlfd, synth->sid2, 126, 25, 0); } else { bristolMidiSendMsg(global.controlfd, synth->sid2, 126, 25, 0); } if (value != 0) { if (synth->mem.param[MOD_START + 2] != 0.0) bristolMidiSendMsg(global.controlfd, synth->sid, 126, 25, 1); else bristolMidiSendMsg(global.controlfd, synth->sid, 126, 25, 0); } else { bristolMidiSendMsg(global.controlfd, synth->sid, 126, 25, 0); } break; case 7: /* Mod O2 - Apply Mod to Osc 2 */ if (value != 0) { if (synth->mem.param[MOD_START + 1] != 0.0) bristolMidiSendMsg(global.controlfd, synth->sid2, 126, 27, 1); else bristolMidiSendMsg(global.controlfd, synth->sid2, 126, 27, 0); } else { bristolMidiSendMsg(global.controlfd, synth->sid2, 126, 27, 0); } if (value != 0) { if (synth->mem.param[MOD_START + 2] != 0.0) bristolMidiSendMsg(global.controlfd, synth->sid, 126, 27, 1); else bristolMidiSendMsg(global.controlfd, synth->sid, 126, 27, 0); } else { bristolMidiSendMsg(global.controlfd, synth->sid, 126, 27, 0); } break; case 8: /* MOD to PWM */ if (value != 0) { if (synth->mem.param[MOD_START + 1] != 0.0) bristolMidiSendMsg(global.controlfd, synth->sid2, 126, 29, 1); else bristolMidiSendMsg(global.controlfd, synth->sid2, 126, 29, 0); } else { bristolMidiSendMsg(global.controlfd, synth->sid2, 126, 29, 0); } if (value != 0) { if (synth->mem.param[MOD_START + 2] != 0.0) bristolMidiSendMsg(global.controlfd, synth->sid, 126, 29, 1); else bristolMidiSendMsg(global.controlfd, synth->sid, 126, 29, 0); } else { bristolMidiSendMsg(global.controlfd, synth->sid, 126, 29, 0); } break; case 9: /* Ammount - Wide Narrow mods */ /* Nothing to do - just a flag that affects swing of wheels. */ /* That is not wise, it should really go to the engine */ break; case 10: /* Transpose down - Radio buttons */ /* * These are 3 way radio buttons, which is a bit of a bummer. We * should consider making it layer sensitive however there is * already sufficient transpose in the oscillators. */ if (value == 0) { if (synth->mem.param[MOD_START + 11] == 0) /* * Default transpose synth->transpose = 36; */ bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_TRANSPOSE); bristolMidiSendMsg(global.controlfd, synth->sid2, 127, 0, BRISTOL_TRANSPOSE); } else { if (synth->mem.param[MOD_START + 11] != 0) { brightonEvent event; event.type = BRIGHTON_FLOAT; event.value = 0; brightonParamChange(synth->win, 2, 11, &event); } bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_TRANSPOSE - 12); bristolMidiSendMsg(global.controlfd, synth->sid2, 127, 0, BRISTOL_TRANSPOSE - 12); } break; case 11: /* Transpose up - Radio buttons */ if (value == 0) { if (synth->mem.param[MOD_START + 10] == 0) /* Default transpose */ bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_TRANSPOSE); bristolMidiSendMsg(global.controlfd, synth->sid2, 127, 0, BRISTOL_TRANSPOSE); } else { if (synth->mem.param[MOD_START + 10] != 0) { brightonEvent event; event.type = BRIGHTON_FLOAT; event.value = 0; brightonParamChange(synth->win, 2, 10, &event); } bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_TRANSPOSE + 12); bristolMidiSendMsg(global.controlfd, synth->sid2, 127, 0, BRISTOL_TRANSPOSE + 12); } break; case 12: /* MULTI MOD LFO - gives MOD LFO per voice rather than global. */ if (synth->mem.param[MOD_START + 12] != 0) { bristolMidiSendMsg(global.controlfd, synth->sid, 126, 22, 1); bristolMidiSendMsg(global.controlfd, synth->sid2, 126, 22, 1); /* * Configure for sync to NOTE_ON, improves variance. */ bristolMidiSendMsg(global.controlfd, synth->sid, 8, 1, 1); bristolMidiSendMsg(global.controlfd, synth->sid2, 8, 1, 1); } else { bristolMidiSendMsg(global.controlfd, synth->sid, 126, 22, 0); bristolMidiSendMsg(global.controlfd, synth->sid2, 126, 22, 0); /* * Configure for sync to never */ bristolMidiSendMsg(global.controlfd, synth->sid, 8, 1, 0); bristolMidiSendMsg(global.controlfd, synth->sid2, 8, 1, 0); } break; case 13: /* Copy lower layer parameters to upper layer */ if ((synth->flags & MEM_LOADING) == 0) obxaCopyLayer(synth); break; } return(0); } static void obxaSetMode(guiSynth *synth) { int selection = synth->mem.param[45]; if (selection == 0) { if (synth->mem.param[46] == 0) selection = 3; else selection = 2; } switch (selection) { case 1: /* Poly */ printf("configure poly\n"); bristolMidiSendMsg(global.controlfd, synth->sid, 126, 30, 1); bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_HIGHKEY|127); bristolMidiSendMsg(global.controlfd, synth->sid2, 127, 0, BRISTOL_LOWKEY|127); break; case 2: /* Split */ printf("configure split %i\n", splitPoint); bristolMidiSendMsg(global.controlfd, synth->sid, 126, 30, 0); if (splitPoint > 0) { bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_HIGHKEY|splitPoint); bristolMidiSendMsg(global.controlfd, synth->sid2, 127, 0, BRISTOL_LOWKEY|(splitPoint + 1)); } break; case 3: /* Layer */ printf("configure layer\n"); bristolMidiSendMsg(global.controlfd, synth->sid, 126, 30, 0); bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_HIGHKEY|127); bristolMidiSendMsg(global.controlfd, synth->sid2, 127, 0, BRISTOL_LOWKEY|0); break; } } static void obxaMode(guiSynth *synth, int c, int o, int value) { brightonEvent event; if (synth->flags & MEM_LOADING) return; synth->mem.param[c] = value; /* * Poly, split and layer radio buttons. */ if (synth->dispatch[RADIOSET_3].other2) { synth->dispatch[RADIOSET_3].other2 = 0; return; } //printf("obxaMode(%i, %i, %i)\n", c, o, value); if (synth->dispatch[RADIOSET_3].other1 != -1) { event.type = BRIGHTON_FLOAT; synth->dispatch[RADIOSET_3].other2 = 1; if (synth->dispatch[RADIOSET_3].other1 != c) event.value = 0; else event.value = 1; brightonParamChange(synth->win, synth->panel, synth->dispatch[RADIOSET_3].other1, &event); } synth->dispatch[RADIOSET_3].other1 = c; /* Bury this here as it has to go somewhere */ if (synth->win->width != width) brightonPut(synth->win, "bitmaps/blueprints/obxashade.xpm", 0, 0, width = synth->win->width, synth->win->height); if (global.libtest) return; /* * If Poly then set upper split to 127-127, lower to 0-127, raise voices * on lower layer. * Dual set both splits to 0-127, lower voices on lower layer. * Layer then set upper and lower splits, lower voices on lower layer. */ if (value == 0) return; obxaSetMode(synth); return; } static int pwSelect = 0; /* * We need to see if for any given oscillator none of the wave buttons are * selected. If this is the case then select triangle. Else disable tri and * configure the selected values. */ static void obxaWaveform(guiSynth *synth, int fd, int chan, int c, int o, int v) { /* * See if this is the PW parameter. */ if (c == 15) { if (synth->flags & MEM_LOADING) return; if (pwSelect == 0) { if (synth->mem.param[LAYER_SWITCH] == 0) synth->mem.param[15] = v; else synth->mem.param[DEVICE_COUNT + 15] = v; bristolMidiSendMsg(fd, chan, 0, 0, v); } else { synth->mem.param[MOD_START + OB_MODCOUNT + 3 + (int) synth->mem.param[LAYER_SWITCH]] = v; bristolMidiSendMsg(fd, chan, 1, 0, v); } return; } /* * See if we need to set PW selector */ if (o == 6) { /* * If the sqr is being selected, then PW will modify this oscillator, * and if going off then it will cotrol the other */ if (v != 0) pwSelect = c; else pwSelect = 1 - c; } /* * If the value is '1' we can just set the desired wave and disable tri. */ if (v != 0) { bristolMidiSendMsg(fd, chan, c, o, v); bristolMidiSendMsg(fd, chan, c, 5, 0); } else { int layer = 0; if (synth->mem.param[LAYER_SWITCH] != 0) layer = DEVICE_COUNT; bristolMidiSendMsg(fd, chan, c, o, v); if (c == 0) { if ((synth->mem.param[layer + 17] == 0) && (synth->mem.param[layer + 18] == 0)) bristolMidiSendMsg(fd, chan, c, 5, 1); } else { if ((synth->mem.param[layer + 21] == 0) && (synth->mem.param[layer + 22] == 0)) bristolMidiSendMsg(fd, chan, c, 5, 1); } } } static int dreset = 0; static int d1 = 0; static int d2 = 0; /* * If controller #41 has value zero then we configure the release rates, else * we use the shortest release rate. */ static void obxaDecay(void *synth, int fd, int chan, int c, int o, int v) { if (c == 41) { if (v == 0) { /* * Set values to their current settings */ dreset = 0; bristolMidiSendMsg(fd, chan, 3, 3, d1); bristolMidiSendMsg(fd, chan, 5, 3, d2); } else { /* * Set values to minimum release time */ dreset = 1; bristolMidiSendMsg(fd, chan, 3, 3, 20); bristolMidiSendMsg(fd, chan, 5, 3, 20); } } else { if (dreset == 0) bristolMidiSendMsg(fd, chan, c, o, v); if (c == 3) d1 = v; else d2 = v; } } static int obxaMidiSendMsg(void *synth, int fd, int chan, int c, int o, int v) { bristolMidiSendMsg(fd, chan, c, o, v); return(0); } static void multiTune(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; int layer = global.synths->mem.param[LAYER_SWITCH]; /* if (synth->flags & MEM_LOADING) */ /* return; */ /* * Configures all the tune settings to zero (ie, 0.5). */ event.type = BRIGHTON_FLOAT; event.value = 0.5; global.synths->mem.param[LAYER_SWITCH] = 0; brightonParamChange(synth->win, synth->panel, FIRST_DEV + 2, &event); brightonParamChange(synth->win, synth->panel, FIRST_DEV + 44, &event); global.synths->mem.param[LAYER_SWITCH] = 1; brightonParamChange(synth->win, synth->panel, FIRST_DEV + 2, &event); brightonParamChange(synth->win, synth->panel, FIRST_DEV + 44, &event); global.synths->mem.param[LAYER_SWITCH] = layer; global.synths->mem.param[2] = 0.5; global.synths->mem.param[44] = 0.5; global.synths->mem.param[DEVICE_COUNT + 2] = 0.5; global.synths->mem.param[DEVICE_COUNT + 44] = 0.5; } /* * This should take the current layer and copy to the other. */ static void obxaCopyLayer(guiSynth *synth) { int i, pSel; brightonEvent event; float pw[2]; printf("Copy Layer\n"); pw[0] = synth->mem.param[15]; pw[1] = synth->mem.param[MOD_START + OB_MODCOUNT + 3]; bcopy(synth->mem.param, &synth->mem.param[DEVICE_COUNT], ACTIVE_DEVS * sizeof(float)); /* * Memory loading should be a few phases. Firstly see which layer is visible * and if it is not the first then display the first panel and load the mem. * After that display the upper panel and load the next set of memories. * Finally return to the original panel. */ if ((pSel = synth->mem.param[LAYER_SWITCH]) == 0) { synth->mem.param[LAYER_SWITCH] = 1; /* * We should consider actually sending the button change action */ obxaPanelSwitch(synth, global.controlfd, synth->midichannel, 0, 0, 0); } /* * We now have to call the GUI to configure all these values. The GUI * will then call us back with the parameters to send to the synth. */ event.type = BRIGHTON_FLOAT; for (i = 0; i < synth->mem.active - 2; i++) { event.value = synth->mem.param[DEVICE_COUNT + i]; brightonParamChange(synth->win, 0, i, &event); } synth->mem.param[DEVICE_COUNT + 15] = pw[0]; synth->mem.param[MOD_START + OB_MODCOUNT + 4] = pw[1]; bristolMidiSendMsg(global.controlfd, synth->sid2, 0, 0, (int) pw[0] * C_RANGE_MIN_1); bristolMidiSendMsg(global.controlfd, synth->sid2, 1, 0, (int) pw[1] * C_RANGE_MIN_1); /* * Memory loading should be a few phases. Firstly see which layer is visible * and if it is not the first then display the first panel and load the mem. * After that display the upper panel and load the next set of memories. * Finally return to the original panel. */ if ((synth->mem.param[LAYER_SWITCH] = pSel) == 0) /* * We should consider actually sending the button change action */ obxaPanelSwitch(synth, global.controlfd, synth->midichannel, 0, 0, 0); } static void obxaSaveMemory(guiSynth *synth, char *name, char *d, int loc, int o) { char path[256]; int fd; /* printf("%f %f %f %f\n", synth->mem.param[15], synth->mem.param[MOD_START + OB_MODCOUNT + 3], synth->mem.param[DEVICE_COUNT + 15], synth->mem.param[MOD_START + OB_MODCOUNT + 4]); * We need to save the Poly/Split/Layer, but don't really want them to be * part of the other general routines, so 'force' it here. Not nice but * will do for now. */ saveMemory(synth, name, d, loc, o); /* * Just save a single sequencer, not one per memory. Can that, save lots */ saveSequence(synth, "obxa", loc, 0); /* * Now we need to consider the second layer. */ if ((name != 0) && (name[0] == '/')) { sprintf(synth->mem.algo, "%s", name); sprintf(path, "%s", name); } else { sprintf(path, "%s/memory/%s/%s%i.mem", getBristolCache("midicontrollermap"), name, name, loc); sprintf(synth->mem.algo, "%s", name); if (name == NULL) sprintf(synth->mem.name, "no name"); else sprintf(synth->mem.name, "%s", name); //printf("saving second layer\n"); } if ((fd = open(path, O_WRONLY, 0770)) < 0) { sprintf(path, "%s/memory/%s/%s%i.mem", global.home, name, name, loc); if ((fd = open(path, O_WRONLY, 0770)) < 0) { return; } } lseek(fd, DEVICE_COUNT * sizeof(float), SEEK_SET); if (write(fd, &synth->mem.param[DEVICE_COUNT], DEVICE_COUNT * sizeof(float)) < 0) printf("write failed 2\n"); close(fd); } static void obxaSequence(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; printf("obxaSequence\n"); if (synth->seq1.param == NULL) { loadSequence(&synth->seq1, "obxa", synth->bank*10 + synth->location, 0); fillSequencer(synth, (arpeggiatorMemory *) synth->seq1.param, 0); } if (synth->mem.param[FUNCTION] != 0) { if (v != 0) { if ((synth->flags & OPERATIONAL) == 0) return; if (synth->flags & MEM_LOADING) return; printf("Sequence learn mode requested %x\n", synth->flags); seqLearn = 1; synth->seq1.param[BRISTOL_AM_SMAX] = 0; /* * Stop the arpeggiator and send a learn request */ bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_ENABLE, 0); bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RESEQ, 1); } else { /* * Stop the learning process */ seqLearn = 0; bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RESEQ, 0); event.value = 0; brightonParamChange(synth->win, synth->panel, FUNCTION, &event); } return; } if (seqLearn == 1) { /* * This is a button press during the learning sequence, in which case * it needs to be terminated. */ seqLearn = 0; bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RESEQ, 0); } /* * If value is going to zero then stop the sequencer. */ if (v == 0) { bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_ENABLE, 0); bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_ENABLE, 0); return; } /* * Otherwise start it. */ bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_ENABLE, 1); } static void obxaFunction(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; /* * This is not really an active button so does not really require a * callback - the memory location is polled by other callbacks. */ printf("obxaFunction\n"); if (v == 0) { if (synth->mem.param[HOLD_KEY] != 0) { event.type = BRIGHTON_FLOAT; event.value = 0; brightonParamChange(synth->win, synth->panel, HOLD_KEY, &event); } if (synth->mem.param[SEQ_MODE] != 0) { event.type = BRIGHTON_FLOAT; event.value = 0; brightonParamChange(synth->win, synth->panel, SEQ_MODE, &event); } if (synth->mem.param[SEQ_MODE + 1] != 0) { event.type = BRIGHTON_FLOAT; event.value = 0; brightonParamChange(synth->win, synth->panel, SEQ_MODE+1, &event); } if (synth->mem.param[SEQ_MODE + 2] != 0) { event.type = BRIGHTON_FLOAT; event.value = 0; brightonParamChange(synth->win, synth->panel, SEQ_MODE+2, &event); } } } static void obxaArpOctave(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; printf("obxaArpOctave: %i %i %i\n", c, o, v); /* * Force exclusion */ if (synth->dispatch[OCTAVE_MODE].other2) { synth->dispatch[OCTAVE_MODE].other2 = 0; return; } event.type = BRIGHTON_FLOAT; if (v != 0) { if (synth->dispatch[OCTAVE_MODE].other1 != -1) { synth->dispatch[OCTAVE_MODE].other2 = 1; if (synth->dispatch[OCTAVE_MODE].other1 != c) event.value = 0; else event.value = 1; brightonParamChange(synth->win, synth->panel, synth->dispatch[OCTAVE_MODE].other1, &event); } synth->dispatch[OCTAVE_MODE].other1 = c; bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RANGE, o); bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_RANGE, o); return; } else { if ((synth->mem.param[OCTAVE_MODE] == 0) && (synth->mem.param[OCTAVE_MODE + 1] == 0) && (synth->mem.param[OCTAVE_MODE + 2] == 0)) { event.value = 1; brightonParamChange(synth->win, synth->panel, c, &event); bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RANGE, o); bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_RANGE, o); } } } static void obxaFilter(guiSynth *synth, int fd, int chan, int c, int o, int v) { /* * Don't change the filter type, alter the feedforward from the other * poles */ if (v != 0) v = 16383; bristolMidiSendMsg(fd, chan, 4, 4, 4); bristolMidiSendMsg(fd, chan, 4, 7, v); // bristolMidiSendMsg(fd, chan, 4, 1, synth->mem.param[25] * C_RANGE_MIN_1); } static void obxaArpeggiate(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; printf("obxaArpeggiate: %i %i\n", c, v); /* * Force exclusion */ if (synth->dispatch[SEQ_MODE].other2) { synth->dispatch[SEQ_MODE].other2 = 0; return; } if (synth->seq1.param == NULL) { loadSequence(&synth->seq1, "obxa", synth->bank*10 + synth->location, 0); fillSequencer(synth, (arpeggiatorMemory *) synth->seq1.param, 0); } printf("obxaArpeggiate(%i, %i)\n", c, v); event.type = BRIGHTON_FLOAT; if (v != 0) { if (synth->dispatch[SEQ_MODE].other1 != -1) { synth->dispatch[SEQ_MODE].other2 = 1; if (synth->dispatch[SEQ_MODE].other1 != c) event.value = 0; else event.value = 1; brightonParamChange(synth->win, synth->panel, synth->dispatch[SEQ_MODE].other1, &event); } synth->dispatch[SEQ_MODE].other1 = c; bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_DIR, o); bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_DIR, o); /* And enable it */ if (synth->mem.param[SEQ_SEL] == 0) bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_ENABLE, 1); else bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_ENABLE, 1); return; } /* * If we are going off then disable the arpeggiator, otherwise set the * mode and start it. */ if (v == 0) { /* * OK, the value is zero. If this is the same controller going off * then disable the arpeggiator, otherwise do nothing. */ if (synth->dispatch[SEQ_MODE].other1 == c) { bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_ENABLE, 0); bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_ENABLE, 0); } return; } } static void obxaChord(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; printf("Chord request: %i\n", v); if (synth->seq1.param == NULL) { loadSequence(&synth->seq1, "obxa", synth->bank*10 + synth->location, 0); fillSequencer(synth, (arpeggiatorMemory *) synth->seq1.param, 0); } event.type = BRIGHTON_FLOAT; if (synth->mem.param[FUNCTION] != 0) { if (v != 0) { if ((synth->flags & OPERATIONAL) == 0) return; if (synth->flags & MEM_LOADING) return; chordLearn = 1; printf("Chord learn requested %x\n", synth->flags); synth->seq1.param[BRISTOL_AM_CCOUNT] = 0; /* * This is to start a re-seq of the chord. */ bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_CHORD_ENABLE, 0); bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_CHORD_RESEQ, 1); } else { chordLearn = 0; bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_CHORD_RESEQ, 0); bristolMidiSendMsg(global.controlfd, synth->sid2, BRISTOL_ARPEGGIATOR, BRISTOL_CHORD_RESEQ, 0); event.value = 0; brightonParamChange(synth->win, synth->panel, FUNCTION, &event); } return; } if (chordLearn == 1) { /* * This is a button press during the learning sequence, in which case * it needs to be terminated. */ chordLearn = 0; bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_CHORD_RESEQ, 0); } bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_CHORD_ENABLE, v); } static void obxaMemory(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; if ((synth->flags & OPERATIONAL) == 0) return; switch (c) { case 16: /* Load */ obxaLoadMemory(synth, "obxa", 0, synth->bank * 10 + synth->location, synth->mem.active, FIRST_DEV, 0); break; case 17: /* Save */ obxaSaveMemory(synth, "obxa", 0, synth->bank * 10 + synth->location, 0); break; case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: if (synth->dispatch[RADIOSET_1].other2) { synth->dispatch[RADIOSET_1].other2 = 0; return; } if (synth->dispatch[RADIOSET_1].other1 != -1) { synth->dispatch[RADIOSET_1].other2 = 1; if (synth->dispatch[RADIOSET_1].other1 != o) event.value = 0; else event.value = 1; brightonParamChange(synth->win, synth->panel, synth->dispatch[RADIOSET_1].other1, &event); } synth->dispatch[RADIOSET_1].other1 = o; synth->bank = c + 1; break; case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: if (synth->dispatch[RADIOSET_2].other2) { synth->dispatch[RADIOSET_2].other2 = 0; return; } if (synth->dispatch[RADIOSET_2].other1 != -1) { synth->dispatch[RADIOSET_2].other2 = 1; if (synth->dispatch[RADIOSET_2].other1 != o) event.value = 0; else event.value = 1; brightonParamChange(synth->win, synth->panel, synth->dispatch[RADIOSET_2].other1, &event); } synth->dispatch[RADIOSET_2].other1 = o; /* * Having the minus seven looks odd, but the controllers count from * zero but I want the actual memories to be from 1 to 64, this * reflects the panel blueprint c - 8 + 1 = c - 7; */ synth->location = c - 7; break; } /* printf(" obxaMemory(B: %i L %i: %i)\n", */ /* synth->bank, synth->location, o); */ } static void obxaMidi(guiSynth *synth, int fd, int chan, int c, int o, int v) { int newchan; if ((synth->flags & OPERATIONAL) == 0) return; /* * For this synth we are going to try and put everything on a single * midi channel - split poly is all voices, split will tell the engine * which ranges apply to which voices on this synth, layer will apply * two notes on the channel, and unison all of them. Unison should really * be an engine feature to setup every voice for a given baudio structure. * * This works badly for the Prophet10 though, so may go for two midi * channels and decide how to intepret them. */ if (c == 2) { if ((newchan = synth->midichannel - 1) < 0) { synth->midichannel = 0; return; } } else { if ((newchan = synth->midichannel + 1) > 15) { synth->midichannel = 15; return; } } printf("midichannel %i %i\n", c, newchan); if (global.libtest == 0) { bristolMidiSendMsg(global.controlfd, synth->sid2, 127, 0, BRISTOL_MIDICHANNEL|newchan); bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_MIDICHANNEL|newchan); } synth->midichannel = newchan; } /* * For the sake of ease of use, links have been placed here to be called * by any of the devices created. They would be better in some other file, * perhaps with this as a dispatch. * * Param refers to the device index in the locations table given below. */ static int obxaCallback(brightonWindow * win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); int sendvalue, sid = 0; //printf("obxaCallback(%i, %i, %f): %x, %1.0f\n", panel, index, value, synth, //global.synths->mem.param[LAYER_SWITCH]); if (synth->flags & SUPPRESS) return(0); if (synth == 0) return(0); if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0)) return(0); if (obxaApp.resources[0].devlocn[index].to == 1.0) sendvalue = value * C_RANGE_MIN_1; else sendvalue = value; if (index == LAYER_SWITCH) { synth->mem.param[LAYER_SWITCH] = value; obxaPanelSwitch(synth, global.controlfd, sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); return(0); } if (synth->mem.param[LAYER_SWITCH] == 0) { /* * This is actually broken for certain cases with the dual function of * the pulsewidth button. */ if (index != 15) synth->mem.param[index] = value; sid = synth->sid; } else { ((guiSynth *) synth->second)->mem.param[index] = value; if (index != 15) synth->mem.param[DEVICE_COUNT + index] = value; sid = synth->sid2; } /* Mode switches */ if ((index == 45) || (index == 46) || (index == 47)) { if (index == 46) { if (value != 0) splitPoint = -2; else splitPoint = -1; } obxaMode(synth, synth->dispatch[index].controller, synth->dispatch[index].operator, value); /* Looks odd, but need to hide the parameters in spare space. */ synth->mem.param[MOD_START + OB_MODCOUNT + index - 45] = value; return(0); } if ((!global.libtest) || (index >= ACTIVE_DEVS)) synth->dispatch[index].routine(synth, global.controlfd, sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #ifdef DEBUG else printf("dispatch[%x,%i](%i, %i, %i, %i, %i)\n", synth, index, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #endif return(0); } /* * Any location initialisation required to run the callbacks. For bristol, this * will connect to the engine, and give it some base parameters. * May need to generate some application specific menus. * Will also then make specific requests to some of the devices to alter their * rendering. */ static int obxaInit(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); dispatcher *dispatch; int i; if (synth == 0) { synth = findSynth(global.synths, 0); if (synth == 0) { printf("cannot init\n"); return(0); } } if ((initmem = synth->location) == 0) initmem = 11; synth->win = win; printf("Initialise the %s link to bristol: %p %p\n", synth->resources->name, synth, synth->win); synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * 2 * sizeof(float)); synth->mem.count = DEVICE_COUNT; synth->mem.active = ACTIVE_DEVS; synth->dispatch = (dispatcher *) brightonmalloc(DEVICE_COUNT * sizeof(dispatcher)); dispatch = synth->dispatch; synth->second = brightonmalloc(sizeof(guiSynth)); bcopy(synth, ((guiSynth *) synth->second), sizeof(guiSynth)); ((guiSynth *) synth->second)->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float)); ((guiSynth *) synth->second)->mem.count = DEVICE_COUNT; ((guiSynth *) synth->second)->mem.active = ACTIVE_DEVS; ((guiSynth *) synth->second)->dispatch = synth->dispatch; /* * We really want to have three connection mechanisms. These should be * 1. Unix named sockets. * 2. UDP sockets. * 3. MIDI pipe. */ if (!global.libtest) { int v; if (synth->voices == BRISTOL_VOICECOUNT) { synth->voices = 10; ((guiSynth *) synth->second)->voices = 5; } else ((guiSynth *) synth->second)->voices = synth->voices >> 1; v = synth->voices; synth->synthtype = BRISTOL_OBX; bcopy(&global, &manual, sizeof(guimain)); if ((synth->sid = initConnection(&global, synth)) < 0) return(-1); manual.flags |= BRISTOL_CONN_FORCE|BRIGHTON_NOENGINE; manual.port = global.port; manual.host = global.host; synth->voices = ((guiSynth *) synth->second)->voices; /* * Just 5 voices on each layer. This should be a parameter since they * had 3, 4 and 5 voices per layer originally. */ if ((synth->sid2 = initConnection(&manual, synth)) < 0) return(-1); global.manualfd = manual.controlfd; global.manual = &manual; manual.manual = &global; synth->voices = v; } else { synth->sid = 5; synth->sid2 = 10; } for (i = 0; i < DEVICE_COUNT; i++) synth->dispatch[i].routine = obxaMidiSendMsg; /* Glide and Unison, done */ dispatch[FIRST_DEV].controller = 126; dispatch[FIRST_DEV].operator = 0; dispatch[FIRST_DEV + 1].controller = 126; dispatch[FIRST_DEV + 1].operator = 1; dispatch[FIRST_DEV + 2].controller = 1; dispatch[FIRST_DEV + 2].operator = 10; /* LFO - operator 2 parameters - Done */ dispatch[FIRST_DEV + 3].controller = 2; dispatch[FIRST_DEV + 3].operator = 0; dispatch[FIRST_DEV + 4].controller = 126; dispatch[FIRST_DEV + 4].operator = 19; dispatch[FIRST_DEV + 5].controller = 126; dispatch[FIRST_DEV + 5].operator = 20; /* S/H - this should be a routing switch. */ dispatch[FIRST_DEV + 6].controller = 126; dispatch[FIRST_DEV + 6].operator = 21; /* Depth Osc/Osc/Filt - routing control/switches */ dispatch[FIRST_DEV + 7].controller = 126; dispatch[FIRST_DEV + 7].operator = 4; dispatch[FIRST_DEV + 8].controller = 126; dispatch[FIRST_DEV + 8].operator = 5; dispatch[FIRST_DEV + 9].controller = 126; dispatch[FIRST_DEV + 9].operator = 6; dispatch[FIRST_DEV + 10].controller = 126; dispatch[FIRST_DEV + 10].operator = 7; /* PWM Osc/Osc - routing control/switches */ dispatch[FIRST_DEV + 11].controller = 126; dispatch[FIRST_DEV + 11].operator = 8; dispatch[FIRST_DEV + 12].controller = 126; dispatch[FIRST_DEV + 12].operator = 9; dispatch[FIRST_DEV + 13].controller = 126; dispatch[FIRST_DEV + 13].operator = 10; /* Osc - Some routing switches. */ dispatch[FIRST_DEV + 14].controller = 0; dispatch[FIRST_DEV + 14].operator = 1; /* PWM - needs to adjust both oscillators, so need a dispatcher. */ dispatch[FIRST_DEV + 15].controller = 15; dispatch[FIRST_DEV + 15].operator = 1; dispatch[FIRST_DEV + 16].controller = 1; dispatch[FIRST_DEV + 16].operator = 9; /* Saw/Square. May need dispatch for tri when both off */ dispatch[FIRST_DEV + 17].controller = 0; dispatch[FIRST_DEV + 17].operator = 4; dispatch[FIRST_DEV + 18].controller = 0; dispatch[FIRST_DEV + 18].operator = 6; /* Crossmod and sync - routing switches */ dispatch[FIRST_DEV + 19].controller = 126; dispatch[FIRST_DEV + 19].operator = 23; dispatch[FIRST_DEV + 20].controller = 1; dispatch[FIRST_DEV + 20].operator = 7; /* Saw/Square. May need dispatch for tri when both off */ dispatch[FIRST_DEV + 21].controller = 1; dispatch[FIRST_DEV + 21].operator = 4; dispatch[FIRST_DEV + 22].controller = 1; dispatch[FIRST_DEV + 22].operator = 6; /* Osc waveforms need a dispatcher to enable tri with both buttons off. */ dispatch[FIRST_DEV + 15].routine = dispatch[FIRST_DEV + 17].routine = dispatch[FIRST_DEV + 18].routine = dispatch[FIRST_DEV + 21].routine = dispatch[FIRST_DEV + 22].routine = (synthRoutine) obxaWaveform; /* Filter - some routing switches */ dispatch[FIRST_DEV + 23].controller = 4; dispatch[FIRST_DEV + 23].operator = 4; dispatch[FIRST_DEV + 23].routine = (synthRoutine) obxaFilter; dispatch[FIRST_DEV + 24].controller = 4; dispatch[FIRST_DEV + 24].operator = 0; dispatch[FIRST_DEV + 25].controller = 4; dispatch[FIRST_DEV + 25].operator = 1; dispatch[FIRST_DEV + 26].controller = 4; dispatch[FIRST_DEV + 26].operator = 2; /* Routing switches. Need to check on KBD tracking though */ dispatch[FIRST_DEV + 27].controller = 126; dispatch[FIRST_DEV + 27].operator = 12; dispatch[FIRST_DEV + 28].controller = 4; dispatch[FIRST_DEV + 28].operator = 3; dispatch[FIRST_DEV + 29].controller = 126; dispatch[FIRST_DEV + 29].operator = 14; dispatch[FIRST_DEV + 30].controller = 126; dispatch[FIRST_DEV + 30].operator = 15; dispatch[FIRST_DEV + 31].controller = 126; dispatch[FIRST_DEV + 31].operator = 17; /* Envelopes */ dispatch[FIRST_DEV + 32].controller = 3; dispatch[FIRST_DEV + 32].operator = 0; dispatch[FIRST_DEV + 33].controller = 3; dispatch[FIRST_DEV + 33].operator = 1; dispatch[FIRST_DEV + 34].controller = 3; dispatch[FIRST_DEV + 34].operator = 2; dispatch[FIRST_DEV + 35].controller = 3; dispatch[FIRST_DEV + 35].operator = 3; dispatch[FIRST_DEV + 36].controller = 5; dispatch[FIRST_DEV + 36].operator = 0; dispatch[FIRST_DEV + 37].controller = 5; dispatch[FIRST_DEV + 37].operator = 1; dispatch[FIRST_DEV + 38].controller = 5; dispatch[FIRST_DEV + 38].operator = 2; dispatch[FIRST_DEV + 39].controller = 5; dispatch[FIRST_DEV + 39].operator = 3; /* We need a separate dispatcher for the decay, since the reset button */ /* will affect the value. */ dispatch[FIRST_DEV + 35].routine = dispatch[FIRST_DEV + 39].routine = (synthRoutine) obxaDecay; /* Master volume - gain of envelope? */ dispatch[FIRST_DEV + 40].controller = 5; dispatch[FIRST_DEV + 40].operator = 4; /* Reset or 'release' DONE */ dispatch[FIRST_DEV + 41].controller = 41; dispatch[FIRST_DEV + 41].operator = 0; dispatch[FIRST_DEV + 41].routine = (synthRoutine) obxaDecay; /* Mod to tremelo */ dispatch[FIRST_DEV + 42].controller = 126; dispatch[FIRST_DEV + 42].operator = 18; /* Balance. Should work as a dispatcher along with master volume? */ dispatch[FIRST_DEV + 43].controller = 126; dispatch[FIRST_DEV + 43].operator = 28; /* Master tune */ dispatch[FIRST_DEV + 44].controller = 126; dispatch[FIRST_DEV + 44].operator = 2; /* Mode management */ dispatch[FIRST_DEV + 45].controller = 45; dispatch[FIRST_DEV + 45].operator = 0; dispatch[FIRST_DEV + 46].controller = 46; dispatch[FIRST_DEV + 46].operator = 1; dispatch[FIRST_DEV + 47].controller = 47; dispatch[FIRST_DEV + 47].operator = 2; dispatch[FIRST_DEV + 45].routine = dispatch[FIRST_DEV + 46].routine = dispatch[FIRST_DEV + 47].routine = (synthRoutine) obxaMode; /* Hold - DONE (stole from Juno.....). Remapped to chording */ dispatch[FIRST_DEV + 48].routine = (synthRoutine) obxaChord; /* Master tune - Done. */ /*dispatch[FIRST_DEV + 48].controller = 126; */ /*dispatch[FIRST_DEV + 48].operator = 2; */ /* Autotune */ dispatch[FIRST_DEV + 49].routine = (synthRoutine) multiTune; dispatch[FIRST_DEV + 79].routine = (synthRoutine) obxaSeqRate; /* Memories. */ dispatch[MEM_START + 0].controller = 16; dispatch[MEM_START + 1].controller = 0; dispatch[MEM_START + 2].controller = 1; dispatch[MEM_START + 3].controller = 2; dispatch[MEM_START + 4].controller = 3; dispatch[MEM_START + 5].controller = 4; dispatch[MEM_START + 6].controller = 5; dispatch[MEM_START + 7].controller = 6; dispatch[MEM_START + 8].controller = 7; dispatch[MEM_START + 9].controller = 8; dispatch[MEM_START + 10].controller = 9; dispatch[MEM_START + 11].controller = 10; dispatch[MEM_START + 12].controller = 11; dispatch[MEM_START + 13].controller = 12; dispatch[MEM_START + 14].controller = 13; dispatch[MEM_START + 15].controller = 14; dispatch[MEM_START + 16].controller = 15; dispatch[MEM_START + 17].controller = 17; dispatch[MEM_START + 0].operator = MEM_START + 0; dispatch[MEM_START + 1].operator = MEM_START + 1; dispatch[MEM_START + 2].operator = MEM_START + 2; dispatch[MEM_START + 3].operator = MEM_START + 3; dispatch[MEM_START + 4].operator = MEM_START + 4; dispatch[MEM_START + 5].operator = MEM_START + 5; dispatch[MEM_START + 6].operator = MEM_START + 6; dispatch[MEM_START + 7].operator = MEM_START + 7; dispatch[MEM_START + 8].operator = MEM_START + 8; dispatch[MEM_START + 9].operator = MEM_START + 9; dispatch[MEM_START + 10].operator = MEM_START + 10; dispatch[MEM_START + 11].operator = MEM_START + 11; dispatch[MEM_START + 12].operator = MEM_START + 12; dispatch[MEM_START + 13].operator = MEM_START + 13; dispatch[MEM_START + 14].operator = MEM_START + 14; dispatch[MEM_START + 15].operator = MEM_START + 15; dispatch[MEM_START + 16].operator = MEM_START + 16; dispatch[MEM_START + 17].operator = MEM_START + 17; dispatch[MEM_START + 0].routine = dispatch[MEM_START + 1].routine = dispatch[MEM_START + 2].routine = dispatch[MEM_START + 3].routine = dispatch[MEM_START + 4].routine = dispatch[MEM_START + 5].routine = dispatch[MEM_START + 6].routine = dispatch[MEM_START + 7].routine = dispatch[MEM_START + 8].routine = dispatch[MEM_START + 9].routine = dispatch[MEM_START + 10].routine = dispatch[MEM_START + 11].routine = dispatch[MEM_START + 12].routine = dispatch[MEM_START + 13].routine = dispatch[MEM_START + 14].routine = dispatch[MEM_START + 15].routine = dispatch[MEM_START + 16].routine = dispatch[MEM_START + 17].routine = (synthRoutine) obxaMemory; dispatch[FIRST_DEV + 68].routine = dispatch[FIRST_DEV + 69].routine = (synthRoutine) obxaMidi; dispatch[FIRST_DEV + 68].controller = 1; dispatch[FIRST_DEV + 69].controller = 2; dispatch[FIRST_DEV + 71].routine = (synthRoutine) obxaFunction; dispatch[FIRST_DEV + 72].controller = 72; dispatch[FIRST_DEV + 72].operator = 0; dispatch[FIRST_DEV + 72].routine = (synthRoutine) obxaArpeggiate; dispatch[FIRST_DEV + 73].controller = 73; dispatch[FIRST_DEV + 73].operator = 1; dispatch[FIRST_DEV + 73].routine = (synthRoutine) obxaArpeggiate; dispatch[FIRST_DEV + 74].controller = 74; dispatch[FIRST_DEV + 74].operator = 2; dispatch[FIRST_DEV + 74].routine = (synthRoutine) obxaArpeggiate; dispatch[FIRST_DEV + 75].routine = (synthRoutine) obxaSequence; dispatch[FIRST_DEV + 76].controller = 76; dispatch[FIRST_DEV + 76].operator = 0; dispatch[FIRST_DEV + 76].routine = (synthRoutine) obxaArpOctave; dispatch[FIRST_DEV + 77].controller = 77; dispatch[FIRST_DEV + 77].operator = 1; dispatch[FIRST_DEV + 77].routine = (synthRoutine) obxaArpOctave; dispatch[FIRST_DEV + 78].controller = 78; dispatch[FIRST_DEV + 78].operator = 2; dispatch[FIRST_DEV + 78].routine = (synthRoutine) obxaArpOctave; dispatch[RADIOSET_1].other1 = -1; dispatch[RADIOSET_2].other1 = -1; dispatch[RADIOSET_3].other1 = -1; dispatch[SEQ_MODE].other1 = -1; dispatch[OCTAVE_MODE].other1 = -1; dispatch[FIRST_DEV + 70].routine = (synthRoutine) obxaPanelSwitch; dispatch[RADIOSET_1].other1 = -1; /* Tune/Gain osc-1/2 main layer */ bristolMidiSendMsg(global.controlfd, synth->sid, 0, 2, 8192); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 2, 8192); bristolMidiSendMsg(global.controlfd, synth->sid, 0, 3, C_RANGE_MIN_1); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 3, C_RANGE_MIN_1); /* Gain on filter contour */ bristolMidiSendMsg(global.controlfd, synth->sid, 3, 4, C_RANGE_MIN_1); /* Select alt filter */ bristolMidiSendMsg(global.controlfd, synth->sid, 4, 4, 0); /* Tune/Gain osc-1/2 second layer */ bristolMidiSendMsg(global.controlfd, synth->sid2, 0, 2, 8192); bristolMidiSendMsg(global.controlfd, synth->sid2, 1, 2, 8192); bristolMidiSendMsg(global.controlfd, synth->sid2, 0, 3, C_RANGE_MIN_1); bristolMidiSendMsg(global.controlfd, synth->sid2, 1, 3, C_RANGE_MIN_1); /* Gain on filter contour */ bristolMidiSendMsg(global.controlfd, synth->sid2, 3, 4, C_RANGE_MIN_1); /* Select alt filter and pole remixing */ bristolMidiSendMsg(global.controlfd, synth->sid2, 4, 4, 4); bristolMidiSendMsg(global.controlfd, synth->sid2, 4, 7, 4096); /* This cause the voices to see REKEY events for arpeg and seq steps */ bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_TRIGGER, 1); bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_RANGE, 2); bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_TRIGGER, 1); bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RANGE, 2); return(0); } /* * This will be called to make any routine specific parameters available. */ static int obxaConfigure(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); brightonEvent event; if (synth == 0) { printf("problems going operational\n"); return(-1); } if (synth->flags & OPERATIONAL) return(0); printf("going operational: %p, %p\n", synth, win); synth->flags |= OPERATIONAL; synth->keypanel = 1; synth->keypanel2 = -1; synth->transpose = 36; /* Don't load a memory, send a bank, location and load request. */ event.intvalue = 1; brightonParamChange(synth->win, synth->panel, MEM_START + 1, &event); brightonParamChange(synth->win, synth->panel, MEM_START + 9, &event); multiTune(synth, 0,0,0,0,0); synth->mem.param[LAYER_SWITCH] = 0; synth->bank = 1; /* * For the OBXa, most of the following has to be moved into the memory * load routines. It is a new paradigm - one panel, two synths. */ obxaLoadMemory(synth, "obxa", 0, initmem, synth->mem.active, FIRST_DEV, 0); synth->mem.param[LAYER_SWITCH] = 0; /* * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only * occurs on first paint, so we suppress the first paint, and then request * an expose here. */ event.type = BRIGHTON_EXPOSE; event.intvalue = 1; brightonParamChange(synth->win, KEY_PANEL, -1, &event); /* Set arpeggiator to 2 octaves and a middle rate */ event.type = BRIGHTON_FLOAT; event.value = 1.0; brightonParamChange(synth->win, 0, OCTAVE_MODE + 1, &event); event.value = 0.4; brightonParamChange(synth->win, 0, 79, &event); synth->loadMemory = (loadRoutine) obxaLoadMemory; synth->saveMemory = (saveRoutine) obxaSaveMemory; configureGlobals(synth); return(0); } bristol-0.60.11/brighton/brightonExplorer.c0000644000175000017500000007442211746476475015631 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* * Notes from the Voyager manual: * * Two filter modes: * * 1. Dual parallel LP, stereo separation, both resonant * 2. Serial HPF/LPF, mono, HPF is non resonant. * * Currently the filter switch is for key envelope velocity. Drop velocity on * this env and use the correct option to select the filter type. * * The mod busses are passed through: * * 1. Wheel Mod * 2. On/Off Pedal * * Release is a scaler of the actual release time. Affects both envelopes. * * Key modes, from control panel (mono only): * * 1. Lowest * 2. Highest * 3. Last key * 4. First key * * Trigger modes, from control panel (mono only): * * 1. Single * 2. Multi */ #include #include "brighton.h" #include "brightonMini.h" #include "brightoninternals.h" int explorerInit(); int explorerConfigure(); int explorerCallback(brightonWindow *, int, int, float); static int midiCallback(brightonWindow *, int, int, float); extern guimain global; extern int empty; #include "brightonKeys.h" #define KEY_PANEL 1 #define FIRST_DEV 0 #define DEVICE_COUNT 77 #define ACTIVE_DEVS 56 #define MEM_START (ACTIVE_DEVS + 1) #define DISPLAY1 (DEVICE_COUNT - 2) #define DISPLAY2 (DEVICE_COUNT - 1) #define S1 85 #define B1 15 #define B2 110 #define B3 37 #define B4 42 #define R14 200 #define R24 400 #define R34 600 #define R44 800 #define R15 200 #define R25 350 #define R35 500 #define R45 650 #define R55 800 #define C1 25 #define C2 90 #define C3 155 #define C4 220 #define C5 285 #define C6 350 #define C6I 395 #define C7 615 #define C8 665 #define C9 742 #define C10 810 #define C11 875 #define C12 945 /* * This structure is for device definition. The structure is defined in * include/brighton.h, further definitions in brighton/brightonDevtable.h and * include/brightoninternals.h * * typedef int (*brightonCallback)(int, float); * typedef struct BrightonLocations { * int device; 0=rotary, 1=scale, etc. * float relx, rely; relative position with regards to 1000 by 1000 window * float relw, relh; relative height. * int from, to; * brightonCallback callback; specific to this dev * char *image; bitmap. If zero take a device default. * int flags; * } brightonLocations; * * This example is for a explorerBristol type synth interface. */ static brightonLocations locations[DEVICE_COUNT] = { /* LFO and control */ {"LFO-Freq", 0, C1 - 7, R14 - 20, S1 + 40, S1 + 40, 0, 1, 0, 0, 0, 0}, {"LFO-Sync", 2, C1 - 5, R24 + 25, B3, B4, 0, 3, 0, "bitmaps/buttons/rockerblue.xpm", 0, 0}, {"GLOBAL TUNE", 0, C1, R34, S1, S1, 0, 1, 0, 0, 0, BRIGHTON_NOTCH}, {"Glide", 0, C1, R44, S1, S1, 0, 1, 0, 0, 0, 0}, /* Routing */ {"Mod1-Source", 0, C2, R14, S1, S1, 0, 4, 0, 0, 0, 0}, {"Mod1-Shape", 0, C2, R24, S1, S1, 0, 3, 0, 0, 0, 0}, {"Mod1-Dest", 0, C2, R34, S1, S1, 0, 5, 0, 0, 0, 0}, {"Mod1-Gain", 0, C2, R44, S1, S1, 0, 1, 0, 0, 0, 0}, {"Mod2-Source", 0, C3, R14, S1, S1, 0, 4, 0, 0, 0, 0}, {"Mod2-Shape", 0, C3, R24, S1, S1, 0, 3, 0, 0, 0, 0}, {"Mod2-Dest", 0, C3, R34, S1, S1, 0, 5, 0, 0, 0, 0}, {"Mod2-Gain", 0, C3, R44, S1, S1, 0, 1, 0, 0, 0, 0}, /* Oscillators */ {"Osc1-Transpose", 0, C4, R24, S1, S1, 0, 5, 0, 0, 0, 0}, {"Osc1-Waveform", 0, C4, R34, S1, S1, 0, 1, 0, 0, 0, 0}, {"Osc2-Tuning", 0, C5 - 7, R14 - 20, S1 + 40, S1 + 40, 0, 1, 0, 0, 0, BRIGHTON_NOTCH}, {"Osc2-Transpose", 0, C5, R24, S1, S1, 0, 5, 0, 0, 0, 0}, {"Osc2-Waveform", 0, C5, R34, S1, S1, 0, 1, 0, 0, 0, 0}, {"Osc3-Tuning", 0, C6 - 7, R14 - 20, S1 + 40, S1 + 40, 0, 1, 0, 0, 0, BRIGHTON_NOTCH}, {"Osc3-Transpose", 0, C6, R24, S1, S1, 0, 5, 0, 0, 0, 0}, {"Osc3-Waveform", 0, C6, R34, S1, S1, 0, 1, 0, 0, 0, 0}, /* Osc mod switches */ {"Sync-1/2", 2, C4, R44 + 10, B1, B2, 0, 1, 0, 0, 0, BRIGHTON_VERTICAL}, {"FM-1/3", 2, C4 + 40, R44 + 10, B1, B2, 0, 1, 0, 0, 0, BRIGHTON_VERTICAL}, {"KBD-3", 2, C4 + 95, R44 + 10, B1, B2, 0, 1, 0, 0, 0, BRIGHTON_VERTICAL}, {"Freq-3", 2, C4 + 135, R44 + 10, B1, B2, 0, 1, 0, 0, 0, BRIGHTON_VERTICAL}, /* Mixer */ {"Mix-EXT", 0, C7, R15, S1, S1, 0, 1, 0, 0, 0, 0}, {"Mix-O1", 0, C7, R25, S1, S1, 0, 1, 0, 0, 0, 0}, {"Mix-O2", 0, C7, R35, S1, S1, 0, 1, 0, 0, 0, 0}, {"Mix-O3", 0, C7, R45, S1, S1, 0, 1, 0, 0, 0, 0}, {"Mix-NSE", 0, C7, R55, S1, S1, 0, 1, 0, 0, 0, 0}, {"Mix-Ext-off", 2, C8, R15 + 25, B3, B4, 0, 1, 0, "bitmaps/buttons/rockerblue.xpm", 0, 0}, {"Mix-O1-off", 2, C8, R25 + 25, B3, B4, 0, 1, 0, "bitmaps/buttons/rockerblue.xpm", 0, 0}, {"Mix-O2-off", 2, C8, R35 + 25, B3, B4, 0, 1, 0, "bitmaps/buttons/rockerblue.xpm", 0, 0}, {"Mix-O3-off", 2, C8, R45 + 25, B3, B4, 0, 1, 0, "bitmaps/buttons/rockerblue.xpm", 0, 0}, {"Mix-Nse-off", 2, C8, R55 + 25, B3, B4, 0, 1, 0, "bitmaps/buttons/rockerblue.xpm", 0, 0}, /* Filter */ {"VCF-Cutoff", 0, C9 - 7, R15 - 25, S1 + 40, S1 + 40, 0, 1, 0, 0, 0, 0}, {"VCF-Space", 0, C9, R25, S1, S1, 0, 1, 0, 0, 0, 0}, {"VCF-Res", 0, C9, R35, S1, S1, 0, 1, 0, 0, 0, 0}, {"VCF-KBD", 0, C9, R45, S1, S1, 0, 1, 0, 0, 0, 0}, {"VCF-Mode", 2, C9, R55 + 25, B3, B4, 0, 1, 0, 0, 0, 0}, /* Filter envelope */ {"VCF-Attack", 0, C10, R15, S1, S1, 0, 1, 0, 0, 0, 0}, {"VCF-Decay", 0, C10, R25, S1, S1, 0, 1, 0, 0, 0, 0}, {"VCF-Sustain", 0, C10, R35, S1, S1, 0, 1, 0, 0, 0, 0}, {"VCF-Release", 0, C10, R45, S1, S1, 0, 1, 0, 0, 0, 0}, {"VCF-EnvLevel", 0, C10, R55, S1, S1, 0, 1, 0, 0, 0, 0}, /* Amp Envelope */ {"VCA-Attack", 0, C11, R15, S1, S1, 0, 1, 0, 0, 0, 0}, {"VCA-Decay", 0, C11, R25, S1, S1, 0, 1, 0, 0, 0, 0}, {"VCA-Sustain", 0, C11, R35, S1, S1, 0, 1, 0, 0, 0, 0}, {"VCA-Release", 0, C11, R45, S1, S1, 0, 1, 0, 0, 0, 0}, {"VCA-Veloc", 2, C11, R55 + 25, B3, B4, 0, 1, 0, 0, 0, 0}, /* Vol, on/off, glide and release */ {"Volume", 0, C12 - 7, R15 - 25 , S1 + 40, S1 + 40, 0, 1, 0, 0, 0, 0}, {"On/Off", 2, C12 - 4, R25 + 25, B3, B4, 0, 1, 0, 0, 0, 0}, {"LFO-Multi", 2, C12 - 4, R35 + 25, B3, B4, 0, 1, 0, "bitmaps/buttons/rockerwhite.xpm", 0, 0}, {"Glide-On", 2, C12 - 4, R45 + 25, B3, B4, 0, 1, 0, "bitmaps/buttons/rockerwhite.xpm", 0, 0}, {"Release-On", 2, C12 - 4, R55 + 25, B3, B4, 0, 1, 0, "bitmaps/buttons/rockerwhite.xpm", 0, 0}, {"Reserved", 5, 405, 410, 180, 518, 0, 1, 0, "bitmaps/buttons/pointer.xpm", 0, 0}, {"Reserved", 5, 405, 410, 180, 518, 0, 1, 0, "bitmaps/buttons/pointer.xpm", 0, BRIGHTON_WITHDRAWN}, /* logo */ {"", 4, 762, 1037, 240, 140, 0, 1, 0, "bitmaps/images/explorer.xpm", 0, 0}, /* memories */ {"", 2, 418, 225, 17, 78, 0, 1.01, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 436, 225, 17, 78, 0, 1.01, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 454, 225, 17, 78, 0, 1.01, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 472, 225, 17, 78, 0, 1.01, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 490, 225, 17, 78, 0, 1.01, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 418, 308, 17, 78, 0, 1.01, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 436, 308, 17, 78, 0, 1.01, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 454, 308, 17, 78, 0, 1.01, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 472, 308, 17, 78, 0, 1.01, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 490, 308, 17, 78, 0, 1.01, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 510, 228, 15, 70, 0, 1.01, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 510, 309, 15, 70, 0, 1.01, 0, "bitmaps/buttons/pressoffo.xpm", "bitmaps/buttons/pressono.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 540, 70, 16, 78, 0, 1.01, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 540, 145, 16, 78, 0, 1.01, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 540, 227, 16, 78, 0, 1.01, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 540, 308, 16, 78, 0, 1.01, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* mem up down */ {"", 2, 402, 228, 15, 70, 0, 1.01, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 402, 311, 15, 70, 0, 1.01, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, /* displays */ {"", 3, 403, 90, 128, 63, 0, 1, 0, 0, "bitmaps/images/alphadisplay3.xpm", 0}, {"", 3, 403, 150, 128, 63, 0, 1, 0, 0, 0, 0} }; /* * This is a set of globals for the main window rendering. Again taken from * include/brighton.h */ brightonApp explorerApp = { "explorer", 0, /* no blueprint on wood background. */ "bitmaps/textures/wood2.xpm", 0, /* or BRIGHTON_STRETCH, default is tesselate */ explorerInit, explorerConfigure, /* 3 callbacks, unused? */ midiCallback, destroySynth, {1, 100, 2, 2, 5, 520, 0, 0}, 817, 472, 0, 0, 7, /* one panel only */ { { "Explorer", "bitmaps/blueprints/explorer.xpm", "bitmaps/textures/metal6.xpm", BRIGHTON_STRETCH, /* flags */ 0, explorerConfigure, explorerCallback, 25, 25, 950, 532, DEVICE_COUNT, locations }, { "Keyboard", 0, "bitmaps/newkeys/ekbg.xpm", /* flags */ 0x020|BRIGHTON_STRETCH, 0, 0, keyCallback, 140, 675, 840, 300, KEY_COUNT_3OCTAVE, keys3octave }, { "Mods", "bitmaps/blueprints/mods.xpm", "bitmaps/textures/metal6.xpm", /* flags */ BRIGHTON_STRETCH, 0, 0, modCallback, 15, 675, 125, 300, 2, mods }, { "SP0", 0, "bitmaps/textures/wood2.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 930, 675, 60, 300, 0, 0 }, { "SP1", 0, "bitmaps/textures/wood2.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 0, 0, 15, 1000, 0, 0 }, { "SP2", 0, "bitmaps/textures/wood2.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 985, 0, 15, 1000, 0, 0 }, } }; /*static dispatcher dispatch[DEVICE_COUNT]; */ static int midiCallback(brightonWindow *win, int controller, int value, float n) { guiSynth *synth = findSynth(global.synths, win); printf("midi callback: %x, %i\n", controller, value); switch(controller) { case MIDI_PROGRAM: printf("midi program: %x, %i\n", controller, value); synth->location = value + synth->bank * 10; if (loadMemory(synth, "explorer", 0, synth->location, synth->mem.active, FIRST_DEV, BRISTOL_STAT) < 0) displayText(synth, "FRE", synth->location, DISPLAY1); else displayText(synth, "PRG", synth->location, DISPLAY1); break; case MIDI_BANK_SELECT: printf("midi banksel: %x, %i\n", controller, value); synth->bank = value; synth->location = (synth->location % 10) + value * 10; if (loadMemory(synth, "explorer", 0, synth->location, synth->mem.active, FIRST_DEV, BRISTOL_STAT) < 0) displayText(synth, "FRE", synth->location, DISPLAY1); else displayText(synth, "PRG", synth->location, DISPLAY1); break; } return(0); } static int explorerMidiSendMsg(void *synth, int fd, int chan, int c, int o, int v) { bristolMidiSendMsg(fd, chan, c, o, v); return(0); } static void explorerMemory(guiSynth *synth, int fd, int chan, int c, int o, int v) { /* printf("explorerMemory(%i %i %i %i %i)\n", fd, chan, c, o, v); */ if (synth->flags & MEM_LOADING) return; if ((synth->flags & OPERATIONAL) == 0) return; if (synth->dispatch[MEM_START].other2) { synth->dispatch[MEM_START].other2 = 0; return; } switch (c) { default: case 0: if (synth->dispatch[MEM_START].other1 != -1) { brightonEvent event; synth->dispatch[MEM_START].other2 = 1; if (synth->dispatch[MEM_START].other1 != c) event.value = 0; else event.value = 1; brightonParamChange(synth->win, synth->panel, synth->dispatch[MEM_START].other1, &event); } synth->dispatch[MEM_START].other1 = c; synth->location = synth->location * 10 + o; if (synth->location >= 1000) synth->location = o; if (loadMemory(synth, "explorer", 0, synth->location, synth->mem.active, FIRST_DEV, BRISTOL_STAT) < 0) displayText(synth, "FRE", synth->location, DISPLAY1); else displayText(synth, "PRG", synth->location, DISPLAY1); break; case 1: if (loadMemory(synth, "explorer", 0, synth->location, synth->mem.active, FIRST_DEV, 0) < 0) displayText(synth, "FRE", synth->location, DISPLAY2); else displayText(synth, "PRG", synth->location, DISPLAY2); /* synth->location = 0; */ break; case 2: saveMemory(synth, "explorer", 0, synth->location, FIRST_DEV); displayText(synth, "PRG", synth->location, DISPLAY2); /* synth->location = 0; */ break; case 3: while (loadMemory(synth, "explorer", 0, ++synth->location, synth->mem.active, FIRST_DEV, 0) < 0) { if (synth->location > 999) synth->location = -1; } displayText(synth, "PRG", synth->location, DISPLAY2); break; case 4: while (loadMemory(synth, "explorer", 0, --synth->location, synth->mem.active, FIRST_DEV, 0) < 0) { if (synth->location < 0) synth->location = 999; } displayText(synth, "PRG", synth->location, DISPLAY2); break; } } /* * For the sake of ease of use, links have been placed here to be called * by any of the devices created. They would be better in some other file, * perhaps with this as a dispatch. * * Param refers to the device index in the locations table given below. */ int explorerCallback(brightonWindow * win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); int sendvalue; /* printf("explorerCallback(%i, %i, %f)\n", panel, index, value); */ if (synth == 0) return(0); if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0)) return(0); if (index >= DEVICE_COUNT) return(0); if (explorerApp.resources[0].devlocn[index].to == 1.0) sendvalue = value * (CONTROLLER_RANGE - 1); else sendvalue = value; synth->mem.param[index] = value; if ((!global.libtest) || (index >= ACTIVE_DEVS)) synth->dispatch[index].routine(synth, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); else printf("dispatch[%p,%i](%i, %i, %i, %i, %i)\n", synth, index, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); return(0); } static void explorerMidi(guiSynth *synth, int fd, int chan, int c, int o, int v) { printf("explorerMidi(%i %i %i %i %i)\n", fd, chan, c, o, v); if ((synth->flags & OPERATIONAL) == 0) return; if (synth->dispatch[MEM_START + 14].other1 == MEM_START + 14) { int newchan; if (c == 1) { if ((newchan = synth->midichannel - 1) < 0) { synth->midichannel = 0; return; } } else { if ((newchan = synth->midichannel + 1) >= 16) { synth->midichannel = 15; return; } } if (global.libtest == 0) bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_MIDICHANNEL|newchan); synth->midichannel = newchan; displayText(synth, "CHAN", synth->midichannel + 1, DISPLAY1); } else { if (c == 1) { while (locations[--synth->dispatch[MEM_START + 15].other2].name[0] == '\0') { if (synth->dispatch[MEM_START + 15].other2 < 0) synth->dispatch[MEM_START + 15].other2 = 49; } } else { while (locations[++synth->dispatch[MEM_START + 15].other2].name[0] == '\0') { if (synth->dispatch[MEM_START + 15].other2 >= 49) synth->dispatch[MEM_START + 15].other2 = 0; } } displayText(synth, locations[synth->dispatch[MEM_START + 15].other2].name, synth->dispatch[MEM_START + 15].other2, DISPLAY2); if (synth->dispatch[MEM_START + 15].other1 == 1) { /*printf("PANEL X SELECTOR %i %i = %i %i\n", */ /*synth->dispatch[MEM_START + 15].other1, */ /*synth->dispatch[MEM_START + 15].other2, */ /*synth->dispatch[synth->dispatch[MEM_START + 15].other2].controller, */ /*synth->dispatch[synth->dispatch[MEM_START + 15].other2].operator); */ synth->dispatch[54].controller = synth->dispatch[ synth->dispatch[MEM_START + 15].other2].controller; synth->dispatch[54].operator = synth->dispatch[ synth->dispatch[MEM_START + 15].other2].operator; } else { /*printf("PANEL Y SELECTOR %i %i = %i %i\n", */ /*synth->dispatch[MEM_START + 15].other1, */ /*synth->dispatch[MEM_START + 15].other2, */ /*synth->dispatch[synth->dispatch[MEM_START + 15].other2].controller, */ /*synth->dispatch[synth->dispatch[MEM_START + 15].other2].operator); */ synth->dispatch[55].controller = synth->dispatch[ synth->dispatch[MEM_START + 15].other2].controller; synth->dispatch[55].operator = synth->dispatch[ synth->dispatch[MEM_START + 15].other2].operator; } } } static void explorerPanelSelect(guiSynth *synth, int fd, int chan, int c, int o, int v) { /* printf("explorerPanelSelect(%x, %i, %i, %i, %i, %i\n", */ /* synth, fd, chan, c, o, v); */ /* dispatch[MEM_START + 14] = dispatch[MEM_START + 15] */ if (synth->dispatch[MEM_START + 14].other2) { synth->dispatch[MEM_START + 14].other2 = 0; return; } if (synth->dispatch[MEM_START + 14].other1 != -1) { brightonEvent event; synth->dispatch[MEM_START + 14].other2 = 1; if (synth->dispatch[MEM_START + 14].other1 != c) event.value = 0; else event.value = 1; brightonParamChange(synth->win, synth->panel, synth->dispatch[MEM_START + 14].other1, &event); } displayText(synth, "CHAN", synth->midichannel + 1, DISPLAY1); if (c == MEM_START + 15) { if (synth->dispatch[MEM_START + 15].other1 > 1) synth->dispatch[MEM_START + 15].other1 = 0; switch (synth->dispatch[MEM_START + 15].other1) { case 0: default: displayText(synth, "PAN-X", synth->dispatch[MEM_START + 15].other2, DISPLAY1); break; case 1: displayText(synth, "PAN-Y", synth->dispatch[MEM_START + 15].other2, DISPLAY1); break; } synth->dispatch[MEM_START + 15].other1++; } synth->dispatch[MEM_START + 14].other1 = c; } /* static void explorerOsc3Transpose(guiSynth *synth) { if (synth->mem.param[23] != 0) bristolMidiSendMsg(global.controlfd, synth->sid, 2, 1, (int) (synth->mem.param[18] / 4)); else bristolMidiSendMsg(global.controlfd, synth->sid, 2, 1, (int) synth->mem.param[18]); } */ static void explorerFilterMode(guiSynth *synth, int fd, int chan, int o, int c, int v) { /* * If value is zero we need to configure two H/LPF and clear the MODE * flag (12/12). Otherwise set the flag and configure C/HPF, H/LPF. */ if (v == 0) { /* printf("LPF/LPF\n"); * FIlter 1 must change to type 4, Houvilainen LPF. */ bristolMidiSendMsg(global.controlfd, synth->sid, 4, 4, 4); bristolMidiSendMsg(global.controlfd, synth->sid, 4, 6, 0); } else { /* printf("HPF/LPF\n"); * FIlter 1 must change to type 0, Chamberlain and HPF */ bristolMidiSendMsg(global.controlfd, synth->sid, 4, 4, 0); bristolMidiSendMsg(global.controlfd, synth->sid, 4, 6, 2); } /* And the main routing flag for filter stereo panning */ bristolMidiSendMsg(global.controlfd, synth->sid, 12, 12, v); } static void explorerFilter(guiSynth *synth, int fd, int chan, int o, int c, int v) { int value; /* See if this is the key track or mod */ if (c == 3) { bristolMidiSendMsg(global.controlfd, synth->sid, 4, c, v); bristolMidiSendMsg(global.controlfd, synth->sid, 9, c, v); return; } if (c == 1) { /* Res goes to both LPF but not to the HPF. */ bristolMidiSendMsg(global.controlfd, synth->sid, 4, c, v); bristolMidiSendMsg(global.controlfd, synth->sid, 9, c, v); return; } /* * We have mod and res that just goes to each filter. * * Cutoff and spare are a function of the eachother. */ bristolMidiSendMsg(global.controlfd, synth->sid, 9, 0, (int) (synth->mem.param[34] * C_RANGE_MIN_1)); value = (synth->mem.param[34] + (synth->mem.param[35] - 0.5f)) * C_RANGE_MIN_1; if (value > C_RANGE_MIN_1) value = C_RANGE_MIN_1; else if (value < 0) value = 0; bristolMidiSendMsg(global.controlfd, synth->sid, 4, 0, value); /* bristolMidiSendMsg(global.controlfd, synth->sid, 4, 0, */ /* (int) (synth->mem.param[35] * C_RANGE_MIN_1)); */ } static void explorerRelease(guiSynth *synth, int fd, int chan, int o, int c, int v) { if ((c == 3) || (c == 5)) { /* Filter/APM env release */ if (synth->mem.param[53] != 0) bristolMidiSendMsg(global.controlfd, synth->sid, c, 3, v); else bristolMidiSendMsg(global.controlfd, synth->sid, c, 3, v / 10); } else { /* Selection switch */ if (synth->mem.param[53] != 0) { bristolMidiSendMsg(global.controlfd, synth->sid, 3, 3, (int) (synth->mem.param[42] * C_RANGE_MIN_1)); bristolMidiSendMsg(global.controlfd, synth->sid, 5, 3, (int) (synth->mem.param[47] * C_RANGE_MIN_1)); } else { bristolMidiSendMsg(global.controlfd, synth->sid, 3, 3, (int) (synth->mem.param[42] * C_RANGE_MIN_1 / 10)); bristolMidiSendMsg(global.controlfd, synth->sid, 5, 3, (int) (synth->mem.param[47] * C_RANGE_MIN_1 / 10)); } } } static void explorerGlide(guiSynth *synth) { if (synth->mem.param[52] != 0) bristolMidiSendMsg(global.controlfd, synth->sid, 11, 0, (int) (synth->mem.param[3] * C_RANGE_MIN_1)); else bristolMidiSendMsg(global.controlfd, synth->sid, 11, 0, 0); } /* * Any location initialisation required to run the callbacks. For bristol, this * will connect to the engine, and give it some base parameters. * May need to generate some application specific menus. * Will also then make specific requests to some of the devices to alter their * rendering. */ int explorerInit(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); dispatcher *dispatch; int i; if (synth == 0) { synth = findSynth(global.synths, 0); if (synth == 0) { printf("cannot init\n"); return(0); } } synth->win = win; printf("Initialise the explorer link to bristol: %p\n", synth->win); synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float)); synth->mem.count = DEVICE_COUNT; synth->mem.active = ACTIVE_DEVS; synth->dispatch = (dispatcher *) brightonmalloc(DEVICE_COUNT * sizeof(dispatcher)); dispatch = synth->dispatch; /* * We really want to have three connection mechanisms. These should be * 1. Unix named sockets. * 2. UDP sockets. * 3. MIDI pipe. */ if (!global.libtest) if ((synth->sid = initConnection(&global, synth)) < 0) return(-1); for (i = 0; i < DEVICE_COUNT; i++) synth->dispatch[i].routine = explorerMidiSendMsg; /* tune/glide */ dispatch[0].controller = 8; dispatch[0].operator = 0; dispatch[1].controller = 8; dispatch[1].operator = 1; dispatch[2].controller = 10; dispatch[2].operator = 0; dispatch[3].routine = (synthRoutine) explorerGlide; /* Bus mods */ dispatch[4].controller = 15; dispatch[4].operator = 0; dispatch[5].controller = 15; dispatch[5].operator = 1; dispatch[6].controller = 15; dispatch[6].operator = 2; dispatch[7].controller = 15; dispatch[7].operator = 3; dispatch[8].controller = 16; dispatch[8].operator = 0; dispatch[9].controller = 16; dispatch[9].operator = 1; dispatch[10].controller = 16; dispatch[10].operator = 2; dispatch[11].controller = 16; dispatch[11].operator = 3; /* Oscillators */ dispatch[12].controller = 0; dispatch[12].operator = 1; dispatch[13].controller = 0; dispatch[13].operator = 0; dispatch[14].controller = 1; dispatch[14].operator = 2; dispatch[15].controller = 1; dispatch[15].operator = 1; dispatch[16].controller = 1; dispatch[16].operator = 0; dispatch[17].controller = 2; dispatch[17].operator = 2; dispatch[18].controller = 2; dispatch[18].operator = 1; dispatch[19].controller = 2; dispatch[19].operator = 0; /* Osc options */ dispatch[20].controller = 12; dispatch[20].operator = 9; dispatch[21].controller = 12; dispatch[21].operator = 10; dispatch[22].controller = 12; dispatch[22].operator = 0; dispatch[23].controller = 12; dispatch[23].operator = 8; /* MIXER */ dispatch[24].controller = 14; dispatch[24].operator = 0; dispatch[25].controller = 0; dispatch[25].operator = 3; dispatch[26].controller = 1; dispatch[26].operator = 3; dispatch[27].controller = 2; dispatch[27].operator = 3; dispatch[28].controller = 12; dispatch[28].operator = 13; /* mixer flags */ dispatch[29].controller = 12; dispatch[29].operator = 5; dispatch[30].controller = 12; dispatch[30].operator = 2; dispatch[31].controller = 12; dispatch[31].operator = 3; dispatch[32].controller = 12; dispatch[32].operator = 4; dispatch[33].controller = 12; dispatch[33].operator = 6; /* Filter */ dispatch[34].controller = 4; dispatch[34].operator = 0; dispatch[35].controller = 12; dispatch[35].operator = 12; dispatch[36].controller = 4; dispatch[36].operator = 1; dispatch[37].controller = 4; dispatch[37].operator = 3; /* Filter spacing is now in the emulater, not the filter. We also need a */ /* filter param dispatcher to configure the two filters together. */ /* Dispatcher */ dispatch[34].routine = dispatch[35].routine = dispatch[36].routine = dispatch[37].routine = (synthRoutine) explorerFilter; dispatch[38].controller = 12; dispatch[38].operator = 12; dispatch[38].routine = (synthRoutine) explorerFilterMode; /* Filter ADSR */ dispatch[39].controller = 3; dispatch[39].operator = 0; dispatch[40].controller = 3; dispatch[40].operator = 1; dispatch[41].controller = 3; dispatch[41].operator = 2; dispatch[42].controller = 3; dispatch[42].operator = 3; dispatch[42].routine = (synthRoutine) explorerRelease; /* velocity from filter control */ dispatch[43].controller = 12; dispatch[43].operator = 11; /* Amp ADSR */ dispatch[44].controller = 5; dispatch[44].operator = 0; dispatch[45].controller = 5; dispatch[45].operator = 1; dispatch[46].controller = 5; dispatch[46].operator = 2; dispatch[47].controller = 5; dispatch[47].operator = 3; dispatch[47].routine = (synthRoutine) explorerRelease; dispatch[48].controller = 5; dispatch[48].operator = 5; /* volume, on/off */ dispatch[49].controller = 5; dispatch[49].operator = 4; dispatch[50].controller = 12; dispatch[50].operator = 1; dispatch[51].controller = 12; dispatch[51].operator = 7; dispatch[52].routine = (synthRoutine) explorerGlide; dispatch[53].controller = 6; dispatch[53].routine = (synthRoutine) explorerRelease; /* Touch panel */ dispatch[54].controller = 8; dispatch[54].operator = 0; dispatch[55].controller = 4; dispatch[55].operator = 0; /* memory */ dispatch[MEM_START].operator = 0; dispatch[MEM_START].controller = MEM_START; dispatch[MEM_START + 1].operator = 1; dispatch[MEM_START + 1].controller = MEM_START + 1; dispatch[MEM_START + 2].operator = 2; dispatch[MEM_START + 2].controller = MEM_START + 2; dispatch[MEM_START + 3].operator = 3; dispatch[MEM_START + 3].controller = MEM_START + 3; dispatch[MEM_START + 4].operator = 4; dispatch[MEM_START + 4].controller = MEM_START + 4; dispatch[MEM_START + 5].operator = 5; dispatch[MEM_START + 5].controller = MEM_START + 5; dispatch[MEM_START + 6].operator = 6; dispatch[MEM_START + 6].controller = MEM_START + 6; dispatch[MEM_START + 7].operator = 7; dispatch[MEM_START + 7].controller = MEM_START + 7; dispatch[MEM_START + 8].operator = 8; dispatch[MEM_START + 8].controller = MEM_START + 8; dispatch[MEM_START + 9].operator = 9; dispatch[MEM_START + 9].controller = MEM_START + 9; dispatch[MEM_START + 10].controller = 1; dispatch[MEM_START + 11].controller = 2; dispatch[MEM_START + 16].controller = 3; dispatch[MEM_START + 17].controller = 4; dispatch[MEM_START + 0].routine = dispatch[MEM_START + 1].routine = dispatch[MEM_START + 2].routine = dispatch[MEM_START + 3].routine = dispatch[MEM_START + 4].routine = dispatch[MEM_START + 5].routine = dispatch[MEM_START + 6].routine = dispatch[MEM_START + 7].routine = dispatch[MEM_START + 8].routine = dispatch[MEM_START + 9].routine = dispatch[MEM_START + 10].routine = dispatch[MEM_START + 11].routine = dispatch[MEM_START + 16].routine = dispatch[MEM_START + 17].routine = (synthRoutine) explorerMemory; /* midi */ dispatch[MEM_START + 12].controller = 2; dispatch[MEM_START + 13].controller = 1; dispatch[MEM_START + 12].routine = dispatch[MEM_START + 13].routine = (synthRoutine) explorerMidi; /* midi/panel selectors */ dispatch[MEM_START + 14].controller = MEM_START + 14; dispatch[MEM_START + 15].controller = MEM_START + 15; dispatch[MEM_START + 14].routine = dispatch[MEM_START + 15].routine = (synthRoutine) explorerPanelSelect; /* No velocity on filter contour, fixed gain */ bristolMidiSendMsg(global.controlfd, synth->sid, 7, 0, 16000); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 5, 0); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 4, 16383); return(0); } /* * This will be called to make any routine specific parameters available. */ int explorerConfigure(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); brightonEvent event; if (synth == 0) { printf("problems going operational\n"); return(-1); } if (synth->flags & OPERATIONAL) return(0); printf("going operational\n"); synth->flags |= OPERATIONAL; synth->keypanel = 1; synth->keypanel2 = -1; synth->transpose = 36; displayText(synth, "CHAN", synth->midichannel + 1, DISPLAY1); loadMemory(synth, "explorer", 0, synth->location, synth->mem.active, FIRST_DEV, 0); displayText(synth, "PRG", synth->location, DISPLAY2); brightonPut(win, "bitmaps/blueprints/explorershade.xpm", 0, 0, win->width, win->height); /* * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only * occurs on first paint, so we suppress the first paint, and then request * an expose here. */ event.type = BRIGHTON_EXPOSE; event.intvalue = 1; brightonParamChange(synth->win, KEY_PANEL, -1, &event); configureGlobals(synth); return(0); } bristol-0.60.11/brighton/brightonSID2.h0000644000175000017500000000360511746476475014532 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ typedef struct Sid2mod { float param[6]; float touch; } sid2mod; typedef struct Sid2dest { float osc1PWM; float osc1Freq; float osc2PWM; float osc2Freq; float osc3PWM; float osc3Freq; float filter; } sid2dest; typedef struct Sid2Osc { float param[16]; } sid2Osc; typedef struct Sid2Pmod { float opt1; float opt2; float opt3; float opt4; float opt5; float opt6; float opt7; sid2mod osc; sid2mod env; sid2mod prod; float ppad[7]; sid2dest destbus[6]; } sid2Pmod; typedef struct Sid2Voice { sid2Osc osc[3]; float filter[8]; float pan; float volume; sid2Pmod mod; } sid2Voice; /* * This will mimic the locations structure which holds GUI settings, then a * separate set of structures for the poly voice programming. 58 + 9 + 27 + 29 + 7 + 28 + 42 + 24 + 5 + 8 + 16 + 1 */ typedef struct Sid2Mem { sid2Voice guivoice; float mode[9]; // Break these out float mmods1[27]; float mmods2[29]; float pad2[23]; float version; float modShadow[5]; float globals[7]; float masterVolume; float memMidi[16]; float display; /* * These are the actual voice memories */ sid2Voice vmem[5]; } sid2Mem; bristol-0.60.11/brighton/brightonRoadRunner.c0000644000175000017500000006576111746476475016116 00000000000000 /* Check out parameter to effects gain of tri wave bit error in triwave touch response * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include #include "brighton.h" #include "brightonMini.h" #include "brightoninternals.h" static int roadrunnerInit(); static int roadrunnerConfigure(); static int roadrunnerCallback(brightonWindow *, int, int, float); static int midiCallback(brightonWindow *, int, int, float); extern guimain global; static int dc, shade_id; #include "brightonKeys.h" #define OPTS_PANEL 0 #define MOD_PANEL 4 #define KEY_PANEL 2 #define MEM_PANEL 3 #define MODS_COUNT 4 #define OPTS_COUNT 22 #define MEM_COUNT 14 #define MODS_START 0 #define OPTS_START MODS_COUNT #define MEM_START (OPTS_COUNT + OPTS_START) /* We use '+2' so that bass and treble get saved with memory */ #define ACTIVE_DEVS (MODS_COUNT + OPTS_COUNT + 2) #define DEVICE_COUNT (ACTIVE_DEVS + MEM_COUNT - 2) /* * This structure is for device definition. The structure is defined in * include/brighton.h, further definitions in brighton/brightonDevtable.h and * include/brightoninternals.h * * typedef int (*brightonCallback)(int, float); * typedef struct BrightonLocations { * int device; 0=rotary, 1=scale, etc. * float relx, rely; relative position with regards to 1000 by 1000 window * float relw, relh; relative height. * int from, to; * brightonCallback callback; specific to this dev * char *image; bitmap. If zero take a device default. * int flags; * } brightonLocations; * * This example is for a roadrunnerBristol type synth interface. */ #define R1 400 #define C1 15 #define C2 (C1 + 114) #define C3 (C2 + 114) #define C4 (C3 + 114) #define W1 100 #define L1 600 static brightonLocations modspanel[MODS_COUNT] = { {"Tune", 1, C1, R1, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_VERTICAL|BRIGHTON_REVERSE|BRIGHTON_NOSHADOW|BRIGHTON_NOTCH}, {"LFO Frequency", 1, C2, R1, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_VERTICAL|BRIGHTON_REVERSE|BRIGHTON_NOSHADOW}, {"Vibrato", 1, C3, R1, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_VERTICAL|BRIGHTON_REVERSE|BRIGHTON_NOSHADOW}, {"Volume", 1, C4, R1, W1, L1, 0, 1, 0, 0, 0, BRIGHTON_VERTICAL|BRIGHTON_REVERSE|BRIGHTON_NOSHADOW}, }; #define S1 200 #define oW1 35 #define oL1 500 #define oC1 16 #define oC2 66 #define oC3 116 #define oC4 172 #define oC5 220 #define oC6 270 #define oC7 735 #define oC8 782 #define oC9 835 #define oC10 884 #define oC11 933 #define oC12 592 #define oC13 642 #define oC14 692 #define oC15 500 #define oC16 549 #define WFS 308 #define oC50 (WFS + 0) #define oC51 (WFS + 28) #define oC52 (WFS + 69) #define oC53 (WFS + 97) #define oC54 (WFS + 138) #define oC55 (WFS + 166) #define oC56 (WFS + 202) #define oR1 140 #define oR2 300 #define oR3 500 #define oR4 700 static brightonLocations options[OPTS_COUNT] = { /* Osc parameters */ {"Detune", 0, oC1, oR1, oW1, oL1, 0, 1, 0, 0, 0, BRIGHTON_REVERSE|BRIGHTON_NOTCH}, {"PulseWidth", 0, oC2, oR1, oW1, oL1, 0, 1, 0, 0, 0, 0}, {"PulseWidthMod", 0, oC3, oR1, oW1, oL1, 0, 1, 0, 0, 0, 0}, /* waveforms */ {"Bass 1", 2, oC50, 100, 27, 600, 0, 1, 0, "bitmaps/buttons/rockersmoothBB.xpm", "bitmaps/buttons/rockersmoothBBd.xpm", 0}, {"Bass 2", 2, oC51, 100, 27, 600, 0, 1, 0, "bitmaps/buttons/rockersmoothBB.xpm", "bitmaps/buttons/rockersmoothBBd.xpm", 0}, {"Mid 1", 2, oC52, 100, 27, 600, 0, 1, 0, "bitmaps/buttons/rockersmoothBBL.xpm", "bitmaps/buttons/rockersmoothBBLd.xpm", 0}, {"Mid 2", 2, oC53, 100, 27, 600, 0, 1, 0, "bitmaps/buttons/rockersmoothBBL.xpm", "bitmaps/buttons/rockersmoothBBLd.xpm", 0}, {"Treble 1", 2, oC54, 100, 27, 600, 0, 1, 0, "bitmaps/buttons/rockersmoothBC.xpm", "bitmaps/buttons/rockersmoothBCd.xpm", 0}, {"Treble 2", 2, oC55, 100, 27, 600, 0, 1, 0, "bitmaps/buttons/rockersmoothBC.xpm", "bitmaps/buttons/rockersmoothBCd.xpm", BRIGHTON_NOSHADOW}, /* The remaining envelope parameters */ {"Decay", 0, oC4, oR1, oW1, oL1, 0, 1, 0, 0, 0, 0}, {"Release", 0, oC5, oR1, oW1, oL1, 0, 1, 0, 0, 0, 0}, {"TouchSense", 2, oC6, 100, 27, 600, 0, 1, 0, "bitmaps/buttons/rockersmoothBW.xpm", "bitmaps/buttons/rockersmoothBWd.xpm", 0}, /* Tremelo */ {"Tremelo", 0, oC16, oR1, oW1, oL1, 0, 1, 0, 0, 0, 0}, /* Chorus */ {"Choris Wet", 0, oC7, oR1, oW1, oL1, 0, 1, 0, 0, 0, 0}, {"ChorusD1", 0, oC8, oR1, oW1, oL1, 0, 1, 0, 0, 0, 0}, {"ChorusD2", 0, oC9, oR1, oW1, oL1, 0, 1, 0, 0, 0, 0}, {"ChorusSpeed", 0, oC10, oR1, oW1, oL1, 0, 1, 0, 0, 0, 0}, /* Reverb */ {"Reberb Wet", 0, oC11, oR1, oW1, oL1, 0, 1, 0, 0, 0, 0}, {"Reverb Cross", 0, oC12, oR1, oW1, oL1, 0, 1, 0, 0, 0, 0}, {"Reverb Feed", 0, oC13, oR1, oW1, oL1, 0, 1, 0, 0, 0, 0}, {"Reverg Length", 0, oC14, oR1, oW1, oL1, 0, 1, 0, 0, 0, 0}, /* Single/Multi LFO */ {"LFO Multi", 2, oC56, 100, 27, 600, 0, 1, 0, "bitmaps/buttons/rockersmoothBGR.xpm", "bitmaps/buttons/rockersmoothBGRd.xpm", 0}, }; #define mR1 100 #define mR2 600 #define mR3 820 #define mC0 (120) #define mC1 (mC0 + 129) #define mC2 (mC1 + 129) #define mC3 (mC2 + 129) #define mC4 (mC3 + 129) #define mC4s (mC4 + 129) #define mC5 50 #define mC6 550 #define mC7 650 #define mC8 780 #define mC9 900 #define mC11 100 #define mC12 255 #define mC13 410 #define mC14 565 #define mC15 720 #define mC16 874 #define S3 100 #define S4 80 #define S5 120 #define S6 150 static brightonLocations mem[MEM_COUNT] = { {"Bass", 0, mC2 - 70, mR2, 260, 260, 0, 1, 0, 0, 0, 0}, {"Treble", 0, mC4 - 100, mR2, 260, 260, 0, 1, 0, 0, 0, 0}, /* memories */ {"Mem-0", 2, mC0, mR1, 125, 400, 0, 1, 0, "bitmaps/buttons/rockersmoothBB.xpm", "bitmaps/buttons/rockersmoothBBd.xpm", 0}, /* -127 65 */ {"Mem-1", 2, mC1, mR1, 125, 400, 0, 1, 0, "bitmaps/buttons/rockersmoothBG.xpm", "bitmaps/buttons/rockersmoothBGd.xpm", 0}, {"Mem-2", 2, mC2, mR1, 125, 400, 0, 1, 0, "bitmaps/buttons/rockersmoothBBL.xpm", "bitmaps/buttons/rockersmoothBBLd.xpm", 0}, /* 190 31 -3 */ {"Mem-3", 2, mC3, mR1, 125, 400, 0, 1, 0, "bitmaps/buttons/rockersmoothBGR.xpm", "bitmaps/buttons/rockersmoothBGRd.xpm", 0}, {"Mem-4", 2, mC4, mR1, 125, 400, 0, 1, 0, "bitmaps/buttons/rockersmoothBC.xpm", "bitmaps/buttons/rockersmoothBCd.xpm", 0}, {"Mem-5", 2, mC4s, mR1, 125, 400, 0, 1, 0, "bitmaps/buttons/rockersmoothBW.xpm", "bitmaps/buttons/rockersmoothBWd.xpm", 0}, {"", 1, 0, 0, 50, 50, 0, 1, 0, "bitmaps/knobs/sliderpointL.xpm", 0, BRIGHTON_VERTICAL|BRIGHTON_REVERSE|BRIGHTON_WITHDRAWN}, {"", 1, 0, 0, 50, 50, 0, 1, 0, "bitmaps/knobs/sliderpointL.xpm", 0, BRIGHTON_VERTICAL|BRIGHTON_REVERSE|BRIGHTON_WITHDRAWN}, /* mem U/D, midi U/D, Load + Save */ {"", 2, mC0 + 35, mR3, S4, S6, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, {"", 2, mC0 + 35, mR2, S4, S6, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, {"", 2, mC8 + 7, mR3, S4, S6, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_NOSHADOW}, {"", 2, mC8 + 7, mR2, S4, S6, 0, 1, 0, "bitmaps/buttons/pressoffo.xpm", "bitmaps/buttons/pressono.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, }; int singleclick = 0; /* * Should try and make this one as generic as possible, and try to use it as * a general memory routine. has Midi u/d, mem u/d, load/save and a display. */ static int memCallback(brightonWindow* win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); /* printf("memCallback(%i, %i, %f) %i, %s\n", panel, index, value, */ /* synth->mem.active, synth->resources->name); */ if (synth->flags & SUPPRESS) return(0); /* * The first ten buttons are exclusive highlighting, we use the first mem * pointer to handle this. */ if (synth->dispatch[MEM_START].other2) { synth->dispatch[MEM_START].other2 = 0; return(0); } if (index < 2) { bristolMidiSendMsg(global.controlfd, synth->sid, 2 - index, 3, (int) (value * C_RANGE_MIN_1)); return(0); } if (index == 13) { if (brightonDoubleClick(dc)) { synth->location = synth->dispatch[MEM_START].other1 - 2; saveMemory(synth, "roadrunner", 0, synth->bank + synth->location,0); singleclick = 0; } else { singleclick = 1; } return(0); } if (index < 8) { int i; brightonEvent event; event.command = BRIGHTON_PARAMCHANGE; event.type = BRIGHTON_FLOAT; event.value = 0; /* * This is a numeric. We need to force exclusion. */ if (synth->dispatch[MEM_START].other1 != -1) { synth->dispatch[MEM_START].other2 = 1; if (synth->dispatch[MEM_START].other1 != index) event.value = 0; else event.value = 1; brightonParamChange(synth->win, panel, synth->dispatch[MEM_START].other1, &event); } synth->location = index - 2; /* * If the last button pressed was the save button (just once) then save * to the new location. */ if (singleclick) { saveMemory(synth, "roadrunner", 0, synth->bank + synth->location,0); singleclick = 0; synth->dispatch[MEM_START].other1 = index; return(0); } loadMemory(synth, "roadrunner", 0, synth->bank + synth->location, synth->mem.active, 0, BRISTOL_NOCALLS|BRISTOL_FORCE); /* * We have loaded the memory but cannot call the devices as they have * various panels. */ for (i = 0; i < MODS_COUNT; i++) { event.value = synth->mem.param[i]; brightonParamChange(synth->win, MOD_PANEL, i, &event); } for (; i < MEM_START; i++) { event.value = synth->mem.param[i]; brightonParamChange(synth->win, OPTS_PANEL, i - OPTS_START, &event); } event.value = synth->mem.param[i]; brightonParamChange(synth->win, MEM_PANEL, i - MEM_START, &event); i++; event.value = synth->mem.param[i]; brightonParamChange(synth->win, MEM_PANEL, i - MEM_START, &event); synth->dispatch[MEM_START].other1 = index; } else { int newchan; /* * This is a control button. */ switch(index) { case 10: /* * Midi Down */ if ((newchan = synth->midichannel - 1) < 0) { synth->midichannel = 0; return(0); } if (global.libtest) { printf("midi chan %i\n", newchan); synth->midichannel = newchan; return(0); } bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_MIDICHANNEL|newchan); synth->midichannel = newchan; break; case 11: /* * Midi Up */ if ((newchan = synth->midichannel + 1) > 15) { synth->midichannel = 15; return(0); } if (global.libtest) { printf("midi chan %i\n", newchan); synth->midichannel = newchan; return(0); } bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_MIDICHANNEL|newchan); synth->midichannel = newchan; break; } } singleclick = 0; return(0); } /* * This is a set of globals for the main window rendering. Again taken from * include/brighton.h */ brightonApp roadrunnerApp = { "roadrunner", 0, /* no blueprint on wood background. */ "bitmaps/textures/leather.xpm", 0, roadrunnerInit, roadrunnerConfigure, /* 3 callbacks */ midiCallback, destroySynth, {-1, 0, 2, 2, 5, 520, 0, 0}, 660, 138, 0, 0, 7, /* panel count */ { { "Options panel", "bitmaps/blueprints/roadrunneropts.xpm", "bitmaps/textures/metal5.xpm", /* flags */ 0x020, 0, 0, roadrunnerCallback, /*30, 50, 940, 365, */ 15, 9, 970, 300, OPTS_COUNT, options }, { "RoadRunner", 0, "bitmaps/textures/leather.xpm", /* flags */ 0, 0, 0, 0, 15, 9, 970, 300, 0, 0 }, { "Keyboard", 0, "bitmaps/newkeys/kbg.xpm", /* flags */ 0x020|BRIGHTON_STRETCH, 0, 0, keyCallback, 204, 305, 790, 555, KEY_COUNT, keysprofile }, { "Memory Panel", 0, "bitmaps/textures/metal5.xpm", 0, 0, 0, roadrunnerCallback, 15, 300, 189, 560, MEM_COUNT, mem }, { "Front Panel Mods", "bitmaps/blueprints/roadrunnermods.xpm", 0, 0, 0, 0, roadrunnerCallback, 15, 860, 970, 140, MODS_COUNT, modspanel, }, { "Metal Side", 0, "bitmaps/textures/metal4.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 0, 0, 15, 1000, 0, 0 }, { "Metal Side", 0, "bitmaps/textures/metal4.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 985, 0, 15, 1000, 0, 0 }, } }; /*static dispatcher dispatch[DEVICE_COUNT]; */ static int midiCallback(brightonWindow *win, int controller, int value, float n) { guiSynth *synth = findSynth(global.synths, win); printf("midi callback: %x, %i\n", controller, value); switch(controller) { case MIDI_PROGRAM: printf("midi program: %x, %i\n", controller, value); synth->location = value; loadMemory(synth, synth->resources->name, 0, synth->bank + synth->location, synth->mem.active, 0, 0); break; case MIDI_BANK_SELECT: printf("midi banksel: %x, %i\n", controller, value); synth->bank = value; break; } return(0); } static void panelSwitch(guiSynth *id, int fd, int chan, int cont, int op, int value) { brightonEvent event; /* * If the sendvalue is zero, then withdraw the opts window, draw the * slider window, and vice versa. */ if (value == 0) { event.type = BRIGHTON_EXPOSE; event.intvalue = 0; brightonParamChange(id->win, 0, -1, &event); event.intvalue = 1; brightonParamChange(id->win, 1, -1, &event); shade_id = brightonPut(id->win, "bitmaps/blueprints/roadrunnershade.xpm", 0, 0, id->win->width, id->win->height); } else { event.type = BRIGHTON_EXPOSE; event.intvalue = 0; brightonParamChange(id->win, 1, -1, &event); event.intvalue = 1; brightonParamChange(id->win, 0, -1, &event); brightonRemove(id->win, shade_id); } } static int roadrunnerMidiNull(void *synth, int fd, int chan, int c, int o, int v) { /* printf("%i, %i, %i\n", c, o, v); */ return(0); } static int roadrunnerMidiDetune(guiSynth *synth, int fd, int chan, int c, int o, int v) { if ((v = 8192 - v) >= 8192) v = 8191; if (v <= -8191) v = -8191; bristolMidiSendMsg(global.controlfd, synth->sid, 0, 2, 8192); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 2, 8192 + v); bristolMidiSendMsg(global.controlfd, synth->sid, 2, 2, 8192 - v); return(0); } static int roadrunnerMidiWF(guiSynth *synth, int fd, int chan, int c, int o, int v) { int cont, square = 0, tri = 0, ramp = 0; /* * Find out which pair this is, B/M/T, if they are both up then select * a triangular wave, otherwise they represent their respective waves. */ switch (c) { default: case OPTS_START + 3: case OPTS_START + 4: /* Bass oscillator */ cont = 30; switch ((int) synth->mem.param[OPTS_START + 3]) { case 0: if (synth->mem.param[OPTS_START + 4] == 0) /* * Tri on, rest off */ tri = 1; else /* * Tri off, ramp off, square on */ square = 1; break; default: if (synth->mem.param[OPTS_START + 4] == 0) /* * ramp on, rest off */ ramp = 1; else { /* * Tri off, ramp on, square on */ ramp = 1; square = 1; } break; } break; case OPTS_START + 5: case OPTS_START + 6: /* Oscillator */ cont = 10; switch ((int) synth->mem.param[OPTS_START + 5]) { case 0: if (synth->mem.param[OPTS_START + 6] != 0) /* * Tri off, ramp off, square on */ square = 1; break; default: if (synth->mem.param[OPTS_START + 6] == 0.0) /* * ramp on, rest off */ ramp = 1; else { /* * Tri off, ramp on, square on */ ramp = 1; square = 1; } break; } break; case OPTS_START + 7: case OPTS_START + 8: /* Treble oscillator */ cont = 20; switch ((int) synth->mem.param[OPTS_START + 7]) { case 0: if (synth->mem.param[OPTS_START + 8] == 0) /* * Tri on, rest off */ tri = 1; else /* * Tri off, ramp off, square on */ square = 1; break; default: if (synth->mem.param[OPTS_START + 8] == 0) /* * ramp on, rest off */ ramp = 1; else { /* * Tri off, ramp on, square on */ ramp = 1; square = 1; } break; } break; } bristolMidiSendMsg(global.controlfd, synth->sid, 126, cont + 0, ramp); bristolMidiSendMsg(global.controlfd, synth->sid, 126, cont + 1, square); bristolMidiSendMsg(global.controlfd, synth->sid, 126, cont + 2, tri); return(0); } static int roadrunnerMidiPW(guiSynth *synth, int fd, int chan, int c, int o, int v) { bristolMidiSendMsg(global.controlfd, synth->sid, 0, 0, v / 2); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 0, v * 3 / 4); bristolMidiSendMsg(global.controlfd, synth->sid, 2, 0, v); return(0); } static int roadrunnerMidiSendMsg(void *synth, int fd, int chan, int c, int o, int v) { /* printf("%i, %i, %i\n", c, o, v); */ bristolMidiSendMsg(fd, chan, c, o, v); return(0); } /* * For the sake of ease of use, links have been placed here to be called * by any of the devices created. They would be better in some other file, * perhaps with this as a dispatch. * * Param refers to the device index in the locations table given below. */ static int roadrunnerCallback(brightonWindow *win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); int sendvalue; if (synth == 0) return(0); if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0)) return(0); if (roadrunnerApp.resources[panel].devlocn[index].to == 1) sendvalue = value * C_RANGE_MIN_1; else sendvalue = value; switch (panel) { case OPTS_PANEL: index+=OPTS_START; break; case MOD_PANEL: break; case MEM_PANEL: if (index == 12) { panelSwitch(synth, 0, 0, 0, 0, value); return(0); } else if (index > 1) { memCallback(win, panel, index, value); return(0); } else index+=MEM_START; } synth->mem.param[index] = value; if ((!global.libtest) || (index >= ACTIVE_DEVS)) synth->dispatch[index].routine(synth, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #define DEBUG #ifdef DEBUG else printf("dispatch[%p,%i](%i, %i, %i, %i, %i)\n", synth, index, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #endif return(0); } /* * Any location initialisation required to run the callbacks. For bristol, this * will connect to the engine, and give it some base parameters. * May need to generate some application specific menus. * Will also then make specific requests to some of the devices to alter their * rendering. */ static int roadrunnerInit(brightonWindow* win) { guiSynth *synth = findSynth(global.synths, win); dispatcher *dispatch; int i; if (synth == 0) { synth = findSynth(global.synths, 0); if (synth == 0) { printf("cannot init\n"); return(0); } } synth->win = win; printf("Initialise the roadrunner link to bristol: %p\n", synth->win); synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float)); synth->mem.count = DEVICE_COUNT; synth->mem.active = ACTIVE_DEVS; synth->dispatch = (dispatcher *) brightonmalloc(DEVICE_COUNT * sizeof(dispatcher)); dispatch = synth->dispatch; /* * We really want to have three connection mechanisms. These should be * 1. Unix named sockets. * 2. UDP sockets. * 3. MIDI pipe. */ if (!global.libtest) if ((synth->sid = initConnection(&global, synth)) < 0) return(-1); for (i = 0; i < DEVICE_COUNT; i++) synth->dispatch[i].routine = roadrunnerMidiNull; /* Front panel - tune, lfo, vibrato, volume */ synth->dispatch[MODS_START + 0].controller = 126; /* Tuning */ synth->dispatch[MODS_START + 0].operator = 1; synth->dispatch[MODS_START + 1].controller = 5; /* LFO frequency */ synth->dispatch[MODS_START + 1].operator = 0; synth->dispatch[MODS_START + 2].controller = 126; /* vibrato */ synth->dispatch[MODS_START + 2].operator = 7; synth->dispatch[MODS_START + 3].controller = 3; /* gain */ synth->dispatch[MODS_START + 3].operator = 4; synth->dispatch[MODS_START + 0].routine = synth->dispatch[MODS_START + 1].routine = synth->dispatch[MODS_START + 2].routine = synth->dispatch[MODS_START + 3].routine = roadrunnerMidiSendMsg; /* EQ controls from memory panel - not in memories */ synth->dispatch[MEM_START + 0].controller = 2; /* Bass gain */ synth->dispatch[MEM_START + 0].operator = 3; synth->dispatch[MEM_START + 1].controller = 1; /* Treble gain */ synth->dispatch[MEM_START + 1].operator = 3; synth->dispatch[MEM_START + 0].routine = synth->dispatch[MEM_START + 1].routine = roadrunnerMidiSendMsg; /* * The rest are from the options panel that is normally hidden. */ synth->dispatch[OPTS_START + 0].routine = (synthRoutine) roadrunnerMidiDetune; synth->dispatch[OPTS_START + 1].routine = (synthRoutine) roadrunnerMidiPW; synth->dispatch[OPTS_START + 2].controller = 126; /* PWM and LFO */ synth->dispatch[OPTS_START + 2].operator = 3; /* Waveforms */ synth->dispatch[OPTS_START + 3].controller = OPTS_START + 3; synth->dispatch[OPTS_START + 4].controller = OPTS_START + 4; synth->dispatch[OPTS_START + 5].controller = OPTS_START + 5; synth->dispatch[OPTS_START + 6].controller = OPTS_START + 6; synth->dispatch[OPTS_START + 7].controller = OPTS_START + 7; synth->dispatch[OPTS_START + 8].controller = OPTS_START + 8; synth->dispatch[OPTS_START + 3].routine = synth->dispatch[OPTS_START + 4].routine = synth->dispatch[OPTS_START + 5].routine = synth->dispatch[OPTS_START + 6].routine = synth->dispatch[OPTS_START + 7].routine = synth->dispatch[OPTS_START + 8].routine = (synthRoutine) roadrunnerMidiWF; synth->dispatch[OPTS_START + 9].controller = 3; /* Env - 2 parameters */ synth->dispatch[OPTS_START + 9].operator = 1; synth->dispatch[OPTS_START + 10].controller = 3; synth->dispatch[OPTS_START + 10].operator = 3; synth->dispatch[OPTS_START + 11].controller = 3; synth->dispatch[OPTS_START + 11].operator = 5; synth->dispatch[OPTS_START + 12].controller = 126; /* Tremelo */ synth->dispatch[OPTS_START + 12].operator = 8; /* Almost done effects - a couple may have to be compound parameters */ synth->dispatch[OPTS_START + 13].controller = 98; /* Effects */ synth->dispatch[OPTS_START + 13].operator = 0; synth->dispatch[OPTS_START + 14].controller = 98; /* Effects */ synth->dispatch[OPTS_START + 14].operator = 1; synth->dispatch[OPTS_START + 15].controller = 98; /* Effects */ synth->dispatch[OPTS_START + 15].operator = 2; synth->dispatch[OPTS_START + 16].controller = 98; /* Effects */ synth->dispatch[OPTS_START + 16].operator = 3; synth->dispatch[OPTS_START + 17].controller = 99; /* Effects */ synth->dispatch[OPTS_START + 17].operator = 0; synth->dispatch[OPTS_START + 18].controller = 99; /* Effects */ synth->dispatch[OPTS_START + 18].operator = 1; synth->dispatch[OPTS_START + 19].controller = 99; /* Effects */ synth->dispatch[OPTS_START + 19].operator = 2; synth->dispatch[OPTS_START + 20].controller = 99; /* Effects */ synth->dispatch[OPTS_START + 20].operator = 3; synth->dispatch[OPTS_START + 21].controller = 126; /* Multi LFO */ synth->dispatch[OPTS_START + 21].operator = 4; synth->dispatch[OPTS_START + 2].routine = synth->dispatch[OPTS_START + 9].routine = synth->dispatch[OPTS_START + 10].routine = synth->dispatch[OPTS_START + 11].routine = synth->dispatch[OPTS_START + 12].routine = synth->dispatch[OPTS_START + 13].routine = synth->dispatch[OPTS_START + 14].routine = synth->dispatch[OPTS_START + 15].routine = synth->dispatch[OPTS_START + 16].routine = synth->dispatch[OPTS_START + 17].routine = synth->dispatch[OPTS_START + 19].routine = synth->dispatch[OPTS_START + 19].routine = synth->dispatch[OPTS_START + 20].routine = synth->dispatch[OPTS_START + 21].routine = roadrunnerMidiSendMsg; /* * These will be replaced by some opts controllers. We need to tie the * envelope parameters for decay, sustain. We need to fix a few parameters * of the oscillators too - transpose, tune and gain. */ bristolMidiSendMsg(global.controlfd, synth->sid, 3, 1, 10); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 2, 16382); /* Oscillators */ bristolMidiSendMsg(global.controlfd, synth->sid, 0, 3, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 3, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 1, 3); bristolMidiSendMsg(global.controlfd, synth->sid, 2, 1, 1); return(0); } /* * This will be called to make any routine specific parameters available. */ static int roadrunnerConfigure(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); brightonEvent event; if (synth == 0) { printf("problems going operational\n"); return(-1); } if (synth->flags & OPERATIONAL) return(0); printf("going operational\n"); synth->flags |= OPERATIONAL; synth->keypanel = KEY_PANEL; synth->keypanel2 = -1; synth->transpose = 36; /* * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only * occurs on first paint, so we suppress the first paint, and then request * an expose here. */ event.type = BRIGHTON_EXPOSE; event.intvalue = 1; brightonParamChange(synth->win, KEY_PANEL, -1, &event); configureGlobals(synth); shade_id = brightonPut(synth->win, "bitmaps/blueprints/roadrunnershade.xpm", 0, 0, synth->win->width, synth->win->height); /* Fix the env attack and sustain */ bristolMidiSendMsg(global.controlfd, synth->sid, 3, 0, 2); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 2, 0); /* Fix the pulsewidths of the first two osc */ bristolMidiSendMsg(global.controlfd, synth->sid, 0, 0, 8192); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 0, 4096); /* detune all oscs just a small amount */ bristolMidiSendMsg(global.controlfd, synth->sid, 0, 2, 8192); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 2, 8292); bristolMidiSendMsg(global.controlfd, synth->sid, 2, 2, 8092); /* LFO to restart on NOTE_ON */ bristolMidiSendMsg(global.controlfd, synth->sid, 5, 1, 8092); /* Configure no split point */ bristolMidiSendMsg(global.controlfd, synth->sid, 126, 5, 127); bristolMidiSendMsg(global.controlfd, synth->sid, 126, 6, 0); event.command = BRIGHTON_PARAMCHANGE; event.type = BRIGHTON_FLOAT; event.value = 1; panelSwitch(synth, 0, 0, 0, 0, 1); brightonParamChange(synth->win, MEM_PANEL, 2, &event); panelSwitch(synth, 0, 0, 0, 0, 0); loadMemory(synth, "roadrunner", 0, 0, synth->mem.active-6, 0, 0); synth->dispatch[MEM_START].other1 = 2; synth->dispatch[MEM_START].other2 = 0; dc = brightonGetDCTimer(win->dcTimeout); return(0); } bristol-0.60.11/brighton/brightonArp2600.c0000644000175000017500000015063611746476475015065 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* ARP Arp2600 */ #include #include "brighton.h" #include "brightonMini.h" #include "brightoninternals.h" static int arp2600Init(); static int arp2600Configure(); static int arp2600Callback(brightonWindow *, int, int, float); /*static int keyCallback(void *, int, int, float); */ static int arp2600MidiCallback(brightonWindow *, int, int, float); extern guimain global; /* #include "brightonKeys.h" */ #define DEVICE_COUNT 201 #define ARP_OUTPUTS 40 #define ARP_INPUTS 60 #define OUTPUT_START 82 #define ACTIVE_DEVS (OUTPUT_START + ARP_OUTPUTS) #define INPUT_START ACTIVE_DEVS #define MEM_START (DEVICE_COUNT - 19) #define MIDI_START (MEM_START + 14) #define DISPLAY_DEV (DEVICE_COUNT - 2) #define DISPLAY_DEV2 (DEVICE_COUNT - 1) #define KEY_PANEL 1 static int oselect; static struct { int input; int id; /* From graphical interface. */ } links[ARP_OUTPUTS]; #define CDIFF 30 #define CDIFF2 12 #define CDIFF3 24 #define CDIFF4 23 #define CDIFF5 20 #define C0 25 #define C1 47 #define C2 67 #define C3 110 #define C4 (C3 + CDIFF) #define C5 (C4 + CDIFF3) #define C6 (C5 + CDIFF3) #define C7 (C6 + CDIFF3) #define C8 (C7 + CDIFF) #define C9 (C8 + CDIFF3) #define C10 (C9 + CDIFF3 - 1) #define C11 (C10 + CDIFF3) #define C12 (C11 + CDIFF3) #define C13 (C12 + CDIFF + 1) #define C14 (C13 + CDIFF3) #define C15 (C14 + CDIFF3) #define C16 (C15 + CDIFF3) #define C17 (C16 + CDIFF3 - 1) #define C18 (C17 + CDIFF) #define C19 (C18 + CDIFF3) #define C20 (C19 + CDIFF3) #define C21 (C20 + CDIFF3) #define C22 (C21 + CDIFF3) #define C23 (C22 + CDIFF3 - 2) #define C24 (C23 + CDIFF3 + 1) #define C25 (C24 + CDIFF3) #define C26 (C25 + CDIFF3 + 4) #define C27 (C26 + CDIFF3) #define C28 (C27 + CDIFF3 - 1) #define C29 (C28 + CDIFF3) #define C30 (C29 + CDIFF3 + 7) #define C31 (C30 + CDIFF3 - 1) #define C32 (C31 + CDIFF3) #define C33 (C32 + CDIFF3) #define C34 (C33 + CDIFF3 + 6) #define C35 (C34 + CDIFF3) #define C36 (C35 + CDIFF3 - 1) #define C37 (C36 + CDIFF3) #define Cb0 602 #define Cb1 (Cb0 + CDIFF5) #define Cb2 (Cb1 + CDIFF5) #define Cb3 (Cb2 + CDIFF5) #define Cb4 (Cb3 + CDIFF5 + 8) #define Cb5 (Cb4 + CDIFF5) #define Cb6 (Cb5 + CDIFF5) #define Cb7 (Cb6 + CDIFF5) #define Cb8 (Cb7 + CDIFF5) /* 244 */ #define Cb9 100 #define Cb10 (Cb9 + CDIFF4 + 1) /* 360 */ #define Cb11 498 #define Cb12 (Cb11 + CDIFF4 + 2) #define R0 365 #define R1 72 #define R2 217 #define R3 720 #define R5 185 #define R6 435 #define W0 11 #define W1 12 #define W2 13 #define L1 160 #define BDIFF (CDIFF + 2) #define BDIFF2 (CDIFF2 + 2) #define B0 170 #define B1 (B0 + BDIFF + BDIFF2) #define B2 (B1 + BDIFF) #define B3 (B2 + BDIFF) #define B4 (B3 + BDIFF) #define B5 (B4 + BDIFF) #define B6 (B5 + BDIFF) #define B7 (B6 + BDIFF) #define B8 (B7 + BDIFF) #define B9 (B8 + BDIFF + BDIFF2) #define B10 (B9 + BDIFF) #define B11 (B10 + BDIFF) #define B12 (B11 + BDIFF) #define B13 (B12 + BDIFF) #define B14 (B13 + BDIFF) #define B15 (B14 + BDIFF) #define B16 (B15 + BDIFF) #define B17 (B16 + BDIFF + BDIFF2) #define B18 (BDIFF) #define B19 (B18 + BDIFF + BDIFF) /* * This structure is for device definition. The structure is defined in * include/brighton.h, further definitions in brighton/brightonDevtable.h and * include/brightoninternals.h * * typedef int (*brightonCallback)(int, float); * typedef struct BrightonLocations { * int device; 0=rotary, 1=scale, etc. * float relx, rely; relative position with regards to 1000 by 1000 window * float relw, relh; relative height. * int from, to; * brightonCallback callback; specific to this dev * char *image; bitmap. If zero take a device default. * int flags; * } brightonLocations; * * This example is for a arp2600Bristol type synth interface. */ static brightonLocations locations[DEVICE_COUNT] = { {"EnvFollow Gain", 1, C0 - 2, R0, W2, L1, 0, 1, 0, "bitmaps/knobs/sliderblackl2.xpm", 0, 0}, {"RM in1 level", 1, C2 - 2, R0, W2, L1, 0, 1, 0, "bitmaps/knobs/sliderblackl2.xpm", 0, 0}, {"RM in2 level", 1, C3 - 1, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblackl2.xpm", 0, 0}, /* Osc-1 - 3 */ {"VCO1 Transpose", 1, C4 - 5, R5, 7, 80, 0, 4, 0, "bitmaps/buttons/klunk3.xpm", 0, 0}, /* "bitmaps/knobs/sliderblackl2.xpm", 0, 0}, */ /* {"", 1, C4 - 1, R0, W1, L1, 0, 1, 0, */ /* "bitmaps/knobs/sliderblackl2.xpm", 0, 0}, */ {"VCO1 Tracking", 2, C4 - 6, R6 - 8, 9, 45, 0, 2, 0, "bitmaps/buttons/klunk2.xpm", 0, BRIGHTON_THREEWAY}, {"VCO1 FM Mod1 lvl", 1, C5, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblackl.xpm", 0, 0}, {"VCO1 FM Mod2 lvl", 1, C6, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblackl.xpm", 0, 0}, {"VCO1 FM Mod3 lvl", 1, C7, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblackl.xpm", 0, 0}, {"VCO1 Sync 2->1", 2, C5 + 17, R5 - 15, 16, 14, 0, 1, 0, "bitmaps/buttons/klunk2.xpm", 0, 0}, {"VCO1 Tune Coarse", 1, 138, 77, 104, 30, 0, 1, 0, "bitmaps/knobs/sliderpointL.xpm", 0, BRIGHTON_VERTICAL|BRIGHTON_REVERSE|BRIGHTON_NOTCH}, {"VCO1 Tune Fine", 1, 138, 120, 104, 30, 0, 1, 0, "bitmaps/knobs/sliderpointL.xpm", 0, BRIGHTON_VERTICAL|BRIGHTON_REVERSE|BRIGHTON_NOTCH}, /* Osc-2 - 11 */ {"VCO2 Transpose", 1, C8 - 6, R5, 7, 80, 0, 4, 0, "bitmaps/buttons/klunk3.xpm", 0, 0}, /* "bitmaps/knobs/sliderblackl.xpm", 0, 0}, */ /* {"VCO2-Transpose", 1, C8, R0, W1, L1, 0, 1, 0, */ /* "bitmaps/knobs/sliderblackl.xpm", 0, 0}, */ {"VCO2 Tracking", 2, C8 - 7, R6 - 8, 9, 45, 0, 2, 0, "bitmaps/buttons/klunk2.xpm", 0, BRIGHTON_THREEWAY}, {"VCO2 FM Mod1 lvl", 1, C9, R0, W0, L1, 0, 1, 0, "bitmaps/knobs/sliderblackl.xpm", 0, 0}, {"VCO2 FM Mod2 lvl", 1, C10, R0, W0, L1, 0, 1, 0, "bitmaps/knobs/sliderblack2.xpm", 0, 0}, {"VCO2 FM Mod2 lvl", 1, C11, R0, W0, L1, 0, 1, 0, "bitmaps/knobs/sliderblack2.xpm", 0, 0}, {"VCO2 PWM", 1, C12, R0, W0, L1, 0, 1, 0, "bitmaps/knobs/sliderblack2.xpm", 0, 0}, {"VCO2 Tune Coarse", 1, 250, 77, 104, 30, 0, 1, 0, "bitmaps/knobs/sliderpointL.xpm", 0, BRIGHTON_VERTICAL|BRIGHTON_REVERSE|BRIGHTON_NOTCH}, {"VCO2 Tune Fine", 1, 250, 120, 104, 30, 0, 1, 0, "bitmaps/knobs/sliderpointL.xpm", 0, BRIGHTON_VERTICAL|BRIGHTON_REVERSE|BRIGHTON_NOTCH}, {"VCO2 PW", 1, 250, 165, 104, 30, 0, 1, 0, "bitmaps/knobs/sliderpointL.xpm", 0, BRIGHTON_VERTICAL|BRIGHTON_REVERSE}, /* Osc-3 - 20 */ {"VCO3 Transpose", 1, C13 - 6, R5, 7, 80, 0, 4, 0, "bitmaps/buttons/klunk3.xpm", 0, 0}, /* "bitmaps/knobs/sliderblack2.xpm", 0, 0}, */ /* {"VCO3 Transpose", 1, C13, R0, W1, L1, 0, 1, 0, */ /* "bitmaps/knobs/sliderblack2.xpm", 0, 0}, */ {"VCO3 Tracking", 2, C13 - 7, R6 - 8, 9, 45, 0, 2, 0, "bitmaps/buttons/klunk2.xpm", 0, BRIGHTON_THREEWAY}, {"VCO3 FM Mod1 lvl", 1, C14, R0, W0, L1, 0, 1, 0, "bitmaps/knobs/sliderblack2.xpm", 0, 0}, {"VCO3 FM Mod2 lvl", 1, C15, R0, W0, L1, 0, 1, 0, "bitmaps/knobs/sliderblack2.xpm", 0, 0}, {"VCO3 FM Mod3 lvl", 1, C16, R0, W0, L1, 0, 1, 0, "bitmaps/knobs/sliderblack2.xpm", 0, 0}, {"VCO3 PWM", 1, C17, R0, W0, L1, 0, 1, 0, "bitmaps/knobs/sliderblack2.xpm", 0, 0}, {"VCO3 Tune Coarse", 1, 376, 77, 104, 30, 0, 1, 0, "bitmaps/knobs/sliderpoint.xpm", 0, BRIGHTON_VERTICAL|BRIGHTON_REVERSE|BRIGHTON_NOTCH}, {"VCO3 Tune Fine", 1, 376, 120, 104, 30, 0, 1, 0, "bitmaps/knobs/sliderpoint.xpm", 0, BRIGHTON_VERTICAL|BRIGHTON_REVERSE|BRIGHTON_NOTCH}, {"VCO3 PW", 1, 376, 165, 104, 30, 0, 1, 0, "bitmaps/knobs/sliderpoint.xpm", 0, BRIGHTON_VERTICAL|BRIGHTON_REVERSE}, /* VCF - 29 */ /* {"", 1, C23 + 11, R1 + 14, 8, 78, 0, 4, 0, */ /* "bitmaps/knobs/sliderblack2.xpm", 0, 0}, */ {"VCF Mix1 lvl", 1, C18, R0, W0, L1, 0, 1, 0, "bitmaps/knobs/sliderblack2.xpm", 0, 0}, {"VCF Mix2 lvl", 1, C19, R0, W0, L1, 0, 1, 0, "bitmaps/knobs/sliderblack2.xpm", 0, 0}, {"VCF Mix3 lvl", 1, C20, R0, W0, L1, 0, 1, 0, "bitmaps/knobs/sliderblack2.xpm", 0, 0}, {"VCF Mix4 lvl", 1, C21, R0, W0, L1, 0, 1, 0, "bitmaps/knobs/sliderblack2.xpm", 0, 0}, {"VCF Mix5 lvl", 1, C22, R0, W0, L1, 0, 1, 0, "bitmaps/knobs/sliderblack2.xpm", 0, 0}, {"VCF Mod1 lvl", 1, C23, R0, W0, L1, 0, 1, 0, "bitmaps/knobs/sliderblack2.xpm", 0, 0}, {"VCF Mod2 lvl", 1, C24, R0, W0, L1, 0, 1, 0, "bitmaps/knobs/sliderblack2.xpm", 0, 0}, {"VCF Mod3 lvl", 1, C25, R0, W0, L1, 0, 1, 0, "bitmaps/knobs/sliderblack2.xpm", 0, 0}, {"VCF Cutoff", 1, 534, 77, 104, 30, 0, 1, 0, "bitmaps/knobs/sliderpoint.xpm", 0, BRIGHTON_VERTICAL|BRIGHTON_REVERSE}, {"VCF Resonance", 1, 534, 120, 104, 30, 0, 1, 0, "bitmaps/knobs/sliderpoint.xpm", 0, BRIGHTON_VERTICAL|BRIGHTON_REVERSE}, /* {"", 1, 500, 165, 104, 30, 0, 1, 0, */ /* "bitmaps/knobs/sliderpoint.xpm", 0, BRIGHTON_VERTICAL|BRIGHTON_REVERSE}, */ /* {"", 1, 500, 208, 104, 30, 0, 1, 0, */ /* "bitmaps/knobs/sliderpoint.xpm", 0, BRIGHTON_VERTICAL|BRIGHTON_REVERSE}, */ /* ADSR/AR - 39 */ {"Attack", 1, C26, R1, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblackr.xpm", 0, 0}, {"Decay", 1, C27, R1, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblackr.xpm", 0, 0}, {"Sustain", 1, C28, R1, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblackr.xpm", 0, 0}, {"Release", 1, C29, R1, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblackr.xpm", 0, 0}, {"AR Attack", 1, C26, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblackr.xpm", 0, 0}, {"AR Release", 1, C29, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblackr.xpm", 0, 0}, {"AR Gate", 2, C27 - 4, 474, 8, 25, 0, 1, 0, "bitmaps/buttons/klunk2.xpm", 0, BRIGHTON_VERTICAL|BRIGHTON_REVERSE}, /* ?? - 46 */ {"VCA Mix1 lvl", 1, C30, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblackr.xpm", 0, 0}, {"VCA Mix2 lvl", 1, C31, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblackr.xpm", 0, 0}, {"VCA Mod1 lvl", 1, C32, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblackr.xpm", 0, 0}, {"VCA Mod2 lvl", 1, C33, R0, W2, L1, 0, 1, 0, "bitmaps/knobs/sliderblackr2.xpm", 0, 0}, /* Mixer */ {"Mix lvl1", 1, C34 + 1, R0, W2, L1, 0, 1, 0, "bitmaps/knobs/sliderblackr2.xpm", 0, 0}, {"Mix lvl2", 1, C35 + 1, R0, W2, L1, 0, 1, 0, "bitmaps/knobs/sliderblackr2.xpm", 0, 0}, /* Effects return - 52 */ {"FX Return Left", 1, C36 + 2, R2, W2, L1, 0, 1, 0, "bitmaps/knobs/sliderblackr2.xpm", 0, 0}, {"FX Return Right", 1, C37 + 2, R2, W2, L1, 0, 1, 0, "bitmaps/knobs/sliderblackr2.xpm", 0, 0}, /* - 54 */ {"Chorus D1", 1, Cb0, R3, W0, L1, 0, 1, 0, "bitmaps/knobs/sliderblack2.xpm", 0, 0}, {"Chorus D2", 1, Cb1, R3, W0, L1, 0, 1, 0, "bitmaps/knobs/sliderblack2.xpm", 0, 0}, {"Chorus D3", 1, Cb2, R3, W0, L1, 0, 1, 0, "bitmaps/knobs/sliderblack2.xpm", 0, 0}, {"Chorus D4", 1, Cb3, R3, W0, L1, 0, 1, 0, "bitmaps/knobs/sliderblack2.xpm", 0, 0}, /* - 58 */ {"Reverb D1", 1, Cb4, R3, W0, L1, 0, 1, 0, "bitmaps/knobs/sliderblackr.xpm", 0, 0}, {"Reverb D2", 1, Cb5, R3, W0, L1, 0, 1, 0, "bitmaps/knobs/sliderblackr.xpm", 0, 0}, {"Reverb D3", 1, Cb6, R3, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblackr2.xpm", 0, 0}, {"Reverb D4", 1, Cb7, R3, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblackr2.xpm", 0, 0}, /* Manual start */ {"", 2, 712, 382, 12, 15, 0, 1, 0, "bitmaps/buttons/patchlow.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_NOSHADOW}, /* - 63 */ {"Noise White/Pink", 1, Cb9, R3, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblackl2.xpm", 0, 0}, {"Noise Level", 1, Cb10, R3, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblackl2.xpm", 0, 0}, /*; - 65 */ {"LFO Level", 1, Cb11, R3, W0, L1, 0, 1, 0, "bitmaps/knobs/sliderblack2.xpm", 0, 0}, {"LFO Rate", 1, Cb12, R3, W0, L1, 0, 1, 0, "bitmaps/knobs/sliderblack2.xpm", 0, 0}, /* - 67 */ {"LFO Sync", 2, Cb12 + 5, 920, 16, 14, 0, 1, 0, "bitmaps/buttons/klunk2.xpm", 0, 0}, /* Global (now program) Volume - 68 */ {"Volume Program", 1, 786, 120, 104, 30, 0, 1, 0, "bitmaps/knobs/sliderpointR.xpm", 0,BRIGHTON_VERTICAL|BRIGHTON_REVERSE}, {"Volume Pan", 1, 888, 120, 104, 30, 0, 1, 0, "bitmaps/knobs/sliderpointR.xpm", 0,BRIGHTON_VERTICAL|BRIGHTON_REVERSE| BRIGHTON_NOTCH}, /* Input gain and glide */ {"Input Gain", 0, 47, 78, 50, 50, 0, 1, 0, "bitmaps/knobs/knobgreynew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"Glide", 0, 101, 78, 50, 50, 0, 1, 0, "bitmaps/knobs/knobgreynew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, /* Voltage processors */ {"Mix1 Gain1", 1, 243, 711, 104, 30, 0, 1, 0, "bitmaps/knobs/sliderpointL.xpm", 0, BRIGHTON_VERTICAL|BRIGHTON_REVERSE}, {"Mix1 Gain2", 1, 243, 767, 104, 30, 0, 1, 0, "bitmaps/knobs/sliderpointL.xpm", 0, BRIGHTON_VERTICAL|BRIGHTON_REVERSE}, {"Mix2 Gain2", 1, 243, 821, 104, 30, 0, 1, 0, "bitmaps/knobs/sliderpointL.xpm", 0, BRIGHTON_VERTICAL|BRIGHTON_REVERSE}, {"Mix3 LagRate", 1, 243, 881, 104, 30, 0, 1, 0, "bitmaps/knobs/sliderpointL.xpm", 0, BRIGHTON_VERTICAL|BRIGHTON_REVERSE}, /* MARK used one dummy for VCA initial volume */ {"VCA Initial Vol", 1, 786, 163, 104, 30, 0, 1, 0, "bitmaps/knobs/sliderpointR.xpm", 0,BRIGHTON_VERTICAL|BRIGHTON_REVERSE}, /* DUMMIES */ {"", 1, 0, 0, 104, 30, 0, 1, 0, "bitmaps/knobs/sliderpointL.xpm", 0, BRIGHTON_VERTICAL|BRIGHTON_REVERSE|BRIGHTON_WITHDRAWN}, {"", 1, 0, 0, 104, 30, 0, 1, 0, "bitmaps/knobs/sliderpointL.xpm", 0, BRIGHTON_VERTICAL|BRIGHTON_REVERSE|BRIGHTON_WITHDRAWN}, {"", 1, 0, 0, 104, 30, 0, 1, 0, "bitmaps/knobs/sliderpointL.xpm", 0, BRIGHTON_VERTICAL|BRIGHTON_REVERSE|BRIGHTON_WITHDRAWN}, {"", 1, 0, 0, 104, 30, 0, 1, 0, "bitmaps/knobs/sliderpointL.xpm", 0, BRIGHTON_VERTICAL|BRIGHTON_REVERSE|BRIGHTON_WITHDRAWN}, {"", 1, 0, 0, 104, 30, 0, 1, 0, "bitmaps/knobs/sliderpointL.xpm", 0, BRIGHTON_VERTICAL|BRIGHTON_REVERSE|BRIGHTON_WITHDRAWN}, /* * These are the patch buttons. Positions are unfortunately arbitrary. * First the outputs, then the inputs. */ /* 82 */ {"Output Preamp", 2, 110, 213, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", 0}, {"", 2, 110, 280, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", 0}, {"", 2, 46, 439, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", 0}, /* VCO1 */ {"", 2, 212, 249, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", 0}, {"", 2, 212, 316, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", 0}, /* VCO2 */ {"", 2, 313, 249, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", 0}, {"", 2, 313, 316, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", 0}, {"", 2, 337, 249, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", 0}, {"", 2, 337, 316, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", 0}, /* VCO3 */ {"", 2, 438, 249, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", 0}, {"", 2, 438, 316, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", 0}, {"", 2, 462, 249, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", 0}, {"", 2, 462, 316, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", 0}, /* VCF */ {"", 2, 660, 287, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", 0}, /* ADSR */ {"", 2, 760, 287, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", 0}, {"", 2, 735, 382, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", 0}, {"", 2, 864, 287, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", 0}, /* Mix out */ {"", 2, 902, 235, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", 0}, /* Noise/SH/Switch */ {"", 2, 146, 797, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", 0}, /* SH/Switch - 324 */ {"", 2, 463, 797, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", 0}, {"", 2, 560, 666, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", 0}, {"", 2, 560, 906, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", 0}, {"", 2, 891, 339, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", 0}, {"", 2, 915, 339, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", 0}, /* Voltage Processor Outputs */ {"", 2, 411, 734, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", 0}, {"", 2, 411, 792, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", 0}, {"", 2, 411, 832, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", 0}, {"", 2, 411, 886, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", 0}, /* Reverb R out */ {"", 2, 961, 505, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", BRIGHTON_WITHDRAWN}, /* CV/Audio inputs */ {"", 2, 30, 716, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", 0}, {"", 2, 30, 772, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", 0}, {"", 2, 30, 826, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", 0}, {"", 2, 30, 886, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", 0}, /* DUMMIES */ {"", 2, 0, 0, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", BRIGHTON_WITHDRAWN}, {"", 2, 0, 0, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm", "bitmaps/buttons/patchonl.xpm", BRIGHTON_WITHDRAWN}, /* * Inputs. From the envelope follower onwards, these offset start from '1' * rather than from zero, this corrected later in the code. */ {"", 2, 900, 900, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_WITHDRAWN}, {"Input EnvFollow", 2, 24, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 67, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 110, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, /* VCO1 - the KDB CV input is disabled - FFS in engine. */ {"", 2, 140, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 164, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 188, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 212, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, /* VCO2 */ {"", 2, 242, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 266, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 289, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 313, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 337, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, /* VCO3 12 */ {"", 2, 367, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 391, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 415, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 438, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 462, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, /* VCF */ {"", 2, 493, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 516, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 540, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 564, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 588, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 611, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 635, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 659, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, /* Envelopes, etc. */ {"", 2, 687, 287, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_WITHDRAWN}, {"", 2, 710, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 734, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_WITHDRAWN}, {"", 2, 758, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_WITHDRAWN}, /* AMP, etc. */ {"", 2, 789, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 813, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 837, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 861, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, /* The rest */ {"", 2, 891, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 915, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 938, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, /* Lin, Rin */ {"", 2, 891, 180, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 961, 180, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, /* Electro inputs */ {"", 2, 560, 754, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 560, 797, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, /* Noise into SH */ {"", 2, 463, 666, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, /* Ext and switch clock */ {"", 2, 324, 886, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_WITHDRAWN}, {"", 2, 544, 864, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, /* Pan */ {"", 2, 915, 180, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, /* Voltage Processor inputs */ {"", 2, 197, 716, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 197, 772, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 197, 826, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 197, 886, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 362, 690, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 362, 746, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 362, 802, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, /* CV/Audio inputs */ {"", 2, 950, 716, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 950, 772, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 950, 826, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 950, 886, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON}, /* DUMMIES */ {"", 2, 900, 900, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_WITHDRAWN}, {"", 2, 900, 900, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_WITHDRAWN}, {"", 2, 900, 900, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_WITHDRAWN}, {"", 2, 900, 900, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm", "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_WITHDRAWN}, #define XS 808 #define XD 30 #define YS 730 #define YD 35 #define XSZ 19 #define YSZ 26 /* L-S-0 */ {"", 2, XS, YS+3*YD, XSZ, YSZ, 0, 1, 0, "bitmaps/digits/L.xpm", "bitmaps/buttons/jellyon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, XS+2*XD, YS+3*YD, XSZ, YSZ, 0, 1, 0, "bitmaps/digits/S.xpm", "bitmaps/buttons/jellyon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, XS+XD, YS+3*YD, XSZ, YSZ, 0, 1, 0, "bitmaps/digits/0.xpm", "bitmaps/buttons/jellyon.xpm", BRIGHTON_CHECKBUTTON}, /* 1-2-3 */ {"", 2, XS, YS, XSZ, YSZ, 0, 1, 0, "bitmaps/digits/1.xpm", "bitmaps/buttons/jellyon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, XS+XD, YS, XSZ, YSZ, 0, 1, 0, "bitmaps/digits/2.xpm", "bitmaps/buttons/jellyon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, XS+2*XD, YS, XSZ, YSZ, 0, 1, 0, "bitmaps/digits/3.xpm", "bitmaps/buttons/jellyon.xpm", BRIGHTON_CHECKBUTTON}, /* 4-5-6 */ {"", 2, XS, YS+1*YD, XSZ, YSZ, 0, 1, 0, "bitmaps/digits/4.xpm", "bitmaps/buttons/jellyon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, XS+XD, YS+1*YD, XSZ, YSZ, 0, 1, 0, "bitmaps/digits/5.xpm", "bitmaps/buttons/jellyon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, XS+2*XD, YS+1*YD, XSZ, YSZ, 0, 1, 0, "bitmaps/digits/6.xpm", "bitmaps/buttons/jellyon.xpm", BRIGHTON_CHECKBUTTON}, /* 7-8-9 */ {"", 2, XS, YS+2*YD, XSZ, YSZ, 0, 1, 0, "bitmaps/digits/7.xpm", "bitmaps/buttons/jellyon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, XS+XD, YS+2*YD, XSZ, YSZ, 0, 1, 0, "bitmaps/digits/8.xpm", "bitmaps/buttons/jellyon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, XS+2*XD, YS+2*YD, XSZ, YSZ, 0, 1, 0, "bitmaps/digits/9.xpm", "bitmaps/buttons/jellyon.xpm", BRIGHTON_CHECKBUTTON}, /* U-P */ {"", 2, XS, YS+4*YD, XSZ, YSZ, 0, 1, 0, "bitmaps/digits/Down.xpm", "bitmaps/buttons/jellyon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, XS+2*XD, YS+4*YD, XSZ, YSZ, 0, 1, 0, "bitmaps/digits/Up.xpm", "bitmaps/buttons/jellyon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, XS, YS+5*YD, XSZ, YSZ, 0, 1, 0, "bitmaps/digits/Down.xpm", "bitmaps/buttons/jellyon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, XS+2*XD, YS+5*YD, XSZ, YSZ, 0, 1, 0, "bitmaps/digits/Up.xpm", "bitmaps/buttons/jellyon.xpm", BRIGHTON_CHECKBUTTON}, /* MARK Stuff in another control for Global Volume */ {"", 1, 786, 77, 104, 30, 0, 1, 0, "bitmaps/knobs/sliderpointR.xpm", 0,BRIGHTON_VERTICAL|BRIGHTON_REVERSE}, /* Display */ {"", 3, 797, 670, 100, YSZ, 0, 1, 0, 0, "bitmaps/images/alphadisplay3.xpm", 0}, /*display 60 */ {"", 3, 797, 695, 100, YSZ, 0, 1, 0, 0, "bitmaps/images/alphadisplay2.xpm", 0}, /*display 60 */ /* 0, 0}, //display 60 */ }; /* */ /* * This is a set of globals for the main window rendering. Again taken from * include/brighton.h */ brightonApp arp2600App = { "arp2600", 0, /* no blueprint on wood background. */ "bitmaps/textures/metal4.xpm", 0, /* BRIGHTON_STRETCH, //flags */ arp2600Init, arp2600Configure, /* 3 callbacks, unused? */ arp2600MidiCallback, destroySynth, {1, 100, 3, 2, 5, 520, 0, 0}, 886, 500, 0, 0, 1, /* Panels */ { { "Arp2600", "bitmaps/blueprints/arp2600.xpm", /*"bitmaps/textures/metal4.xpm", */ "bitmaps/textures/metal2.xpm", /*"bitmaps/textures/bluemeanie.xpm", */ BRIGHTON_STRETCH, /* flags */ 0, 0, arp2600Callback, 0, 0, 1000, 1000, DEVICE_COUNT, locations } } }; static int arp2600MidiSendMsg(void *synth, int fd, int chan, int c, int o, int v) { bristolMidiSendMsg(fd, chan, c, o, v); return(0); } /* * This is a shim, when loading a memory we have to clear out all existing * patches and then re-request them afterwards. This is a slow memory operation * since we have to unpatch everything before the memory can be allocated. * * This could be improved. */ static int arp2600LoadMemory(guiSynth *synth, char *n, char *a, int b, int c, int d, int e) { brightonEvent event; int i, result; if (e == 0) { for (i = 0; i < ARP_OUTPUTS; i++) { if (links[i].input > 0) { /* printf("Mem disconnecting %i from %i", i, links[i].input); */ event.type = BRIGHTON_UNLINK; event.intvalue = 16382; brightonParamChange(synth->win, 0, OUTPUT_START+ i, &event); for (i = 0; i < ARP_OUTPUTS; i++) { links[i].input = -1; links[i].id = -1; } break; } } /* * This is used to ensure we could not have left any patches hanging in * the engine. We could use a similar 'clear all' operation for the GUI * so speed things up? */ bristolMidiSendMsg(global.controlfd, synth->sid, 102, 0, 0); } result = loadMemory(synth, n, a, b, c, d, e); /* * See if we need to patch things back in. */ if (e == 0) { for (i = 0; i < ARP_OUTPUTS; i++) { links[i].input = -1; links[i].id = -1; if (synth->mem.param[OUTPUT_START + i] > 0) { int connect = synth->mem.param[OUTPUT_START + i]; /* printf("Mem connecting %i to %1.0f\n", i, */ /* synth->mem.param[OUTPUT_START + i]); */ /* * Select the input, request a link for the GUI and then the * link request to the engine. */ event.type = BRIGHTON_PARAMCHANGE; event.value = 1; brightonParamChange(synth->win, 0, OUTPUT_START + i, &event); event.type = BRIGHTON_LINK; event.intvalue = INPUT_START + connect; links[oselect].input = connect; links[oselect].id = brightonParamChange(synth->win, 0, OUTPUT_START + i, &event); /* * This call could be put into another early cycle through the * table. This would cause the engine to be patched almost * immediately, and the GUI would follow shortly afterwards. * * Subtraction of 1 is due to offset differences */ bristolMidiSendMsg(global.controlfd, synth->sid, 100, i, connect - 1); synth->mem.param[OUTPUT_START + i] = connect; } } oselect = -1; /* PW Osc-1 */ bristolMidiSendMsg(global.controlfd, synth->sid, 0, 0, 16383); } return(result); } static int arp2600MidiCallback(brightonWindow *win, int command, int value, float v) { guiSynth *synth = findSynth(global.synths, win); printf("midi callback: %x, %i\n", command, value); switch(command) { case MIDI_PROGRAM: printf("midi program: %x, %i\n", command, value); synth->location = value; arp2600LoadMemory(synth, "arp2600", 0, synth->location, synth->mem.active, 0, 0); break; case MIDI_BANK_SELECT: printf("midi banksel: %x, %i\n", command, value); synth->bank = value; break; } return(0); } static int arp2600Memory(guiSynth *synth, int fd, int chan, int c, int o, int v) { /* printf(" arp2600Memory(B: %i L %i: %i, %i)\n", */ /* synth->bank, synth->location, c, o); */ switch (c) { default: case 0: synth->location = synth->location * 10 + o; if (synth->location >= 1000) synth->location = o; if (loadMemory(synth, "arp2600", 0, synth->location, synth->mem.active, 0, BRISTOL_STAT) < 0) displayText(synth, "FRE", synth->location, DISPLAY_DEV); else displayText(synth, "PRG", synth->location, DISPLAY_DEV); break; case 1: arp2600LoadMemory(synth, "arp2600", 0, synth->location, synth->mem.active, 0, 0); displayText(synth, "PRG", synth->location, DISPLAY_DEV); break; case 2: /* * Before we can save a memory we have to merge our links into * the mem buffer */ saveMemory(synth, "arp2600", 0, synth->location, 0); displayText(synth, "PRG", synth->location, DISPLAY_DEV); break; case 3: /* * Go through the memories, but do not load any of them. This will * break when we find a used one. */ while (arp2600LoadMemory(synth, "arp2600", 0, --synth->location, synth->mem.active, 0, 1) < 0) { if (synth->location < 0) { synth->location = 1000; } } /* Then load it */ arp2600LoadMemory(synth, "arp2600", 0, synth->location, synth->mem.active, 0, 0); displayText(synth, "PRG", synth->location, DISPLAY_DEV); break; case 4: /* * Go through the memories, but do not load any of them. This will * break when we find a used one. */ while (arp2600LoadMemory(synth, "arp2600", 0, ++synth->location, synth->mem.active, 0, 1) < 0) { if (synth->location > 999) { synth->location = -1; } } /* Then load it */ arp2600LoadMemory(synth, "arp2600", 0, synth->location, synth->mem.active, 0, 0); displayText(synth, "PRG", synth->location, DISPLAY_DEV); break; } return(0); } static int arp2600Midi(guiSynth *synth, int fd, int chan, int c, int o, int v) { int newchan; if ((synth->flags & OPERATIONAL) == 0) return(0); if (c == 1) { if ((newchan = synth->midichannel - 1) < 0) { newchan = synth->midichannel = 0; displayText(synth, "MIDI", newchan + 1, DISPLAY_DEV2); return(0); } } else { if ((newchan = synth->midichannel + 1) >= 16) { newchan = synth->midichannel = 15; displayText(synth, "MIDI", newchan + 1, DISPLAY_DEV2); return(0); } } displayText(synth, "MIDI", newchan + 1, DISPLAY_DEV2); if (global.libtest == 0) { /* * To overcome that we should consider checking a sequence number in * the message library? That is non trivial since it requires that * our midi messges have a 'ack' flag included - we cannot check for * ack here (actually, we could, and in the app is probably the right * place to do it rather than the lib however both would have to be * changed to suppor this - nc). */ bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_MIDICHANNEL|newchan); } synth->midichannel = newchan; return(0); } /* * For the sake of ease of use, links have been placed here to be called * by any of the devices created. They would be better in some other file, * perhaps with this as a dispatch. * * Param refers to the device index in the locations table given below. */ static int arp2600Callback(brightonWindow * win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); int sendvalue; /* printf("arp2600Callback(%i, %f): %x\n", index, value, synth); */ if (synth == 0) return(0); if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0)) return(0); if (arp2600App.resources[0].devlocn[index].to == 1.0) sendvalue = value * (CONTROLLER_RANGE - 1); else sendvalue = value; synth->mem.param[index] = value; /*if ((!global.libtest) || (index >= ACTIVE_DEVS)) */ if ((!global.libtest) || (index >= 71)) synth->dispatch[index].routine(synth, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #ifdef DEBUG else printf("dispatch[%x,%i](%i, %i, %i, %i, %i)\n", synth, index, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #endif return(0); } static int arp2600Volume(guiSynth *synth, int fd, int chan, int c, int o, int v) { bristolMidiSendMsg(global.controlfd, synth->sid, c, o, (int) (synth->mem.param[68] * synth->mem.param[198] * C_RANGE_MIN_1)); return(0); } static int arp2600ManualStart(guiSynth *synth, int fd, int chan, int c, int o, int v) { if (v == 0) bristolMidiSendMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_KEYOFF, 0, 40); else bristolMidiSendMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_KEYON, 0, 40); return(0); } static int arp2600IOSelect(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; if ((synth->flags & OPERATIONAL) == 0) return(0); /* printf("arp2600IOSelect(%i, %i, %i)", c, o, v); */ event.command = BRIGHTON_PARAMCHANGE; /* * We have quite a lot of work here, we need to mark any output that is * selected, if an input is selected then we should mark active the previous * output to link them up and draw the desired layer item. We should keep * all this in some structure such that it can be deconfigured, ie, patches * can be removed. * * The structure we need should have an input and output list, this should * give the true co-ords for the start and endpoint since it will be used * to evaluate the transforms for the patch source to the on-screen dest * bitmaps. * * There should also be a sanity check that clears any wayward output * selections, required before saveMemory() can be called. * * We will probably need a selection of bitmaps so that we can simplify * the stretch algorithm. If we only have one bitmaps then we need a more * complex transform since the end points should not be stretched, only * the intermittant cabling: * cable source is 146bits, 3 for each end. * Target length is 725 for example * the 3 start and end pixels get copied, * the middle 140 bits must be scaled to 719. * The result should then be rotated into position. */ if (c == 1) { if (v > 0) oselect = o; else oselect = -1; /* * If we select an output that is assigned then clear it. */ if (links[o].input > 0) { bristolMidiSendMsg(global.controlfd, synth->sid, 101, o, links[o].input - 1); links[o].input = 0; event.type = BRIGHTON_UNLINK; event.intvalue = links[o].id; brightonParamChange(synth->win, 0, OUTPUT_START + o, &event); } } else if (c == 2) { int i; if (oselect >= 0) { for (i = 0; i < ARP_OUTPUTS; i++) { if ((links[i].input > 0) && (links[i].input == o)) { int hold; /* event.intvalue = links[i].id; */ /* event.type = BRIGHTON_UNLINK; */ /* brightonParamChange(synth->win, 0, OUTPUT_START+ i, &event); */ hold = oselect; event.type = BRIGHTON_PARAMCHANGE; event.value = 0; brightonParamChange(synth->win, 0, OUTPUT_START+ i, &event); oselect = hold; } } synth->mem.param[OUTPUT_START + oselect] = o; links[oselect].input = o; /* * Need to request the drawing of a link. We need to send a message * that the library will interpret as a connection request. * All we have is brighton param change. We should consider sending * one message with each key click on an output, and another on * each input - this is the only way we can get two panel numbers * across, something we will eventually require. brightonParamChange(synth->win, 1, INPUT_START + oselect, &event); * Subtraction of 1 is due to offset differences */ bristolMidiSendMsg(global.controlfd, synth->sid, 100, oselect, o-1); event.type = BRIGHTON_LINK; event.intvalue = INPUT_START + o; links[oselect].id = brightonParamChange(synth->win, 0, OUTPUT_START + oselect, &event); } else { /* * See if this input is connected, if so clear it. */ for (i = 0; i < ARP_OUTPUTS; i++) { if ((links[i].input > 0) && (links[i].input == o)) { /* * What I need to do is send an event to the output device * turning it off. */ event.type = BRIGHTON_PARAMCHANGE; event.value = 0; brightonParamChange(synth->win, 0, OUTPUT_START+i, &event); } } } oselect = -1; } return(0); } /* * Any location initialisation required to run the callbacks. For bristol, this * will connect to the engine, and give it some base parameters. * May need to generate some application specific menus. * Will also then make specific requests to some of the devices to alter their * rendering. */ static int arp2600Init(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); dispatcher *dispatch; int i; if (synth == 0) { synth = findSynth(global.synths, (int) 0); if (synth == 0) { printf("cannot init\n"); return(0); } } synth->win = win; printf("Initialise the arp2600 link to bristol: %p\n", synth->win); synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float)); synth->mem.count = DEVICE_COUNT; synth->mem.active = ACTIVE_DEVS; synth->dispatch = (dispatcher *) brightonmalloc(DEVICE_COUNT * sizeof(dispatcher)); dispatch = synth->dispatch; /* * We really want to have three connection mechanisms. These should be * 1. Unix named sockets. * 2. UDP sockets. * 3. MIDI pipe. */ if (!global.libtest) { if ((synth->sid = initConnection(&global, synth)) < 0) return(-1); } for (i = 0; i < DEVICE_COUNT; i++) { /* * This sets up the input and output code. */ if (i >= MEM_START) { synth->dispatch[i].controller = 0; } else if (i >= INPUT_START) { /* Inputs */ synth->dispatch[i].controller = 2; synth->dispatch[i].operator = i - ACTIVE_DEVS; synth->dispatch[i].routine = (synthRoutine) arp2600IOSelect; } else if (i >= OUTPUT_START) { /* Outputs */ synth->dispatch[i].controller = 1; synth->dispatch[i].operator = i - ACTIVE_DEVS + ARP_OUTPUTS; synth->dispatch[i].routine = (synthRoutine) arp2600IOSelect; } else synth->dispatch[i].routine = arp2600MidiSendMsg; } /* Env and Ringmod */ dispatch[0].controller = 11; dispatch[0].operator = 0; dispatch[1].controller = 8; dispatch[1].operator = 0; dispatch[2].controller = 8; dispatch[2].operator = 1; /* VCO1 */ dispatch[3].controller = 0; dispatch[3].operator = 1; /* 4 is KBD control */ dispatch[4].controller = 126; dispatch[4].operator = 3; dispatch[5].controller = 103; dispatch[5].operator = 4; dispatch[6].controller = 103; dispatch[6].operator = 5; dispatch[7].controller = 103; dispatch[7].operator = 6; dispatch[8].controller = 1; /* Sync NEXT osc to this on */ dispatch[8].operator = 7; dispatch[9].controller = 0; dispatch[9].operator = 2; dispatch[10].controller = 0; dispatch[10].operator = 10; /* VCO2 */ dispatch[11].controller = 1; /* Transpose */ dispatch[11].operator = 1; /* 12 is KDB control */ dispatch[12].controller = 126; dispatch[12].operator = 4; dispatch[13].controller = 103; dispatch[13].operator = 8; dispatch[14].controller = 103; dispatch[14].operator = 9; dispatch[15].controller = 103; dispatch[15].operator = 10; dispatch[16].controller = 103; /* Gain PWM of square wave. */ dispatch[16].operator = 11; dispatch[17].controller = 1; dispatch[17].operator = 2; dispatch[18].controller = 1; dispatch[18].operator = 10; dispatch[19].controller = 1; dispatch[19].operator = 0; /* VCO3 */ dispatch[20].controller = 2; dispatch[20].operator = 1; /* 21 is KDB control */ dispatch[21].controller = 126; dispatch[21].operator = 5; dispatch[22].controller = 103; dispatch[22].operator = 13; dispatch[23].controller = 103; dispatch[23].operator = 14; dispatch[24].controller = 103; dispatch[24].operator = 15; dispatch[25].controller = 103; dispatch[25].operator = 16; dispatch[26].controller = 2; dispatch[26].operator = 2; dispatch[27].controller = 2; dispatch[27].operator = 10; dispatch[28].controller = 2; dispatch[28].operator = 0; /* Mixer into VCF */ dispatch[29].controller = 103; dispatch[29].operator = 17; dispatch[30].controller = 103; dispatch[30].operator = 18; dispatch[31].controller = 103; dispatch[31].operator = 19; dispatch[32].controller = 103; dispatch[32].operator = 20; dispatch[33].controller = 103; dispatch[33].operator = 21; /* dispatch[29].routine = dispatch[30].routine = dispatch[31].routine = dispatch[32].routine = dispatch[33].routine = (synthRoutine) arp2600FilterMix; */ /* VCF mods */ dispatch[34].controller = 103; dispatch[34].operator = 22; dispatch[35].controller = 103; dispatch[35].operator = 23; dispatch[36].controller = 103; dispatch[36].operator = 24; /* VCF Params */ dispatch[37].controller = 3; dispatch[37].operator = 0; dispatch[38].controller = 3; dispatch[38].operator = 1; /* Env Params */ dispatch[39].controller = 4; dispatch[39].operator = 0; dispatch[40].controller = 4; dispatch[40].operator = 1; dispatch[41].controller = 4; dispatch[41].operator = 2; dispatch[42].controller = 4; dispatch[42].operator = 3; /* AR */ dispatch[43].controller = 7; dispatch[43].operator = 0; dispatch[44].controller = 7; dispatch[44].operator = 3; /* Trigger. */ dispatch[45].controller = 126; dispatch[45].operator = 7; /* AMP Params */ dispatch[46].controller = 103; dispatch[46].operator = 29; dispatch[47].controller = 103; dispatch[47].operator = 30; dispatch[48].controller = 103; dispatch[48].operator = 31; dispatch[49].controller = 103; dispatch[49].operator = 32; /* Mixer */ dispatch[50].controller = 103; dispatch[50].operator = 33; dispatch[51].controller = 103; dispatch[51].operator = 34; /* FX levels */ dispatch[52].controller = 99; dispatch[52].operator = 4; dispatch[53].controller = 99; dispatch[53].operator = 5; /* Four dimension D controls - 13 */ dispatch[54].controller = 13; dispatch[54].operator = 0; dispatch[55].controller = 13; dispatch[55].operator = 1; dispatch[56].controller = 13; dispatch[56].operator = 2; dispatch[57].controller = 13; dispatch[57].operator = 3; /* Reverb controls */ dispatch[58].controller = 99; dispatch[58].operator = 0; dispatch[59].controller = 99; dispatch[59].operator = 1; dispatch[60].controller = 99; dispatch[60].operator = 2; dispatch[61].controller = 99; dispatch[61].operator = 3; dispatch[62].controller = 99; dispatch[62].operator = 60; dispatch[62].routine = (synthRoutine) arp2600ManualStart; /* Noise */ dispatch[63].controller = 6; dispatch[63].operator = 2; dispatch[64].controller = 6; dispatch[64].operator = 0; /* LFO stuff */ dispatch[65].controller = 126; dispatch[65].operator = 6; dispatch[66].controller = 9; dispatch[66].operator = 0; dispatch[67].controller = 9; dispatch[67].operator = 1; /* Master Volume and Pan - both should become GM2 option MARK */ dispatch[68].controller = 126; dispatch[68].operator = 11; dispatch[68].routine = (synthRoutine) arp2600Volume; dispatch[69].controller = 126; dispatch[69].operator = 2; /* Preamplifier */ dispatch[70].controller = 126; dispatch[70].operator = 10; /* Glide */ dispatch[71].controller = 126; dispatch[71].operator = 0; /* Voltage processing */ dispatch[72].controller = 103; dispatch[72].operator = 44; dispatch[73].controller = 103; dispatch[73].operator = 45; dispatch[74].controller = 103; dispatch[74].operator = 46; dispatch[75].controller = 12; dispatch[75].operator = 0; dispatch[76].controller = 126; dispatch[76].operator = 12; dispatch[MEM_START +0].routine = dispatch[MEM_START +1].routine = dispatch[MEM_START +2].routine = dispatch[MEM_START +3].routine = dispatch[MEM_START +4].routine = dispatch[MEM_START +5].routine = dispatch[MEM_START +6].routine = dispatch[MEM_START +7].routine = dispatch[MEM_START +8].routine = dispatch[MEM_START +9].routine = dispatch[MEM_START +10].routine = dispatch[MEM_START +11].routine = dispatch[MEM_START +12].routine = dispatch[MEM_START +13].routine = (synthRoutine) arp2600Memory; dispatch[MEM_START + 0].controller = 1; dispatch[MEM_START + 1].controller = 2; dispatch[MEM_START + 2].operator = 0; dispatch[MEM_START + 3].operator = 1; dispatch[MEM_START + 4].operator = 2; dispatch[MEM_START + 5].operator = 3; dispatch[MEM_START + 6].operator = 4; dispatch[MEM_START + 7].operator = 5; dispatch[MEM_START + 8].operator = 6; dispatch[MEM_START + 9].operator = 7; dispatch[MEM_START + 10].operator = 8; dispatch[MEM_START + 11].operator = 9; dispatch[MEM_START + 12].controller = 3; dispatch[MEM_START + 13].controller = 4; dispatch[MIDI_START].controller = 1; dispatch[MIDI_START + 1].controller = 2; dispatch[MIDI_START].routine = dispatch[MIDI_START + 1].routine = (synthRoutine) arp2600Midi; dispatch[198].controller = 126; dispatch[198].operator = 11; dispatch[198].routine = (synthRoutine) arp2600Volume; /* * Need to specify env gain fixed, filter mod on, osc waveform. */ bristolMidiSendMsg(global.controlfd, synth->sid, 102, 0, 0); /* clear patch */ /* No filter kbd tracking - we emulate it */ bristolMidiSendMsg(global.controlfd, synth->sid, 3, 2, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 3, 0); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 4, 4); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 7, 4096); bristolMidiSendMsg(global.controlfd, synth->sid, 3, 8, 100); bristolMidiSendMsg(global.controlfd, synth->sid, 6, 1, 1); /* AR Env params */ bristolMidiSendMsg(global.controlfd, synth->sid, 4, 4, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 7, 1, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 7, 2, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 7, 4, 16383); /* bristolMidiSendMsg(global.controlfd, synth->sid, 4, 4, 16383); */ /* bristolMidiSendMsg(global.controlfd, synth->sid, 3, 2, 16383); */ /* bristolMidiSendMsg(global.controlfd, synth->sid, 0, 4, 16383); */ /* bristolMidiSendMsg(global.controlfd, synth->sid, 1, 6, 16383); */ /* Request rooney filter for lag operator. */ bristolMidiSendMsg(global.controlfd, synth->sid, 12, 4, 3); return(0); } /* * This will be called to make any routine specific parameters available. */ static int arp2600Configure(brightonWindow* win) { guiSynth *synth = findSynth(global.synths, win); brightonEvent event; if (synth == 0) { printf("problems going operational\n"); return(-1); } if (synth->flags & OPERATIONAL) return(0); printf("going operational\n"); synth->flags |= OPERATIONAL; synth->keypanel = synth->keypanel2 = -1; synth->transpose = 36; synth->bank = 0; event.value = 1; arp2600LoadMemory(synth, "arp2600", 0, synth->location, synth->mem.active, 0, 0); /* * This needs to be fixed. If we load a memory it can override the active * device count. Perhaps for eventual release of the software this is not * an issue though - the active count and memories are then set in stone. * If they do not match then we should back out, but it is a bit on the * late side now. Should be put into the loadMem routines. */ synth->mem.active = ACTIVE_DEVS; /* * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only * occurs on first paint, so we suppress the first paint, and then request * an expose here. */ event.type = BRIGHTON_FLOAT; event.value = 0.8; brightonParamChange(synth->win, 0, 198, &event); /* * Touch a key on/off */ /* bristolMidiSendMsg(global.controlfd, synth->midichannel, */ /* BRISTOL_EVENT_KEYON, 0, 10 + synth->transpose); */ /* bristolMidiSendMsg(global.controlfd, synth->midichannel, */ /* BRISTOL_EVENT_KEYOFF, 0, 10 + synth->transpose); */ configureGlobals(synth); synth->loadMemory = (loadRoutine) arp2600LoadMemory; return(0); } bristol-0.60.11/brighton/brightonBassMaker.c0000644000175000017500000017161711746476475015705 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* * The 'Bass' Maker, 4 stage 16 step sequencer. * * Crashes after BM is stopped. Issues with voice->baudio was NULL. * Apparent loss of pitch bend. * Mod controller mapping does not appear to work. * * Global transpose. Test. * Mem search DONE * Midi channel DONE * Need to make sure transpose and channel selections are in the memories and * recovered. Tested ctype, cc, transpose * * Controller options * Controller to note (13 steps) + channel * Controller to tune * Controller to pitchwheel * Controller to mod wheel * Controller to other continuous controller * Controller to operator parameter * * Copy page * Fill values * * Midi send and recieve clock. ffs. */ #include #include "brighton.h" #include "bristolmidi.h" #include "brightonMini.h" #include "brightoninternals.h" #include "brightonledstates.h" static int bmInit(); static int bmConfigure(); static int bmCallback(brightonWindow *, int, int, float); extern guimain global; #include "brightonKeys.h" static int dc; #define BM_TRANSPOSE 24 #define KEY_PANEL 1 #define PAGE_COUNT 4 /* This would require rebuilding the control panel */ #define OP_COUNT 8 #define PAGE_STEP 16 #define STEP_COUNT (PAGE_STEP * PAGE_COUNT) #define TOTAL_DEVS (PAGE_STEP * OP_COUNT) #define CONTROL_COUNT 60 /* controls less memomry selectors/entry */ #define CONTROL_ACTIVE 20 #define COFF (TOTAL_DEVS * PAGE_COUNT) #define ACTIVE_DEVS (COFF + CONTROL_ACTIVE) #define DEVICE_COUNT (COFF + CONTROL_COUNT) #define DISPLAY_DEV (CONTROL_COUNT - 1) #define BM_C_CONTROL 0 /* or greater */ #define BM_C_NOTE -1 #define BM_C_TUNE -2 #define BM_C_GLIDE -3 /* ffs */ #define BM_C_MOD -4 /* ffs */ #define BM_C_OPERATOR -5 /* ffs */ /* * This structure is for device definition. The structure is defined in * include/brighton.h, further definitions in brighton/brightonDevtable.h and * include/brightoninternals.h * * typedef int (*brightonCallback)(int, float); * typedef struct BrightonLocations { * int device; 0=rotary, 1=scale, etc. * float relx, rely; relative position with regards to 1000 by 1000 window * float relw, relh; relative height. * int from, to; * brightonCallback callback; specific to this dev * char *image; bitmap. If zero take a device default. * int flags; * } brightonLocations; * * This example is for a bmBristol type synth interface. */ typedef struct BmNote { float note; float transp; float velocity; float cont; float led; float button; float pad1; float pad2; } bmNote; typedef struct BmPage { bmNote step[PAGE_STEP]; } bmPage; /* A/B/C/D active: 0 4 4 */ /* A/B/C/D select: 4 4 8 */ /* Speed, Duty, 4xdirection: 8 6 14 */ /* 6 pad: 14 6 20 */ /* ABCD led * 2: 20 8 28 */ /* Dir led * 4: 28 4 32 */ /* Memory 12: 32 12 44 */ /* Display 4: 44 4 48 */ /* 12 pad: 48 12 60 */ typedef struct BmControl { float speed; float duty; float up; float down; float updown; float rand; float active[PAGE_COUNT]; float select[PAGE_COUNT]; float transpose; float ctype; float cc; float cop; float pad1[2]; /* 20 Following parameters are NOT in the memories */ float activeled[PAGE_COUNT]; float selectled[PAGE_COUNT]; float dirled[PAGE_COUNT]; float mem[12]; float start; float stop; float pad2[10]; float display[PAGE_COUNT]; } bmControl; typedef struct BmMem { bmPage page[PAGE_COUNT]; bmControl control; /* These are transient parameters used during operation */ int lastnote; int lastpage; int laststep; int clearstep; int lastcnote; int cMemPage; int cMemEntry; int pageSelect; } bmMem; struct { synthRoutine control[OP_COUNT]; } call; #define DR1 194 #define R1 60 #define R2 (R1 + DR1 + 10) #define R3 (R2 + DR1 - 10) #define R4 (R3 + DR1) #define R5 (R4 + DR1) #define R6 (R5 + DR1/3 - 15) #define DC1 60 #define C1 30 #define C2 (C1 + DC1) #define C3 (C2 + DC1) #define C4 (C3 + DC1) #define C5 (C4 + DC1) #define C6 (C5 + DC1) #define C7 (C6 + DC1) #define C8 (C7 + DC1) #define C9 (C8 + DC1) #define C10 (C9 + DC1) #define C11 (C10 + DC1) #define C12 (C11 + DC1) #define C13 (C12 + DC1) #define C14 (C13 + DC1) #define C15 (C14 + DC1) #define C16 (C15 + DC1) #define W1 35 #define H1 100 #define W2 20 #define H2 60 #define W3 12 #define H3 27 #define H4 75 #define O1 (W1 / 3) #define O2 ((W1 - W2) / 2 + 4) #define O3 ((W1 - W3) / 2 + 3) static brightonLocations locations[TOTAL_DEVS] = { {"", 0, C1, R1, W1, H1, 0, 12, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"", 2, C1 + O3, R2, 10, H4, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY}, {"", 0, C1, R3, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"", 0, C1, R4, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, BRIGHTON_NOTCH}, {"", 12, C1 + O3, R5, W3, H3, 0, 4, 0, 0, 0, 0}, {"", 2, C1 + O2, R6, W2, H2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlW.xpm", BRIGHTON_CHECKBUTTON}, {"", 0, C1 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, C1 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, C2, R1, W1, H1, 0, 12, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"", 2, C2 + O3, R2, 10, H4, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY}, {"", 0, C2, R3, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"", 0, C2, R4, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, BRIGHTON_NOTCH}, {"", 12, C2 + O3, R5, W3, H3, 0, 4, 0, 0, 0, 0}, {"", 2, C2 + O2, R6, W2, H2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlW.xpm", BRIGHTON_CHECKBUTTON}, {"", 0, C2 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, C2 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, C3, R1, W1, H1, 0, 12, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"", 2, C3 + O3, R2, 10, H4, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY}, {"", 0, C3, R3, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"", 0, C3, R4, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, BRIGHTON_NOTCH}, {"", 12, C3 + O3, R5, W3, H3, 0, 4, 0, 0, 0, 0}, {"", 2, C3 + O2, R6, W2, H2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON}, {"", 0, C3 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, C3 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, C4, R1, W1, H1, 0, 12, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"", 2, C4 + O3, R2, 10, H4, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY}, {"", 0, C4, R3, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"", 0, C4, R4, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, BRIGHTON_NOTCH}, {"", 12, C4 + O3, R5, W3, H3, 0, 4, 0, 0, 0, 0}, {"", 2, C4 + O2, R6, W2, H2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON}, {"", 0, C4 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, C4 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, C5, R1, W1, H1, 0, 12, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"", 2, C5 + O3, R2, 10, H4, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY}, {"", 0, C5, R3, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"", 0, C5, R4, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, BRIGHTON_NOTCH}, {"", 12, C5 + O3, R5, W3, H3, 0, 4, 0, 0, 0, 0}, {"", 2, C5 + O2, R6, W2, H2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON}, {"", 0, C5 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, C5 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, C6, R1, W1, H1, 0, 12, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"", 2, C6 + O3, R2, 10, H4, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY}, {"", 0, C6, R3, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"", 0, C6, R4, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, BRIGHTON_NOTCH}, {"", 12, C6 + O3, R5, W3, H3, 0, 4, 0, 0, 0, 0}, {"", 2, C6 + O2, R6, W2, H2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON}, {"", 0, C6 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, C6 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, C7, R1, W1, H1, 0, 12, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"", 2, C7 + O3, R2, 10, H4, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY}, {"", 0, C7, R3, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"", 0, C7, R4, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, BRIGHTON_NOTCH}, {"", 12, C7 + O3, R5, W3, H3, 0, 4, 0, 0, 0, 0}, {"", 2, C7 + O2, R6, W2, H2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON}, {"", 0, C7 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, C7 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, C8, R1, W1, H1, 0, 12, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"", 2, C8 + O3, R2, 10, H4, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY}, {"", 0, C8, R3, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"", 0, C8, R4, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, BRIGHTON_NOTCH}, {"", 12, C8 + O3, R5, W3, H3, 0, 4, 0, 0, 0, 0}, {"", 2, C8 + O2, R6, W2, H2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON}, {"", 0, C8 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, C8 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, C9, R1, W1, H1, 0, 12, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"", 2, C9 + O3, R2, 10, H4, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY}, {"", 0, C9, R3, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"", 0, C9, R4, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, BRIGHTON_NOTCH}, {"", 12, C9 + O3, R5, W3, H3, 0, 4, 0, 0, 0, 0}, {"", 2, C9 + O2, R6, W2, H2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON}, {"", 0, C9 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, C9 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, C10, R1, W1, H1, 0, 12, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"", 2, C10 + O3, R2, 10, H4, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY}, {"", 0, C10, R3, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"", 0, C10, R4, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, BRIGHTON_NOTCH}, {"", 12, C10 + O3, R5, W3, H3, 0, 4, 0, 0, 0, 0}, {"", 2, C10 + O2, R6, W2, H2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON}, {"", 0, C10 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, C10 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, C11, R1, W1, H1, 0, 12, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"", 2, C11 + O3, R2, 10, H4, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY}, {"", 0, C11, R3, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"", 0, C11, R4, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, BRIGHTON_NOTCH}, {"", 12, C11 + O3, R5, W3, H3, 0, 4, 0, 0, 0, 0}, {"", 2, C11 + O2, R6, W2, H2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON}, {"", 0, C11 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, C11 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, C12, R1, W1, H1, 0, 12, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"", 2, C12 + O3, R2, 10, H4, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY}, {"", 0, C12, R3, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"", 0, C12, R4, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, BRIGHTON_NOTCH}, {"", 12, C12 + O3, R5, W3, H3, 0, 4, 0, 0, 0, 0}, {"", 2, C12 + O2, R6, W2, H2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON}, {"", 0, C12 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, C12 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, C13, R1, W1, H1, 0, 12, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"", 2, C13 + O3, R2, 10, H4, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY}, {"", 0, C13, R3, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"", 0, C13, R4, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, BRIGHTON_NOTCH}, {"", 12, C13 + O3, R5, W3, H3, 0, 4, 0, 0, 0, 0}, {"", 2, C13 + O2, R6, W2, H2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON}, {"", 0, C13 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, C13 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, C14, R1, W1, H1, 0, 12, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"", 2, C14 + O3, R2, 10, H4, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY}, {"", 0, C14, R3, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"", 0, C14, R4, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, BRIGHTON_NOTCH}, {"", 12, C14 + O3, R5, W3, H3, 0, 4, 0, 0, 0, 0}, {"", 2, C14 + O2, R6, W2, H2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON}, {"", 0, C14 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, C14 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, C15, R1, W1, H1, 0, 12, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"", 2, C15 + O3, R2, 10, H4, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY}, {"", 0, C15, R3, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"", 0, C15, R4, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, BRIGHTON_NOTCH}, {"", 12, C15 + O3, R5, W3, H3, 0, 4, 0, 0, 0, 0}, {"", 2, C15 + O2, R6, W2, H2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON}, {"", 0, C15 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, C15 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, C16, R1, W1, H1, 0, 12, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"", 2, C16 + O3, R2, 10, H4, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY}, {"", 0, C16, R3, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"", 0, C16, R4, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, BRIGHTON_NOTCH}, {"", 12, C16 + O3, R5, W3, H3, 0, 4, 0, 0, 0, 0}, {"", 2, C16 + O2, R6, W2, H2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON}, {"", 0, C16 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 0, C16 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, }; /* * start/pause + flash, stop=return to start. 2 + led * 4 screen selectors + 4 active selectors a/b/c/d 8 + 8 led * * speed, up, down, u/d, rand, trig, duty cycle. * rotary * 2 + 5. * * memories 12 * * controller mapping - tuning, mod, etc. * display + option + up/down * * 8+7(+5pad+)8+3+12+4(+12pad)=60 */ #define CR1 300 #define CR2 500 #define CW1 30 #define CH1 200 static brightonLocations bm_controls[CONTROL_COUNT] = { /* Speed, Duty, 4xdirection: 0 6 6 */ {"", 0, 20, 255, 50, 500, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"", 0, 100, 255, 50, 500, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, {"", 2, 230, CR1, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_u.xpm", "bitmaps/digits/kbd_u.xpm", BRIGHTON_NOSHADOW}, {"", 2, 230, CR2, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_down.xpm", "bitmaps/digits/kbd_down.xpm", 0}, {"", 2, 260, CR1, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_ud.xpm", "bitmaps/digits/kbd_ud.xpm", 0}, {"", 2, 260, CR2, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_r.xpm", "bitmaps/digits/kbd_r.xpm", 0}, /* A/B/C/D active: 6 4 10 */ {"", 2, 340, CR1, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_a.xpm", "bitmaps/digits/kbd_a.xpm", BRIGHTON_NOSHADOW}, {"", 2, 370, CR1, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_b.xpm", "bitmaps/digits/kbd_b.xpm", BRIGHTON_NOSHADOW}, {"", 2, 400, CR1, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_c.xpm", "bitmaps/digits/kbd_c.xpm", BRIGHTON_NOSHADOW}, {"", 2, 430, CR1, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_d.xpm", "bitmaps/digits/kbd_d.xpm", 0}, /* A/B/C/D select: 10 4 14 */ {"", 2, 340, CR2, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_a.xpm", "bitmaps/buttons/touchnlW.xpm", BRIGHTON_CHECKBUTTON|0}, {"", 2, 370, CR2, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_b.xpm", "bitmaps/buttons/touchnlW.xpm", BRIGHTON_CHECKBUTTON|0}, {"", 2, 400, CR2, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_c.xpm", "bitmaps/buttons/touchnlW.xpm", BRIGHTON_CHECKBUTTON|0}, {"", 2, 430, CR2, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_d.xpm", "bitmaps/buttons/touchnlW.xpm", BRIGHTON_CHECKBUTTON|0}, /* 6 pad: 14 6 20 */ {"", 0, 9, 9, 9, 9, 0, 1, 0, 0, 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 0, 9, 9, 9, 9, 0, 1, 0, 0, 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 0, 9, 9, 9, 9, 0, 1, 0, 0, 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 0, 9, 9, 9, 9, 0, 1, 0, 0, 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 0, 9, 9, 9, 9, 0, 1, 0, 0, 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 0, 9, 9, 9, 9, 0, 1, 0, 0, 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, /* ABCD led * 2: 20 8 28 */ {"", 12, 350, 200, 11, 85, 0, 4, 0, 0, 0, 0}, {"", 12, 380, 200, 11, 85, 0, 4, 0, 0, 0, 0}, {"", 12, 410, 200, 11, 85, 0, 4, 0, 0, 0, 0}, {"", 12, 440, 200, 11, 85, 0, 4, 0, 0, 0, 0}, {"", 12, 350, 730, 11, 85, 0, 4, 0, 0, 0, 0}, {"", 12, 380, 730, 11, 85, 0, 4, 0, 0, 0, 0}, {"", 12, 410, 730, 11, 85, 0, 4, 0, 0, 0, 0}, {"", 12, 440, 730, 11, 85, 0, 4, 0, 0, 0, 0}, /* Dir led * 4: 28 4 32 */ {"", 12, 240, 200, 11, 85, 0, 4, 0, 0, 0, 0}, {"", 12, 240, 730, 11, 85, 0, 4, 0, 0, 0, 0}, {"", 12, 270, 200, 11, 85, 0, 4, 0, 0, 0, 0}, {"", 12, 270, 730, 11, 85, 0, 4, 0, 0, 0, 0}, /* Memory 12: 32 12 44 */ {"", 2, 530, CR1, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_0.xpm", "bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, {"", 2, 560, CR1, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_1.xpm", "bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, {"", 2, 590, CR1, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_2.xpm", "bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, {"", 2, 620, CR1, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_3.xpm", "bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW}, {"", 2, 650, CR1, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_4.xpm", "bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON|0}, {"", 2, 530, CR2, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_5.xpm", "bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON|0}, {"", 2, 560, CR2, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_6.xpm", "bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON|0}, {"", 2, 590, CR2, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_7.xpm", "bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON|0}, {"", 2, 620, CR2, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_8.xpm", "bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON|0}, {"", 2, 650, CR2, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_9.xpm", "bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON|0}, {"", 2, 680, CR1, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_ld.xpm", "bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON|0}, {"", 2, 680, CR2, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_s.xpm", "bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON|0}, /* Start/Stop + LED */ {"", 2, 175, CR1, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_st.xpm", "bitmaps/digits/kbd_st.xpm", 0}, {"", 2, 175, CR2, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_stop.xpm", "bitmaps/digits/kbd_stop.xpm", 0}, {"", 12, 185, 200, 11, 80, 0, 4, 0, 0, 0, 0}, {"", 12, 185, 730, 11, 80, 0, 4, 0, 0, 0, 0}, /* 8 pad: 52 8 60 */ {"", 0, 9, 9, 9, 9, 0, 1, 0, 0, 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 0, 9, 9, 9, 9, 0, 1, 0, 0, 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 0, 9, 9, 9, 9, 0, 1, 0, 0, 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 0, 9, 9, 9, 9, 0, 1, 0, 0, 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 0, 9, 9, 9, 9, 0, 1, 0, 0, 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 0, 9, 9, 9, 9, 0, 1, 0, 0, 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 0, 9, 9, 9, 9, 0, 1, 0, 0, 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, /* Display 5: 55 5 60 */ {"", 2, 740, CR1, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_ua.xpm", "bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON|0}, {"", 2, 740, CR2, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_da.xpm", "bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON}, {"", 2, 950, CR1, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_fn.xpm", "bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON|0}, {"", 2, 950, CR2, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_ret.xpm", "bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON}, {"", 3, 775, 415, 170, 123, 0, 1, 0, 0, "bitmaps/images/alphadisplay3.xpm", 0} }; static int bmMidiCallback(brightonWindow *win, int controller, int value, float n) { guiSynth *synth = findSynth(global.synths, win); printf("midi callback: %x, %i\n", controller, value); switch(controller) { case MIDI_PROGRAM: printf("midi program: %x, %i\n", controller, value); synth->bank = value - (value % 8); synth->location = value % 8; loadMemory(synth, "bassmaker", 0, synth->bank * 10 + synth->location, synth->mem.active, 0, 0); break; /* * This needs a case statement for midi clock which can then be used * to drive the fast timers. */ } return(0); } /* * This is a set of globals for the main window rendering. Again taken from * include/brighton.h */ brightonApp bmApp = { "bassmaker", 0, "bitmaps/textures/metal2.xpm", BRIGHTON_STRETCH|BRIGHTON_REVERSE, /* default is tesselate */ bmInit, bmConfigure, /* 3 callbacks, unused? */ bmMidiCallback, destroySynth, {1, 100, 2, 2, 5, 520, 0, 0}, 820, 410, 0, 0, 8, { { "BM-20", "bitmaps/blueprints/bm.xpm", "bitmaps/textures/metal2.xpm", BRIGHTON_STRETCH|BRIGHTON_REVERSE, /* flags */ 0, bmConfigure, bmCallback, 11, 243, 976, 690, TOTAL_DEVS, locations }, { "BM-20", "bitmaps/blueprints/bm.xpm", "bitmaps/textures/metal2.xpm", BRIGHTON_STRETCH|BRIGHTON_REVERSE|BRIGHTON_WITHDRAWN, /* flags */ 0, bmConfigure, bmCallback, 11, 243, 976, 690, TOTAL_DEVS, locations }, { "BM-20", "bitmaps/blueprints/bm.xpm", "bitmaps/textures/metal2.xpm", BRIGHTON_STRETCH|BRIGHTON_REVERSE|BRIGHTON_WITHDRAWN, /* flags */ 0, bmConfigure, bmCallback, 11, 243, 976, 690, TOTAL_DEVS, locations }, { "BM-20", "bitmaps/blueprints/bm.xpm", "bitmaps/textures/metal2.xpm", BRIGHTON_STRETCH|BRIGHTON_REVERSE|BRIGHTON_WITHDRAWN, /* flags */ 0, bmConfigure, bmCallback, 11, 243, 976, 690, TOTAL_DEVS, locations }, { "Mods", "bitmaps/blueprints/bmmods.xpm", //"bitmaps/textures/metal7.xpm", /* flags */ "bitmaps/textures/metal2.xpm", BRIGHTON_VERTICAL|BRIGHTON_REVERSE|BRIGHTON_STRETCH, 0, 0, bmCallback, 12, 0, 977, 240, CONTROL_COUNT, bm_controls }, { "Wood", 0, "bitmaps/textures/wood6.xpm", BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 14, 930, 974, 60, 0, 0 }, { "SP1", 0, "bitmaps/images/rhodes.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 0, 0, 12, 1000, 0, 0 }, { "SP2", 0, "bitmaps/images/rhodes.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 988, 0, 12, 1000, 0, 0 }, } }; int bmMidiSendMsg(void *synth, int fd, int chan, int c, int o, int v) { // bristolMidiSendMsg(fd, chan, c, o, v); return(0); } static void bmMemShim(guiSynth *synth) { int i; bmMem *bm = (bmMem *) synth->mem.param; brightonEvent event; event.type = BRIGHTON_FLOAT; /* * We need to review the button state and from that set the per note LED to * the desired color */ for (i = 0; i < STEP_COUNT; i++) { event.value = bm->page[i / PAGE_STEP].step[i % PAGE_STEP].button; //printf("Shim %i: %i %i = %f\n", i, i / PAGE_STEP, (i % PAGE_STEP) * OP_COUNT + 4, event.value); brightonParamChange(synth->win, i / PAGE_STEP, (i % PAGE_STEP) * OP_COUNT + 4, &event); } synth->transpose = bm->control.transpose - 12; } #define BM_DIR_UP 0 #define BM_DIR_DOWN 1 #define BM_DIR_UPDOWN 2 #define BM_DIR_RAND 3 #define BM_INC_A 0x01 #define BM_INC_B 0x02 #define BM_INC_C 0x04 #define BM_INC_D 0x08 static void bmStuffPage(guiSynth *synth, int page, int dir) { if (dir == BM_DIR_UP) { brightonFastTimer(synth->win, page, 4, BRIGHTON_FT_REQ, 0); brightonFastTimer(synth->win, page, 12, BRIGHTON_FT_REQ, 0); brightonFastTimer(synth->win, page, 20, BRIGHTON_FT_REQ, 0); brightonFastTimer(synth->win, page, 28, BRIGHTON_FT_REQ, 0); brightonFastTimer(synth->win, page, 36, BRIGHTON_FT_REQ, 0); brightonFastTimer(synth->win, page, 44, BRIGHTON_FT_REQ, 0); brightonFastTimer(synth->win, page, 52, BRIGHTON_FT_REQ, 0); brightonFastTimer(synth->win, page, 60, BRIGHTON_FT_REQ, 0); brightonFastTimer(synth->win, page, 68, BRIGHTON_FT_REQ, 0); brightonFastTimer(synth->win, page, 76, BRIGHTON_FT_REQ, 0); brightonFastTimer(synth->win, page, 84, BRIGHTON_FT_REQ, 0); brightonFastTimer(synth->win, page, 92, BRIGHTON_FT_REQ, 0); brightonFastTimer(synth->win, page, 100, BRIGHTON_FT_REQ, 0); brightonFastTimer(synth->win, page, 108, BRIGHTON_FT_REQ, 0); brightonFastTimer(synth->win, page, 116, BRIGHTON_FT_REQ, 0); brightonFastTimer(synth->win, page, 124, BRIGHTON_FT_REQ, 0); } else if (dir == BM_DIR_DOWN) { brightonFastTimer(synth->win, page, 124, BRIGHTON_FT_REQ, 0); brightonFastTimer(synth->win, page, 116, BRIGHTON_FT_REQ, 0); brightonFastTimer(synth->win, page, 108, BRIGHTON_FT_REQ, 0); brightonFastTimer(synth->win, page, 100, BRIGHTON_FT_REQ, 0); brightonFastTimer(synth->win, page, 92, BRIGHTON_FT_REQ, 0); brightonFastTimer(synth->win, page, 84, BRIGHTON_FT_REQ, 0); brightonFastTimer(synth->win, page, 76, BRIGHTON_FT_REQ, 0); brightonFastTimer(synth->win, page, 68, BRIGHTON_FT_REQ, 0); brightonFastTimer(synth->win, page, 60, BRIGHTON_FT_REQ, 0); brightonFastTimer(synth->win, page, 52, BRIGHTON_FT_REQ, 0); brightonFastTimer(synth->win, page, 44, BRIGHTON_FT_REQ, 0); brightonFastTimer(synth->win, page, 36, BRIGHTON_FT_REQ, 0); brightonFastTimer(synth->win, page, 28, BRIGHTON_FT_REQ, 0); brightonFastTimer(synth->win, page, 20, BRIGHTON_FT_REQ, 0); brightonFastTimer(synth->win, page, 12, BRIGHTON_FT_REQ, 0); brightonFastTimer(synth->win, page, 4, BRIGHTON_FT_REQ, 0); } else if (dir == BM_DIR_RAND) { brightonFastTimer(synth->win, page, (rand() & 0x0f) * 8 + 4, BRIGHTON_FT_REQ, 0); brightonFastTimer(synth->win, page, (rand() & 0x0f) * 8 + 4, BRIGHTON_FT_REQ, 0); brightonFastTimer(synth->win, page, (rand() & 0x0f) * 8 + 4, BRIGHTON_FT_REQ, 0); brightonFastTimer(synth->win, page, (rand() & 0x0f) * 8 + 4, BRIGHTON_FT_REQ, 0); brightonFastTimer(synth->win, page, (rand() & 0x0f) * 8 + 4, BRIGHTON_FT_REQ, 0); brightonFastTimer(synth->win, page, (rand() & 0x0f) * 8 + 4, BRIGHTON_FT_REQ, 0); brightonFastTimer(synth->win, page, (rand() & 0x0f) * 8 + 4, BRIGHTON_FT_REQ, 0); brightonFastTimer(synth->win, page, (rand() & 0x0f) * 8 + 4, BRIGHTON_FT_REQ, 0); brightonFastTimer(synth->win, page, (rand() & 0x0f) * 8 + 4, BRIGHTON_FT_REQ, 0); brightonFastTimer(synth->win, page, (rand() & 0x0f) * 8 + 4, BRIGHTON_FT_REQ, 0); brightonFastTimer(synth->win, page, (rand() & 0x0f) * 8 + 4, BRIGHTON_FT_REQ, 0); brightonFastTimer(synth->win, page, (rand() & 0x0f) * 8 + 4, BRIGHTON_FT_REQ, 0); brightonFastTimer(synth->win, page, (rand() & 0x0f) * 8 + 4, BRIGHTON_FT_REQ, 0); brightonFastTimer(synth->win, page, (rand() & 0x0f) * 8 + 4, BRIGHTON_FT_REQ, 0); brightonFastTimer(synth->win, page, (rand() & 0x0f) * 8 + 4, BRIGHTON_FT_REQ, 0); brightonFastTimer(synth->win, page, (rand() & 0x0f) * 8 + 4, BRIGHTON_FT_REQ, 0); } } static void bmStuffCallbacks(guiSynth *synth) { bmMem *bm = (bmMem *) synth->mem.param; int seq, inc = 0; if (synth->flags & MEM_LOADING) return; /* * The next two changes would disable the sequence if we change it, that * is arguably correct? event.value = BRIGHTON_LED_OFF; brightonParamChange(synth->win, 4, 46, &event); event.value = BRIGHTON_LED_RED; brightonParamChange(synth->win, 4, 47, &event); */ /* * We have to consider which pages we are going to include, the page and * note ordering (U, D, UD, R) and perhaps eventually a time code 3/4, 4/4? brightonFastTimer(synth->win, 0, 4, BRIGHTON_FT_REQ, 0); */ if (bm->control.up != 0) { printf("Sequence Up: include page"); seq = BM_DIR_UP; } if (bm->control.down != 0) { printf("Sequence down: include page"); seq = BM_DIR_DOWN; } if (bm->control.updown != 0) { printf("Sequence updown: include page"); seq = BM_DIR_UPDOWN; } if (bm->control.rand != 0) { printf("Sequence rand: include page"); seq = BM_DIR_RAND; } if (bm->control.active[0] != 0) { printf(" A"); inc |= BM_INC_A; } if (bm->control.active[1] != 0) { printf(" B"); inc |= BM_INC_B; } if (bm->control.active[2] != 0) { printf(" C"); inc |= BM_INC_C; } if (bm->control.active[3] != 0) { printf(" D"); inc |= BM_INC_D; } brightonFastTimer(0, 0, 0, BRIGHTON_FT_CANCEL, 0); if (bm->control.up != 0) { /* Stuff the straight sequence */ if (bm->control.active[0] != 0) bmStuffPage(synth, 0, BM_DIR_UP); if (bm->control.active[1] != 0) bmStuffPage(synth, 1, BM_DIR_UP); if (bm->control.active[2] != 0) bmStuffPage(synth, 2, BM_DIR_UP); if (bm->control.active[3] != 0) bmStuffPage(synth, 3, BM_DIR_UP); } else if (bm->control.down != 0) { if (bm->control.active[0] != 0) bmStuffPage(synth, 0, BM_DIR_DOWN); if (bm->control.active[1] != 0) bmStuffPage(synth, 1, BM_DIR_DOWN); if (bm->control.active[2] != 0) bmStuffPage(synth, 2, BM_DIR_DOWN); if (bm->control.active[3] != 0) bmStuffPage(synth, 3, BM_DIR_DOWN); } else if (bm->control.updown != 0) { if (bm->control.active[0] != 0) bmStuffPage(synth, 0, BM_DIR_UP); if (bm->control.active[1] != 0) bmStuffPage(synth, 1, BM_DIR_UP); if (bm->control.active[2] != 0) bmStuffPage(synth, 2, BM_DIR_UP); if (bm->control.active[3] != 0) bmStuffPage(synth, 3, BM_DIR_UP); if (bm->control.active[3] != 0) bmStuffPage(synth, 3, BM_DIR_DOWN); if (bm->control.active[2] != 0) bmStuffPage(synth, 2, BM_DIR_DOWN); if (bm->control.active[1] != 0) bmStuffPage(synth, 1, BM_DIR_DOWN); if (bm->control.active[0] != 0) bmStuffPage(synth, 0, BM_DIR_DOWN); } else if (bm->control.rand != 0) { /* * Choose a random page, then request a random order of the notes. */ bmStuffPage(synth, rand() & 0x03, BM_DIR_RAND); bmStuffPage(synth, rand() & 0x03, BM_DIR_RAND); bmStuffPage(synth, rand() & 0x03, BM_DIR_RAND); bmStuffPage(synth, rand() & 0x03, BM_DIR_RAND); } printf("\n"); if (bm->control.start != 0) brightonFastTimer(0, 0, 0, BRIGHTON_FT_START, 0); } static int rmi = 0; static int bmMemory(guiSynth *synth, int fd, int chan, int c, int o, int v) { printf("bmMemory(%i %i %i %i %i)\n", fd, chan, c, o, v); if (synth->flags & MEM_LOADING) return(0); if ((synth->flags & OPERATIONAL) == 0) return(0); /* * We have 12 buttons, 0..9, load, save. */ switch (c) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: if (rmi) { rmi = 0; synth->location = c; } else if ((synth->location = synth->location * 10 + c) >= 1000) synth->location = c; displayPanelText(synth, "MEM", synth->location, 4, DISPLAY_DEV); break; case 10: /* * We have to send a notes off before reloading a sequence otherwise * we might leave notes dangling. */ bristolMidiSendMsg(fd, synth->sid, 127, 0, BRISTOL_ALL_NOTES_OFF); if (loadMemory(synth, "bassmaker", 0, synth->location, synth->mem.active, 0, BRISTOL_FORCE) < 0) displayPanelText(synth, "FREE", synth->location, 4,DISPLAY_DEV); else displayPanelText(synth, "LOAD", synth->location, 4,DISPLAY_DEV); bmStuffCallbacks(synth); bmMemShim(synth); rmi = 1; break; case 11: if (brightonDoubleClick(dc)) { displayPanelText(synth, "SAVE", synth->location, 4,DISPLAY_DEV); saveMemory(synth, "bassmaker", 0, synth->location, 0); rmi = 1; } break; } return(0); } /* * For the sake of ease of use, links have been placed here to be called * by any of the devices created. They would be better in some other file, * perhaps with this as a dispatch. * * Param refers to the device index in the locations table given below. */ static int bmCallback(brightonWindow * win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); int sendvalue; //printf("bmCallback(%i, %i, %f) %x\n", panel, index, value, synth); if (synth == 0) return(0); switch (panel) { case 1: index += TOTAL_DEVS; break; case 2: index += TOTAL_DEVS * 2; break; case 3: index += TOTAL_DEVS * 3; break; case 4: index += TOTAL_DEVS * 4; break; } if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0)) return(0); if (bmApp.resources[panel].devlocn[index].to == 1.0) sendvalue = value * (CONTROLLER_RANGE - 1); else sendvalue = value; synth->mem.param[index] = value; /* if ((!global.libtest) || (index >= ACTIVE_DEVS)) */ // if ((!global.libtest) || (index >= 40)) synth->dispatch[index].routine(synth, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); /* // else printf("dispatch[%p,%i](%i, %i, %i, %i, %i)\n", synth, index, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); // */ return(0); } static void bmPanelSwitch(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; bmMem *bm = (bmMem *) synth->mem.param; event.type = BRIGHTON_FLOAT; event.value = BRIGHTON_LED_OFF; brightonParamChange(synth->win, 4, 24, &event); brightonParamChange(synth->win, 4, 25, &event); brightonParamChange(synth->win, 4, 26, &event); brightonParamChange(synth->win, 4, 27, &event); event.type = BRIGHTON_EXPOSE; event.intvalue = 0; brightonParamChange(synth->win, 0, -1, &event); // event.type = BRIGHTON_EXPOSE; // event.intvalue = 0; brightonParamChange(synth->win, 1, -1, &event); // event.type = BRIGHTON_EXPOSE; // event.intvalue = 0; brightonParamChange(synth->win, 2, -1, &event); // event.type = BRIGHTON_EXPOSE; // event.intvalue = 0; brightonParamChange(synth->win, 3, -1, &event); event.type = BRIGHTON_FLOAT; event.value = BRIGHTON_LED_YELLOW_FLASHING; brightonParamChange(synth->win, 4, 24+c, &event); event.type = BRIGHTON_EXPOSE; event.intvalue = 1; brightonParamChange(synth->win, c, -1, &event); switch (c) { case 0: displayPanelText(synth, "panel A", c + 1, 4, DISPLAY_DEV); bm->pageSelect = 0; break; case 1: displayPanelText(synth, "panel B", c + 1, 4, DISPLAY_DEV); bm->pageSelect = 1; break; case 2: displayPanelText(synth, "panel C", c + 1, 4, DISPLAY_DEV); bm->pageSelect = 2; break; case 3: displayPanelText(synth, "panel D", c + 1, 4, DISPLAY_DEV); bm->pageSelect = 3; break; } } static void bmSendControl(guiSynth *synth, bmMem *bm, int c, int o) { /* * Control can have various possibilities ranging from a basic controller * change to note events and targetted device events. */ switch ((int) bm->control.ctype) { case BM_C_CONTROL: /* * Because of the way control.cc is implemented, this is actually * the second MIDI channel: this gives access to the first 15 CC */ bristolMidiSendMsg(global.controlfd, synth->midichannel, 0, bm->control.cc, (int) (bm->page[c].step[o].cont * C_RANGE_MIN_1)); break; case BM_C_NOTE: { int note, chan, velocity; /* * Convert the setting into 12 steps, take cc to be midi channel * Channel is the 'cc' setting here. */ if ((chan = bm->control.cc) > 15) chan = 15; note = (int) (bm->page[c].step[o].cont * 12); velocity = (int) (bm->page[c].step[o].velocity * 127); note += synth->transpose + bm->page[c].step[o].transp * 12; bristolMidiSendKeyMsg(global.controlfd, chan, BRISTOL_EVENT_KEYOFF, bm->lastcnote, velocity); bristolMidiSendKeyMsg(global.controlfd, chan, BRISTOL_EVENT_KEYON, note, velocity); bm->lastcnote = note; break; } case BM_C_GLIDE: /* * This is 126/0 for most emulators and that may need to be * enforced later. */ bristolMidiSendMsg(global.controlfd, synth->sid, 126, 0, (int) (bm->page[c].step[o].cont * C_RANGE_MIN_1)); break; case BM_C_TUNE: /* * This is 126/1 for most emulators and that may need to be * enforced later. */ bristolMidiSendMsg(global.controlfd, synth->sid, 126, 1, (int) (bm->page[c].step[o].cont * C_RANGE_MIN_1)); break; case BM_C_MOD: /* * This is CC #1 for most emulators and that may need to be * enforced later. */ bristolMidiSendMsg(global.controlfd, synth->midichannel, 0, 1, (int) (bm->page[c].step[o].cont * C_RANGE_MIN_1)); break; case BM_C_OPERATOR: /* * cop = operator, 126 will be typical use. * cc = controller of operator */ break; } } static void bmCallNote(guiSynth *synth, int fd, int chan, int c, int o, int v) { bmMem *bm = (bmMem *) synth->mem.param; int note = bm->page[c].step[o].note + synth->transpose + bm->page[c].step[o].transp * 12; int velocity = (int) (bm->page[c].step[o].velocity * 127); //printf("bmCallNote(%i, %i, %i)\n", c, o, v); /* * If we are stopped then send the note, otherwise do nothing */ if (bm->control.stop != 0) { bristolMidiSendKeyMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_KEYOFF, bm->lastnote, velocity); bmSendControl(synth, bm, c, o); bristolMidiSendKeyMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_KEYON, note, velocity); } bm->lastnote = note; bm->lastpage = c; bm->laststep = o; } static void bmCallTranspose(guiSynth *synth, int fd, int chan, int c, int o, int v) { bmMem *bm = (bmMem *) synth->mem.param; int note = bm->page[c].step[o].note + synth->transpose + bm->page[c].step[o].transp * 12; int velocity = (int) (bm->page[c].step[o].velocity * 127); /* * If we are stopped then send the note, otherwise do nothing */ if (bm->control.stop != 0) { bristolMidiSendKeyMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_KEYOFF, bm->lastnote, velocity); bmSendControl(synth, bm, c, o); bristolMidiSendKeyMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_KEYON, note, velocity); } bm->lastnote = note; bm->lastpage = c; bm->laststep = o; //printf("bmCallTranspose(%i, %i, %i)\n", c, o, v); } static void bmCallVolume(guiSynth *synth, int fd, int chan, int c, int o, int v) { bmMem *bm = (bmMem *) synth->mem.param; int note = bm->page[c].step[o].note + synth->transpose + bm->page[c].step[o].transp * 12; int velocity = (int) (bm->page[c].step[o].velocity * 127); /* * If we are stopped then send the note, otherwise do nothing */ if (bm->control.stop != 0) { bristolMidiSendKeyMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_KEYOFF, bm->lastnote, velocity); bmSendControl(synth, bm, c, o); bristolMidiSendKeyMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_KEYON, note, velocity); } bm->lastnote = note; bm->lastpage = c; bm->laststep = o; //printf("bmCallVolume(%i, %i, %i)\n", c, o, v); } static void bmCallController(guiSynth *synth, int fd, int chan, int c, int o, int v) { /* * If we are stopped then send the controller, otherwise do nothing */ //printf("bmCallController(%i, %i, %i)\n", c, o, v); } static void bmCallLed(guiSynth *synth, int fd, int chan, int c, int o, int v) { bmMem *bm = (bmMem *) synth->mem.param; int note; int velocity; /* * If we are playing then send the note on/off + control. Depending on the * configured LED state we may skip the note, skip the note off event, etc. */ //synth->mem.param[c * TOTAL_DEVS + o * OP_COUNT + 5]); note = bm->page[c].step[o].note + synth->transpose + bm->page[c].step[o].transp * 12; velocity = (int) (bm->page[c].step[o].velocity * 127); //printf("bmCallLed(%i, %i, %i) note %i, v %i \n", c, o, v, note, velocity); switch ((int) bm->page[c].step[o].button) { case 0: default: /* Send note on/off according to value */ if (v) { bmSendControl(synth, bm, c, o); bristolMidiSendKeyMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_KEYON, note, velocity); } else bristolMidiSendKeyMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_KEYOFF, note, velocity); break; case 1: /* Dont' send note off */ if (v) { bmSendControl(synth, bm, c, o); bristolMidiSendKeyMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_KEYON, note, velocity); } break; case 2: /* Dont' send note on, only off */ bristolMidiSendKeyMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_KEYOFF, note, velocity); return; case 3: /* * all notes off? Nothing? bristolMidiSendMsg(fd, synth->sid, 127, 0, BRISTOL_ALL_NOTES_OFF); */ return; } bm->lastnote = note; bm->lastpage = c; bm->laststep = o; } static void bmCallButton(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; printf("bmCallButton(%i, %i, %i)\n", c, o, c * TOTAL_DEVS + 0); event.type = BRIGHTON_FLOAT; if (++synth->mem.param[c * TOTAL_DEVS + o * OP_COUNT + 4] > 3) synth->mem.param[c * TOTAL_DEVS + o * OP_COUNT + 4] = 0; event.value = synth->mem.param[c * TOTAL_DEVS + o * OP_COUNT + 4]; brightonParamChange(synth->win, c, o * OP_COUNT + 4, &event); synth->mem.param[c * TOTAL_DEVS + o * OP_COUNT + 5] = synth->mem.param[c * TOTAL_DEVS + o * OP_COUNT + 4]; } static void bmCallPad1(guiSynth *synth, int fd, int chan, int c, int o, int v) { } static void bmCallPad2(guiSynth *synth, int fd, int chan, int c, int o, int v) { } static void bmSpeed(guiSynth *synth, int fd, int chan, int c, int o, int v) { /* * We need to stuff both speed and duty cycle printf("speed %f, duty %f\n", 10 + synth->mem.param[COFF + 0] * synth->mem.param[COFF + 0] * 990, (10 + synth->mem.param[COFF + 0] * synth->mem.param[COFF + 0] * 990) * synth->mem.param[COFF + 1]); */ /* * Speed should go from 10 to 1000ms? Can change that later. */ brightonFastTimer(0, 0, 0, BRIGHTON_FT_TICKTIME, 10 + synth->mem.param[COFF + 0] * synth->mem.param[COFF + 0] * 990); brightonFastTimer(0, 0, 0, BRIGHTON_FT_DUTYCYCLE, (10 + synth->mem.param[COFF + 0] * synth->mem.param[COFF + 0] * 990) * synth->mem.param[COFF + 1]); } static int ssEx = 0; static void bmDirection(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; if (v ==0) return; /* * Clear all the LED, light this one, stuff the callback table */ event.type = BRIGHTON_FLOAT; event.value = BRIGHTON_LED_OFF; brightonParamChange(synth->win, 4, 28, &event); brightonParamChange(synth->win, 4, 29, &event); brightonParamChange(synth->win, 4, 30, &event); brightonParamChange(synth->win, 4, 31, &event); switch (c) { case 0: synth->mem.param[COFF + 3] = synth->mem.param[COFF + 4] = synth->mem.param[COFF + 5] = 0; break; case 1: synth->mem.param[COFF + 2] = synth->mem.param[COFF + 4] = synth->mem.param[COFF + 5] = 0; break; case 2: synth->mem.param[COFF + 2] = synth->mem.param[COFF + 3] = synth->mem.param[COFF + 5] = 0; break; case 3: synth->mem.param[COFF + 2] = synth->mem.param[COFF + 3] = synth->mem.param[COFF + 4] = 0; break; } event.value = BRIGHTON_LED_GREEN; brightonParamChange(synth->win, 4, 28 + c, &event); bmStuffCallbacks(synth); } /* * Controller options * Controller to mod wheel * Controller to tune * Controller to pitchwheel * Controller to note (13 steps) + channel * Controller to other continuous controller * Controller to operator parameter (later) * Copy page * Save * Load */ static void bmCopyPage(guiSynth *synth, int fd, int chan, bmMem *bm, int from, int to) { int i; brightonEvent event; if (from == to) return; event.type = BRIGHTON_FLOAT; for (i = 0; i < PAGE_STEP; i++) { event.value = bm->page[from].step[i].note; brightonParamChange(synth->win, to, i * OP_COUNT + 0, &event); event.value = bm->page[from].step[i].transp; brightonParamChange(synth->win, to, i * OP_COUNT + 1, &event); event.value = bm->page[from].step[i].velocity; brightonParamChange(synth->win, to, i * OP_COUNT + 2, &event); event.value = bm->page[from].step[i].cont; brightonParamChange(synth->win, to, i * OP_COUNT + 3, &event); event.value = bm->page[from].step[i].led; brightonParamChange(synth->win, to, i * OP_COUNT + 4, &event); } } static char * copyMenu[5] = { "copy to A", "copy to B", "copy to C", "copy to D", 0 }; static char * ctlMenu[6] = { "CTL CC", "CTL NOTE", "CTL TUNE", "CTL Glide", "CTL MOD", 0 }; static char *transpMenu[26] = { "-12 Semitones", "-11 Semitones", "-10 Semitones", "-9 Semitones", "-8 Semitones", "-7 Semitones", "-6 Semitones", "-5 Semitones", "-4 Semitones", "-3 Semitones", "-2 Semitones", "-1 Semitone", "0 Semitones", "+1 Semitone", "+2 Semitones", "+3 Semitones", "+4 Semitones", "+5 Semitones", "+6 Semitones", "+7 Semitones", "+8 Semitones", "+9 Semitones", "+10 Semitones", "+11 Semitones", "+12 Semitones", 0 }; static char *midiChan[17] = { "MIDI CH 1", /* Bass channel selection. These should be submenu */ "MIDI CH 2", "MIDI CH 3", "MIDI CH 4", "MIDI CH 5", "MIDI CH 6", "MIDI CH 7", "MIDI CH 8", "MIDI CH 9", "MIDI CH 10", "MIDI CH 11", "MIDI CH 12", "MIDI CH 13", "MIDI CH 14", "MIDI CH 15", "MIDI CH 16", 0 }; static char *clearMenu[6] = { "Clear Note", "Clear Tranpose", "Clear Volume", "Clear Cont", "Clear Trigger", 0 }; static char *memMenu[4] = { "Find Up", "Mem Down", "Mem Up", 0 }; typedef struct bMenuList { char *title; int count; char **content; } bMenuList; #define B_M_C 7 typedef struct BMenu { bMenuList item[B_M_C]; int count; int current; int sub; } bMenu; bMenu mainMenu = { { {"Memory", 3, memMenu}, {"Copy", 4, copyMenu}, {"Controllers", 5, ctlMenu}, {"First MIDI", 16, midiChan}, {"Second MIDI", 16, midiChan}, {"Clear", 5, clearMenu}, {"Transpose", 25, transpMenu}, }, B_M_C, 0, -1 }; static void bmMultiMenuMove(guiSynth *synth, int fd, int chan, int c, int o, int v) { /* * We could be in the main menu or a submenu, need to check the submenu * setting then move through the text strings. */ if (mainMenu.sub == -1) { /* * Main menu */ if (v == 0) { if (--mainMenu.current < 0) mainMenu.current = mainMenu.count - 1; displayPanel(synth, mainMenu.item[mainMenu.current].title, synth->location, 4, DISPLAY_DEV); } else { if (++mainMenu.current >= mainMenu.count) mainMenu.current = 0; displayPanel(synth, mainMenu.item[mainMenu.current].title, synth->location, 4, DISPLAY_DEV); } } else { /* * Sub menu */ if (v == 0) { if (--mainMenu.sub < 0) mainMenu.sub = mainMenu.item[mainMenu.current].count - 1; displayPanel(synth, mainMenu.item[mainMenu.current].content[mainMenu.sub], synth->location, 4, DISPLAY_DEV); } else { if (++mainMenu.sub >= mainMenu.item[mainMenu.current].count) mainMenu.sub = 0; displayPanel(synth, mainMenu.item[mainMenu.current].content[mainMenu.sub], synth->location, 4, DISPLAY_DEV); } } } static void bmMenuFunction(guiSynth *synth, int fd, int chan, int c, int o, int v) { /* * For now just return to start of main menu */ mainMenu.sub = -1; displayPanel(synth, mainMenu.item[mainMenu.current].title, synth->location, 4, DISPLAY_DEV); } static void bmMultiMenuEnter(guiSynth *synth, int fd, int chan, int c, int o, int v) { bmMem *bm = (bmMem *) synth->mem.param; /* * Execute the desired function and save to a memory dummy location if * necessary (controller functions). */ if (mainMenu.sub < 0) { /* * We should preload a value here which is the current selected value */ switch (mainMenu.current) { case 3: mainMenu.sub = synth->midichannel; break; case 4: mainMenu.sub = bm->control.cc; break; case 6: mainMenu.sub = synth->transpose + 12; break; default: mainMenu.sub = 0; break; } displayPanel(synth, mainMenu.item[mainMenu.current].content[mainMenu.sub], synth->location, 4, DISPLAY_DEV); return; } switch (mainMenu.current) { case 0: /* Memory */ switch (mainMenu.sub) { case 2: { /* Mem Up */ int location = synth->location; while (loadMemory(synth, "bassmaker", 0, ++location, synth->mem.active, 0, BRISTOL_STAT) < 0) { if (location == synth->location) break; if (location == 1023) location = -1; } synth->location = location; displayPanelText(synth, "Mem", synth->location, 4, DISPLAY_DEV); break; } case 1: { /* Mem Down */ int location; if ((location = synth->location) == 0) location = 1024; while (loadMemory(synth, "bassmaker", 0, --location, synth->mem.active, 0, BRISTOL_STAT) < 0) { if (location == synth->location) break; if (location == 0) location = 1024; } synth->location = location; displayPanelText(synth, "Mem", synth->location, 4, DISPLAY_DEV); break; } case 0: { /* Mem Find Up */ int location = synth->location; while (loadMemory(synth, "bassmaker", 0, ++location, synth->mem.active, 0, BRISTOL_STAT) >= 0) { if (location == synth->location) break; if (location == 1023) location = 0; } synth->location = location; displayPanelText(synth, "Free", synth->location, 4, DISPLAY_DEV); break; } } break; case 1: /* Copy */ switch (mainMenu.sub) { case 0: /* Copy page */ bmCopyPage(synth, fd, chan, bm, bm->pageSelect, 0); break; case 1: /* Copy page */ bmCopyPage(synth, fd, chan, bm, bm->pageSelect, 1); break; case 2: /* Copy page */ bmCopyPage(synth, fd, chan, bm, bm->pageSelect, 2); break; case 3: /* Copy page */ bmCopyPage(synth, fd, chan, bm, bm->pageSelect, 3); break; } break; case 2: /* * Controllers */ switch (mainMenu.sub) { case 0: /* CC */ bm->control.ctype = 11; break; case 1: bm->control.ctype = -1; break; case 2: /* Set control function Pitch */ bm->control.ctype = -2; break; case 3: bm->control.ctype = -2; break; case 4: bm->control.ctype = -4; break; } break; case 3: /* Fist MIDI */ synth->midichannel = mainMenu.sub; break; case 4: /* Second MIDI */ bm->control.cc = mainMenu.sub; break; case 5: /* Clear Menu ops */ { int i, page, offset; brightonEvent event; event.type = BRIGHTON_FLOAT; page = bm->pageSelect; offset = mainMenu.sub; switch (offset) { case 0: default: event.value = 0; break; case 1: event.value = 1.0; break; case 2: event.value = 0.8; break; case 3: event.value = 0.5; break; } for (i = 0; i < PAGE_STEP; i++) { brightonParamChange(synth->win, page, i * OP_COUNT + offset, &event); } } break; case 6: /* Transpose */ bm->control.transpose = BM_TRANSPOSE + mainMenu.sub - 12; synth->transpose = BM_TRANSPOSE + mainMenu.sub - 12; break; } } static void bmMenu(guiSynth *synth, int fd, int chan, int c, int o, int v) { printf("bmMenu(%i, %i, %i)\n", c, o, v); switch(c) { case 0: /* Up menu */ bmMultiMenuMove(synth, fd, chan, c, o, 1); break; case 1: /* Down menu */ bmMultiMenuMove(synth, fd, chan, c, o, 0); break; case 2: /* Function */ bmMenuFunction(synth, fd, chan, c, o, v); break; case 3: /* Enter */ bmMultiMenuEnter(synth, fd, chan, c, o, v); break; } } static void bmPageSelect(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; event.type = BRIGHTON_FLOAT; if (v == 0) event.value = BRIGHTON_LED_OFF; else event.value = BRIGHTON_LED_GREEN; brightonParamChange(synth->win, 4, 20 + c, &event); bmStuffCallbacks(synth); } static void bmStartStop(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; bmMem *bm = (bmMem *) synth->mem.param; if (ssEx) { ssEx = 0; return; } event.type = BRIGHTON_FLOAT; bristolMidiSendMsg(fd, synth->sid, 127, 0, BRISTOL_ALL_NOTES_OFF); if (c == 1) { /* Stop */ event.value = BRIGHTON_LED_OFF; brightonParamChange(synth->win, 4, 46, &event); event.value = BRIGHTON_LED_RED; brightonParamChange(synth->win, 4, 47, &event); ((bmMem *) synth->mem.param)->lastnote = -1;; brightonFastTimer(0, 0, 0, BRIGHTON_FT_STOP, 0); /* And send a MIDI all notes off */ bristolMidiSendMsg(fd, synth->sid, 127, 0, BRISTOL_ALL_NOTES_OFF); ssEx = 1; event.value = 0.0; brightonParamChange(synth->win, 4, 44, &event); bm->clearstep = bm->laststep; bm->laststep = 0; } else { /* * There are two cases here, first press and second press. First press * will start the sequence, second will pause the sequence. * * When it is first press we need to clock the first element in the * list. */ if (bm->clearstep >= 0) { event.value = BRIGHTON_LED_OFF; brightonParamChange(synth->win, bm->lastpage, 4 + bm->clearstep * 8, &event); } bm->clearstep = -1; /* Turn off Stop LED */ event.value = BRIGHTON_LED_OFF; brightonParamChange(synth->win, 4, 47, &event); if (synth->mem.param[COFF + 45] != 0) { /* Stopped - toggle to green and run */ event.value = BRIGHTON_LED_GREEN; } else { /* If we were not stopped then were we running */ if (synth->mem.param[COFF + 44] != 0) { event.value = BRIGHTON_LED_GREEN; } else { event.value = BRIGHTON_LED_YELLOW_FLASHING; } } brightonParamChange(synth->win, 4, 46, &event); brightonFastTimer(0, 0, 0, BRIGHTON_FT_START, 0); event.command = BRIGHTON_FAST_TIMER; event.value = 1; brightonParamChange(synth->win, bm->lastpage, 4 + bm->laststep * 8, &event); ssEx = 1; event.value = 0.0; brightonParamChange(synth->win, 4, 45, &event); } } /* * Any location initialisation required to run the callbacks. For bristol, this * will connect to the engine, and give it some base parameters. * May need to generate some application specific menus. * Will also then make specific requests to some of the devices to alter their * rendering. */ static int bmInit(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); dispatcher *dispatch; int i; if (synth == 0) { synth = findSynth(global.synths, 0); if (synth == 0) { printf("cannot init\n"); return(0); } } call.control[0] = (synthRoutine) bmCallNote; call.control[1] = (synthRoutine) bmCallTranspose; call.control[2] = (synthRoutine) bmCallVolume; call.control[3] = (synthRoutine) bmCallController; call.control[4] = (synthRoutine) bmCallLed; call.control[5] = (synthRoutine) bmCallButton; call.control[6] = (synthRoutine) bmCallPad1; call.control[7] = (synthRoutine) bmCallPad2; synth->win = win; printf("Initialise the bm link to bristol: %p\n", synth->win); synth->mem.param = (float *) brightonmalloc(sizeof(bmMem)); synth->mem.count = sizeof(bmMem) / sizeof(float); synth->mem.active = ACTIVE_DEVS; synth->dispatch = (dispatcher *) brightonmalloc(DEVICE_COUNT * sizeof(dispatcher)); dispatch = synth->dispatch; /* * We really want to have three connection mechanisms. These should be * 1. Unix named sockets. * 2. UDP sockets. * 3. MIDI pipe. */ if (!global.libtest) if ((synth->sid = initConnection(&global, synth)) < 0) return(-1); for (i = 0; i < DEVICE_COUNT; i++) synth->dispatch[i].routine = bmMidiSendMsg; for (i = 0; i < PAGE_STEP * PAGE_COUNT * OP_COUNT; i++) { /* Page */ synth->dispatch[i].controller = i / (PAGE_STEP * OP_COUNT); /* Step */ synth->dispatch[i].operator = (i / OP_COUNT) % PAGE_STEP; /* Control index */ synth->dispatch[i].routine = call.control[i % OP_COUNT]; } /* Control Panel Speed/Duty */ synth->dispatch[COFF + 0].controller = 1; synth->dispatch[COFF + 1].controller = 2; synth->dispatch[COFF + 0].routine = synth->dispatch[COFF + 1].routine = (synthRoutine) bmSpeed; /* Dir */ synth->dispatch[COFF + 2].controller = 0; synth->dispatch[COFF + 3].controller = 1; synth->dispatch[COFF + 4].controller = 2; synth->dispatch[COFF + 5].controller = 3; synth->dispatch[COFF + 2].routine = synth->dispatch[COFF + 3].routine = synth->dispatch[COFF + 4].routine = synth->dispatch[COFF + 5].routine = (synthRoutine) bmDirection; /* Select/Include */ synth->dispatch[COFF + 6].controller = 0; synth->dispatch[COFF + 7].controller = 1; synth->dispatch[COFF + 8].controller = 2; synth->dispatch[COFF + 9].controller = 3; synth->dispatch[COFF + 6].routine = synth->dispatch[COFF + 7].routine = synth->dispatch[COFF + 8].routine = synth->dispatch[COFF + 9].routine = (synthRoutine) bmPageSelect; /* Edit */ synth->dispatch[COFF + 10].controller = 0; synth->dispatch[COFF + 11].controller = 1; synth->dispatch[COFF + 12].controller = 2; synth->dispatch[COFF + 13].controller = 3; synth->dispatch[COFF + 10].routine = synth->dispatch[COFF + 11].routine = synth->dispatch[COFF + 12].routine = synth->dispatch[COFF + 13].routine = (synthRoutine) bmPanelSwitch; synth->dispatch[COFF + 32].controller = 0; synth->dispatch[COFF + 33].controller = 1; synth->dispatch[COFF + 34].controller = 2; synth->dispatch[COFF + 35].controller = 3; synth->dispatch[COFF + 36].controller = 4; synth->dispatch[COFF + 37].controller = 5; synth->dispatch[COFF + 38].controller = 6; synth->dispatch[COFF + 39].controller = 7; synth->dispatch[COFF + 40].controller = 8; synth->dispatch[COFF + 41].controller = 9; synth->dispatch[COFF + 42].controller = 10; synth->dispatch[COFF + 43].controller = 11; /* Start/Stop */ synth->dispatch[COFF + 44].controller = 0; synth->dispatch[COFF + 45].controller = 1; synth->dispatch[COFF + 44].routine = synth->dispatch[COFF + 45].routine = (synthRoutine) bmStartStop; synth->dispatch[COFF + 32].routine = synth->dispatch[COFF + 33].routine = synth->dispatch[COFF + 34].routine = synth->dispatch[COFF + 35].routine = synth->dispatch[COFF + 36].routine = synth->dispatch[COFF + 37].routine = synth->dispatch[COFF + 38].routine = synth->dispatch[COFF + 39].routine = synth->dispatch[COFF + 40].routine = synth->dispatch[COFF + 41].routine = synth->dispatch[COFF + 42].routine = synth->dispatch[COFF + 43].routine = (synthRoutine) bmMemory; synth->dispatch[COFF + 55].controller = 0; synth->dispatch[COFF + 56].controller = 1; synth->dispatch[COFF + 57].controller = 2; synth->dispatch[COFF + 58].controller = 3; synth->dispatch[COFF + 55].routine = synth->dispatch[COFF + 56].routine = synth->dispatch[COFF + 57].routine = synth->dispatch[COFF + 58].routine = (synthRoutine) bmMenu; return(0); } /* * This will be called to make any routine specific parameters available. */ static int bmConfigure(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); brightonEvent event; if (synth == 0) { printf("problems going operational\n"); return(-1); } if (synth->flags & OPERATIONAL) return(0); printf("going operational\n"); synth->flags |= OPERATIONAL; synth->keypanel = 1; synth->keypanel2 = -1; synth->transpose = BM_TRANSPOSE; brightonPut(win, "bitmaps/blueprints/bmshade.xpm", 0, 0, win->width, win->height); event.type = BRIGHTON_EXPOSE; event.intvalue = 1; brightonParamChange(synth->win, 1, -1, &event); brightonParamChange(synth->win, 2, -1, &event); brightonParamChange(synth->win, 3, -1, &event); event.intvalue = 0; brightonParamChange(synth->win, 1, -1, &event); brightonParamChange(synth->win, 2, -1, &event); brightonParamChange(synth->win, 3, -1, &event); event.intvalue = 1; brightonParamChange(synth->win, 0, -1, &event); event.type = BRIGHTON_FLOAT; event.value = BRIGHTON_LED_YELLOW_FLASHING; brightonParamChange(synth->win, 4, 24, &event); /* Stop button */ event.value = BRIGHTON_LED_RED; brightonParamChange(synth->win, 4, 47, &event); event.value = 1.0; brightonParamChange(synth->win, 4, 45, &event); event.type = BRIGHTON_INT; event.intvalue = 1; event.value = 1; brightonParamChange(synth->win, 0, 4, &event); event.value = 18; brightonParamChange(synth->win, 0, 11, &event); event.value = 3; brightonParamChange(synth->win, 0, 18, &event); event.value = 1; brightonParamChange(synth->win, 0, 25, &event); loadMemory(synth, "bassmaker", 0, synth->location, synth->mem.active, 0, BRISTOL_FORCE); bmStuffCallbacks(synth); bmMemShim(synth); displayPanel(synth, "BASSMAKER", synth->location, 4, DISPLAY_DEV); dc = brightonGetDCTimer(win->dcTimeout); return(0); } bristol-0.60.11/brighton/brightonMixerMemory.c0000644000175000017500000003615011746476475016302 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include #include #include #include #include #include #include #include "bristol.h" #include "bristolmidi.h" #include "brightonMixer.h" #include "brightonMixerMemory.h" #include "brighton.h" #include "brightonMini.h" static mixerMem *new = NULL, *prev = NULL; static char songDir[32] = "default"; static DIR *memlist = NULL; static struct dirent *entry; extern guimain global; extern void displayPanel(guiSynth *, char *, int, int, int); /* * Most of this is actually borrowed from brightonroutines.c, but since the * mixer operations are a little central to the whole application have chosen * to make it bespoke */ int saveMixerMemory(guiSynth *synth, char *name) { char path[256]; int fd; sprintf(path, "%s/memory/%s/%s/%s.mem", getBristolCache("midicontrollermap"), "mixer", songDir, name); sprintf(synth->mem.algo, "mixer"); if (name == NULL) sprintf(synth->mem.name, "no name"); else sprintf(synth->mem.name, "%s", name); if ((fd = open(path, O_WRONLY|O_CREAT|O_TRUNC, 0660)) < 0) return(-1); if (write(fd, &synth->mem, sizeof(struct Memory) - sizeof(float *)) < 0) printf("write failed 1\n"); if (write(fd, synth->mem.param, sizeof(mixerMem)) < 0) printf("write failed 1\n"); close(fd); return(0); } static int doLoadMixerMemory(guiSynth *synth) { brightonEvent event; int channel, param; event.type = BRIGHTON_FLOAT; /* * Now we have the parameters loaded we need to start sending off events * to the GUI to draw the mixer, that will notify the engine and set the * parameters here again (as an undesirable sideffect); * * Going to start with the steroe bus section as it is (comparatively) easy. */ for (channel = 0; channel < 4; channel++) { event.value = new->vbus[channel].clear.vol; brightonParamChange(synth->win, BUS_PANEL, 240 + channel * 3, &event); event.value = new->vbus[channel].clear.left; brightonParamChange(synth->win, BUS_PANEL, 240 + channel * 3 + 1, &event); event.value = new->vbus[channel].clear.right; brightonParamChange(synth->win, BUS_PANEL, 240 + channel * 3 + 2, &event); } /* * Effects bussing section */ for (channel = 0; channel < 8; channel++) { /* * Six events for the continuous controllers */ for (param = 0; param < 6; param++) { event.value = new->bus[channel].b.opaque[param]; brightonParamChange(synth->win, BUS_PANEL, channel * 30 + param, &event); } /* * One event for the FX select new->bus[channel].b.clear.algorithm; */ event.value = 1.01; if (new->bus[channel].b.clear.algorithm < 0) { brightonParamChange(synth->win, BUS_PANEL, channel * 30 + 6, &event); event.value = 0.0; brightonParamChange(synth->win, BUS_PANEL, channel * 30 + 6, &event); } else { if (new->bus[channel].b.clear.algorithm != prev->bus[channel].b.clear.algorithm) brightonParamChange(synth->win, BUS_PANEL, channel * 30 + 6 + new->bus[channel].b.clear.algorithm, &event); } /* * Sixteen events for the output busses. */ for (param = 0; param < 16; param++) { /* if (new->bus[channel].b.clear.outputSelect[param] <= 0) event.value = 0.0; else event.value = 1.01; */ event.value = new->bus[channel].b.clear.outputSelect[param]; brightonParamChange(synth->win, BUS_PANEL, channel * 30 + 14 + param, &event); } } /* * And the channels themselves. */ for (channel = 0; channel < new->chancount; channel++) { /* * One event for the input selection. There are several logical states: * 1. New track has selection - call it. * 2. New Track has no selection - clear the previous one. */ if (new->chan[channel].inputSelect >= 0) { /* * Only apply if the parameter has changed */ if (new->chan[channel].inputSelect != prev->chan[channel].inputSelect) { event.value = 1.0; brightonParamChange(synth->win, channel + 4, new->chan[channel].inputSelect, &event); } } else { event.value = 1.0; brightonParamChange(synth->win, channel + 4, 0, &event); event.value = 0.0; brightonParamChange(synth->win, channel + 4, 0, &event); } /* * Presend bus selections */ for (param = 0; param < 4; param++) { event.value = new->chan[channel].preSend[param]; brightonParamChange(synth->win, channel + 4, 16 + param, &event); } /* * Dynamics algorithm selection */ if (new->chan[channel].dynamics >= 0) { if (new->chan[channel].dynamics != prev->chan[channel].dynamics) { event.value = 1.01; brightonParamChange(synth->win, channel + 4, 20 + new->chan[channel].dynamics, &event); } } else { event.value = 1.01; brightonParamChange(synth->win, channel + 4, 20, &event); event.value = 0.0; brightonParamChange(synth->win, channel + 4, 20, &event); } /* * Filter algorithm selection */ if (new->chan[channel].filter >= 0) { if (new->chan[channel].filter != prev->chan[channel].filter) { event.value = 1.01; brightonParamChange(synth->win, channel + 4, 23 + new->chan[channel].filter, &event); } } else { event.value = 1.01; brightonParamChange(synth->win, channel + 4, 23, &event); event.value = 0.0; brightonParamChange(synth->win, channel + 4, 23, &event); } /* * Postsend bus selections */ for (param = 0; param < 4; param++) { event.value = new->chan[channel].postSend[param]; brightonParamChange(synth->win, channel + 4, 27 + param, &event); } /* * FX algorithm selection */ if (new->chan[channel].fxAlgo >= 0) { if (new->chan[channel].fxAlgo != prev->chan[channel].fxAlgo) { event.value = 1.01; brightonParamChange(synth->win, channel + 4, 31 + new->chan[channel].fxAlgo, &event); } } else { event.value = 1.01; brightonParamChange(synth->win, channel + 4, 31, &event); event.value = 0.0; brightonParamChange(synth->win, channel + 4, 31, &event); } /* * Continuous controllers */ for (param = 0; param < 17; param++) { event.value = new->chan[channel].p.opaque[param]; brightonParamChange(synth->win, channel + 4, 38 + param, &event); } event.value = new->chan[channel].mute; brightonParamChange(synth->win, channel + 4, 55, &event); event.value = new->chan[channel].solo; brightonParamChange(synth->win, channel + 4, 56, &event); event.value = new->chan[channel].boost; brightonParamChange(synth->win, channel + 4, 57, &event); /* * Output select */ for (param = 0; param < 16; param++) { event.value = new->chan[channel].outputSelect[param]; brightonParamChange(synth->win, channel + 4, 58 + param, &event); } /* * vBus selection */ if (new->chan[channel].stereoBus >= 0) { if (new->chan[channel].stereoBus != prev->chan[channel].stereoBus) { event.value = 1.01; brightonParamChange(synth->win, channel + 4, 74 + new->chan[channel].stereoBus, &event); } } else { event.value = 1.01; brightonParamChange(synth->win, channel + 4, 74, &event); event.value = 0.0; brightonParamChange(synth->win, channel + 4, 74, &event); } event.value = new->chan[channel].p.clear.vol; brightonParamChange(synth->win, channel + 4, 78, &event); displayPanel(synth, new->chan[channel].scratch, 0, channel + 4, 79); sprintf(((mixerMem *) synth->mem.param)->chan[channel].scratch, "%s", new->chan[channel].scratch); } return(0); } /* * Saving the memory is reasonably trivial. Reading it back is a little more * work since we have to call the parameter routines to set the values. */ int loadMixerMemory(guiSynth *synth, char *name, int param) { char path[256]; int fd; if (param == 1) { sprintf(songDir, "%s", name); return(0); } if (param == 2) { if (strlen(name) != 0) { sprintf(path, "%s/memory/%s/%s", getBristolCache("midicontrollermap"), "mixer", name); mkdir(path, 0755); } return(0); } if (strcmp(name, "revert") == 0) { mixerMem *t; bcopy(prev, new, sizeof(mixerMem)); t = prev; prev = (mixerMem *) synth->mem.param; synth->mem.param = (float *) t; doLoadMixerMemory(synth); return(0); } sprintf(path, "%s/memory/%s/%s/%s.mem", getBristolCache("midicontrollermap"), "mixer", songDir, name); if ((fd = open(path, O_RDONLY, 0770)) < 0) { sprintf(path, "%s/memory/%s/%s/%s.mem", global.home, "mixer", songDir, name); if ((fd = open(path, O_RDONLY, 0770)) < 0) return(-1); } if (read(fd, &synth->mem.algo[0], 32) < 0) printf("read failed\n"); if (read(fd, &synth->mem.name[0], 32) < 0) printf("read failed\n"); if (read(fd, new, 2 * sizeof(int)) < 0) printf("read failed\n"); if (read(fd, new, sizeof(mixerMem)) < 0) printf("read failed\n"); bcopy(synth->mem.param, prev, sizeof(mixerMem)); doLoadMixerMemory(synth); close(fd); return(0); } /* * Get a memory structure, null it out, put in a few details and give it back */ void * initMixerMemory(int count) { int i; mixerMem *m; if ((m = (mixerMem *) malloc(sizeof(mixerMem))) == NULL) return(0); if ((new = (mixerMem *) malloc(sizeof(mixerMem))) == NULL) return(0); if ((prev = (mixerMem *) malloc(sizeof(mixerMem))) == NULL) return(0); bzero(m, sizeof(mixerMem)); sprintf(&m->name[0], "no name"); m->version = MIXER_VERSION; m->chancount = count; for (i = 0; i < MAX_CHAN_COUNT; i++) { m->chan[i].inputSelect = -1; m->chan[i].dynamics = -1; m->chan[i].filter = -1; m->chan[i].fxAlgo = -1; m->chan[i].stereoBus = -1; sprintf(&m->chan[i].scratch[0], "Trk: %i", i + 1); } for (i = 0; i < MAX_VBUS_COUNT; i++) m->bus[i].b.clear.algorithm = -1; bcopy(m, prev, sizeof(mixerMem)); return(m); } char * getMixerMemory(mixerMem *m, int op, int param) { char path[256], *dotptr; switch(op) { case MM_GETLIST: if (memlist == 0) { /* * See if we want to list songs or memories in a song dir */ if (param == 1) sprintf(path, "%s/memory/%s", global.home, "mixer"); else sprintf(path, "%s/memory/%s/%s", global.home, "mixer", songDir); if ((memlist = opendir(path)) == NULL) return(0); } if ((entry = readdir(memlist)) == 0) { closedir(memlist); memlist = NULL; return(0); } while (entry->d_name[0] == '.') { if ((entry = readdir(memlist)) == 0) { closedir(memlist); memlist = NULL; return(0); } } if ((dotptr = index(entry->d_name, '.')) != NULL) *dotptr = '\0'; /* * Call a set of routines that will open the directory and then * return its contents until finnished. */ return(entry->d_name); default: if (param == 79) { return(&m->chan[op - 4].scratch[0]); } } return(0); } int setMixerMemory(mixerMem *m, int op, int param, float *value, char *text) { int channel = 0, offset = 0; switch(op) { case VBUS_PANEL: /* * We expect parameters from 0 to 12, they will translate to * The bus:v/l/r */ channel = param / 3; offset = param % 3; m->vbus[channel].opaque[offset] = *value; break; case BUS_PANEL: /* * but parameters are opaque but I want to separate them out * here since the functions will be unique in the engine. */ channel = param / 30; offset = param % 30; if (offset < 6) /* * Continuous controllers */ m->bus[channel].b.opaque[offset] = *value; else if (offset < 14) { /* * FX Selector, single value */ if (*value == 0) m->bus[channel].b.clear.algorithm = -1; else m->bus[channel].b.clear.algorithm = offset - 6; } else if (offset < 30) { /* * Output channel selection */ m->bus[channel].b.clear.outputSelect[offset - 14] = *value; } break; default: channel = op - 4; offset = param; if (offset < 16) { /* * Input channel selection radio buttons */ if (*value == 0) { m->chan[channel].inputSelect = -1; } else { m->chan[channel].inputSelect = offset; } } else if (offset < 20) { /* * Presend bus selection. */ m->chan[channel].preSend[offset - 16] = *value; } else if (offset < 23) { /* * Dynamics also radio button selection. */ if (*value == 0) { m->chan[channel].dynamics = -1; } else { m->chan[channel].dynamics = offset - 20; } } else if (offset < 27) { /* * Filter algo radio button selection. */ if (*value == 0) { m->chan[channel].filter = -1; } else { m->chan[channel].filter = offset - 23; } } else if (offset < 31) { /* * Postsend bus selection. */ m->chan[channel].postSend[offset - 27] = *value; } else if (offset < 38) { /* * Effect radio button selection. */ if (*value == 0) { m->chan[channel].fxAlgo = -1; } else { m->chan[channel].fxAlgo = offset - 31; } } else if (offset < 55) { /* * The continuous controllers less fader */ m->chan[channel].p.opaque[offset - 38] = *value; } else if (offset == 55) { m->chan[channel].mute = *value; } else if (offset == 56) { m->chan[channel].solo = *value; } else if (offset == 57) { m->chan[channel].boost = *value; } else if (offset < 74) { m->chan[channel].outputSelect[offset - 58] = *value; } else if (offset < 78) { /* * vBus radio buttons */ if (*value == 0) { m->chan[channel].stereoBus = -1; } else { m->chan[channel].stereoBus = offset - 74; } } else if (offset == 78) { m->chan[channel].p.clear.vol = *value; } else if (offset == 79) { if (text != NULL) sprintf(m->chan[channel].scratch, "%s", text); } break; } return(0); } /* * loadMemory, saveMemory, initMemory, get/setMemory? */ /* wow. the return type of this varies depending on op. no. -DR */ int mixerMemory(guiSynth *synth, int op, int subop, int param, void *value) { switch(op) { case MM_SAVE: return(saveMixerMemory(synth, value)); case MM_LOAD: return(loadMixerMemory(synth, value, param)); case MM_INIT: /* * This was orginally a rather dumb typecast return((int) initMixerMemory(param)); * Need to review all of this code as the mixer gets rolled out */ return(0); case MM_SET: return(setMixerMemory((mixerMem *) synth->mem.param, subop, param, value, NULL)); /* * This will be moved into a separate call. case MM_GET: return(getMixerMemory((mixerMem *) synth->mem.param, subop, param, value)); */ } return(0); } bristol-0.60.11/brighton/brightonRoutines.c0000644000175000017500000005610411746476475015636 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include #include #include #include #include #include #include #include #include #include #include #include "bristol.h" #include "brightoninternals.h" #include "brightonMini.h" extern guimain global; extern void brightonMidiInput(bristolMidiMsg *, guimain *); struct sockaddr address; /* * Free any memory we have have used up, close the link to the control socket * potentially sending a disconnect request. */ void cleanupBristolQuietly() { /* * This comes from a sigpipe only. This means we have lost our socket to * to the engine OR our socket to the X server, which is a bit of a bummer * since in one case we want to send a message to the engine but if it * is this socket that failed we will then get a SIGPIPE again. * * Put the signal back on default handling and then call the normal * cleanup routines. If this was the engine socket then we will then die * reasonably gracefully..... global.controlfd = -1; cleanupBristol(); */ signal(SIGPIPE, SIG_DFL); signal(SIGINT, SIG_DFL); cleanupBristol(); } void cleanupBristol() { bristolMidiMsg msg; close(0); if (global.synths->win != 0) global.synths->win->flags |= BRIGHTON_EXITING; if (global.synths->flags & REQ_DEBUG_MASK) printf("cleanupBrighton()\n"); if (global.libtest) { global.flags |= REQ_EXIT; return; } if (global.controlfd < 0) { global.flags |= REQ_EXIT; return; } /* * We don't need to clean out every synth, we need to cleanout the second * manual if it is configured, then the controlfd bristolMidiSendNRP(global.controlfd, global.synths->sid, BRISTOL_NRP_MIDI_GO, 0); */ if ((global.manualfd != 0) && (global.manualfd != global.controlfd)) { bristolMidiSendMsg(global.manualfd, global.synths->sid2, 127, 0, BRISTOL_EXIT_ALGO); if (global.synths->flags & REQ_DEBUG_MASK) printf("Secondary layer removed\n"); /* OK, so sleep is lax, we used to wait for a message */ bristolMidiRead(global.controlfd, &msg); } /* The engine has to restart MIDI processing after the exit */ bristolMidiSendNRP(global.controlfd, global.synths->sid, BRISTOL_NRP_MIDI_GO, 0); bristolMidiSendMsg(global.controlfd, global.synths->sid, 127, 0, BRISTOL_EXIT_ALGO); if (global.synths->flags & REQ_DEBUG_MASK) printf("Primary layer removed\n"); /* We used to wait for a message however it is of no interest now */ //bristolMidiRead(global.controlfd, &msg); usleep(250000); if ((global.manualfd != 0) && (global.manualfd != global.controlfd)) bristolMidiClose(global.manualfd); bristolMidiClose(global.controlfd); printf("brighton exiting\n"); //BAutoRepeat(global.synths->win->display, 1); //sleep(1); global.flags |= REQ_EXIT; //exit(0); } int destroySynth(brightonWindow* win) { guiSynth *synth = findSynth(global.synths, win); bristolMidiMsg msg; printf("destroySynth(%p): %i\n", win, synth->sid); /* * Since we registered two synths, we now need to remove the upper * manual. */ bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_EXIT_ALGO); if (bristolMidiRead(global.controlfd, &msg) < 0) printf("socket closed\n"); return(0); } void displayPanel(guiSynth *synth, char *text, int value, int panel, int index) { brightonEvent event; char display[32]; memset(&event, 0, sizeof(brightonEvent)); sprintf(display, "%s", text); event.type = BRIGHTON_MEM; event.m = (void *) &display[0]; brightonParamChange(synth->win, panel, index, &event); } int displayPanelText(guiSynth *synth, char *text, int value, int panel, int index) { brightonEvent event; char display[32]; memset(&event, 0, sizeof(brightonEvent)); sprintf(display, "%s: %i", text, value); event.type = BRIGHTON_MEM; event.m = (void *) &display[0]; brightonParamChange(synth->win, panel, index, &event); return(0); } int displayText(guiSynth *synth, char *text, int value, int index) { brightonEvent event; char display[32]; memset(&event, 0, sizeof(brightonEvent)); sprintf(display, "%s: %i", text, value); event.type = BRIGHTON_MEM; event.m = (void *) &display[0]; brightonParamChange(synth->win, synth->panel, index, &event); return(0); } guiSynth * findSynth(guiSynth *synth, brightonWindow* win) { /*printf("findSynth(%x, %x)\n", synth, reference); */ if (synth == 0) return(0); if (synth->win == win) return(synth); return(findSynth(synth->next, win)); } static char *myHome = NULL; char * oldgetBristolCache() { /* * See if we have a valid private directory, if we do not find one then * create it. */ if (myHome == NULL) { struct stat statbuf; char *envcache; char path[1024]; myHome = (char *) calloc(1024, 1); /* * See if we have an env configured if so see if it exists, if not * create a tree. * * If this fails then use $HOME/.bristol and create the tree. * * If these fail then fall back to the factory tree. */ if ((envcache = getenv("BRISTOL_CACHE")) != NULL) { /* * See if we can access the cache. */ if (stat(envcache, &statbuf) == 0) { /* * If we have the cache, is it formatted and do we have * permissions? There are several cases: * We own it and have rw permissions. * Somebody else owns it but we have write permissions * We are in the group and have write permissions. * I think we should only take the first option since otherwise * we can create memories that other users may not be able to * access due to our umask. */ sprintf(path, "%s/memory", envcache); if (stat(path, &statbuf) == 0) { if (((statbuf.st_uid != getuid()) || ((statbuf.st_mode & 0600) != 0600))) envcache = NULL; else strcpy(myHome, envcache); } else { if (mkdir(path, 0755) != 0) envcache = NULL; else { sprintf(path, "%s/memory/profiles", envcache); mkdir(path, 0755); strcpy(myHome, envcache); } } } else { /* * So, we have an env variable but cannot access it. See if we * can create it. */ if (mkdir(envcache, 0755) != 0) envcache = NULL; else { sprintf(path, "%s/memory", envcache); mkdir(path, 0755); sprintf(path, "%s/memory/profiles", envcache); mkdir(path, 0755); strcpy(myHome, envcache); } } } /* * If the cache is still null it means either we do not have an * environment variable or it is not accessible. */ if (envcache == NULL) { /* This obviously won't happen often, but anyway: */ if ((envcache = getenv("HOME")) == NULL) { if (envcache == NULL) envcache = global.home; } else { /* * Use home directory. If we do not have a tree then create it * again. */ sprintf(path, "%s/.bristol", envcache); sprintf(myHome, "%s", path); if (stat(path, &statbuf) != 0) { mkdir(path, 0755); sprintf(path, "%s/.bristol/memory", envcache); mkdir(path, 0755); sprintf(path, "%s/.bristol/memory/profiles", envcache); mkdir(path, 0755); } } } } return(myHome); } extern char *getBristolCache(char *); int getMemoryLocation(char *algo, char *name, int location, int perms) { char path[256], *ppath, *ext = "mem"; int fd; /* * This should look for a private copy, and if not found then look for * a public copy. */ if ((name != 0) && (name[0] == '/')) sprintf(path, "%s", name); else { struct stat statbuf; /* * So this should get us our memory location. We need to look and see * if we have a directory for this emulation and create it if not. */ ppath = getBristolCache(algo); sprintf(path, "%s/memory/%s", ppath, algo); if (stat(path, &statbuf) != 0) { /* * If we cannot stat the private location then we really ought to * look and see if .bristol exists. If so then we should create a * tree to include memory/algo and return it */ mkdir(path, 0755); } if (name != NULL) ext = name; sprintf(path, "%s/memory/%s/%s%i.%s", ppath, algo, algo, location, ext); } if ((fd = open(path, perms, 0600)) < 0) { //printf("%s\n", path); sprintf(path, "%s/memory/%s/%s%i.%s", global.home, algo, algo, location, ext); return(open(path, perms, 0660)); } //printf("%s\n", path); return(fd); } #define RECOPY_MAX_FILE 1024 * 1024 static void bsmCopy(char *src, char *dst) { char buffer[RECOPY_MAX_FILE]; int srcfd, dstfd, count; srcfd = open(src, O_RDONLY); if ((count = read(srcfd, buffer, RECOPY_MAX_FILE)) > 0) { dstfd = open(dst, O_WRONLY|O_TRUNC|O_CREAT, 0644); count = write(dstfd, buffer, count); close(dstfd); } close(srcfd); } /* * The next two will copy files into and out of the bristol cache. Read is only * really used on system startup if a session file has been given by Jack SM but * it could be more general. Write will copy cache files out to wherever they * have been requested. */ int bristolMemoryExport(int source, char *dst, char *algo) { char srcpath[1024]; char fpath[1024]; snprintf(srcpath, 1024, "%s/memory/%s/%s%i.mem", getBristolCache(algo), algo, algo, source); bsmCopy(srcpath, dst); printf("Export %s to %s\n", srcpath, dst); snprintf(srcpath, 1024, "%s/memory/%s/%s%i.seq", getBristolCache(algo), algo, algo, source); snprintf(fpath, 1024, "%s.seq", dst); bsmCopy(srcpath, fpath); snprintf(fpath, 1024, "%s.prof", dst); brightonWriteConfiguration( global.synths->win, algo, global.synths->midichannel, fpath); return(0); } int bristolMemoryImport(int dest, char *src, char *algo) { char dstpath[1024]; char fpath[1024]; snprintf(dstpath, 1024, "%s/memory/%s/%s%i.mem", getBristolCache(algo), algo, algo, dest); bsmCopy(src, dstpath); printf("Import %s to %s\n", src, dstpath); snprintf(fpath, 1024, "%s.seq", src); snprintf(dstpath, 1024, "%s/memory/%s/%s%i.seq", getBristolCache(algo), algo, algo, dest); bsmCopy(fpath, dstpath); snprintf(fpath, 1024, "%s.prof", src); brightonReadConfiguration( global.synths->win, global.synths->win->template, global.synths->midichannel, algo, fpath); //brightonReadConfiguration(synth->win, algo, synth->midichannel, fpath); return(0); } static int checkSeqMem(arpeggiatorMemory *mem) { if ((mem->s_max < 0) || (mem->s_max > BRISTOL_SEQ_MAX) || (mem->c_count < 0) || (mem->c_count > BRISTOL_CHORD_MAX)) return(-1); return(0); } /* * Just to be aware if you reading this, the GUI does not sequence the engine * or play chords. The calls below tell the engine to go into learning mode * and then we tell it what keys it should store. The engine then sequences * and chords. */ int fillSequencer(guiSynth *synth, arpeggiatorMemory *mem, int flags) { int sid = synth->sid; int i; if (flags & BRISTOL_NOCALLS) return(0); if (checkSeqMem(mem) < 0) { printf("Sequencer sizing problem: %f %p\n", mem->s_max, mem->chord); return(-1); } if (flags & BRISTOL_SID2) sid = synth->sid2; if ((synth->flags & REQ_DEBUG_MASK) > REQ_MIDI_DEBUG2) printf("Sending Arpeggiation to engine: %i events\n", (int) mem->s_max); printf("fill sequence %i\n", (int) mem->s_max); if (mem->s_max > 0) { bristolMidiSendMsg(global.controlfd, sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RESEQ, 1); printf("send arpeggiation: %i\n", (int) mem->s_max); for (i = 0; i < mem->s_max; i++) { printf("arpeggio step %i is %i\n", i, (int) mem->sequence[i]); bristolMidiSendMsg(global.controlfd, sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_KEY, (int) mem->sequence[i]); } } bristolMidiSendMsg(global.controlfd, sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RESEQ, 0); if ((synth->flags & REQ_DEBUG_MASK) > REQ_MIDI_DEBUG2) printf("Sending Chord to engine: %i events\n", (int) mem->c_count); if (mem->c_count > 0) { bristolMidiSendMsg(global.controlfd, sid, BRISTOL_ARPEGGIATOR, BRISTOL_CHORD_RESEQ, 1); for (i = 0; i < mem->c_count; i++) { printf("chord %i is %i\n", i, (int) mem->chord[i]); bristolMidiSendMsg(global.controlfd, sid, BRISTOL_ARPEGGIATOR, BRISTOL_CHORD_KEY, (int) mem->chord[i]); } } bristolMidiSendMsg(global.controlfd, sid, BRISTOL_ARPEGGIATOR, BRISTOL_CHORD_RESEQ, 0); return(0); } int loadSequence(memory *seq, char *algo, int location, int flags) { int fd; memory tmem; if (seq->param == NULL) { seq->param = brightonmalloc(sizeof(arpeggiatorMemory)); bzero(seq->param, sizeof(arpeggiatorMemory)); seq->count = sizeof(arpeggiatorMemory) / sizeof(float); seq->active = seq->count; seq->vers = 0; sprintf(&seq->algo[0], "bristol sequencer"); } if ((fd = getMemoryLocation(algo, "seq", location, O_RDONLY)) < 0) return(-1); if (read(fd, &tmem.algo[0], 32) < 0) { printf("read failed on params\n"); close(fd); return(-1); } if (read(fd, &tmem.name[0], 32) < 0) { printf("read failed on name\n"); close(fd); return(-1); } if (read(fd, &tmem.count, 4 * sizeof(short)) < 0) { printf("read failed opts\n"); close(fd); return(-1); } if (tmem.vers != 0) { /* * Future revisions to the memory structures should put hooks in here */ printf("read failed: vers %i no supported\n", tmem.vers); close(fd); return(-1); } if (strcmp(&tmem.algo[0], "bristol sequencer") != 0) { if (tmem.algo[0] == '\0') printf("Attempt to read (noname) into sequencer\n"); else printf("Attempt to read %s into sequencer\n", &tmem.algo[0]); if ((flags & BRISTOL_SEQFORCE) == 0) { close(fd); return(-1); } sprintf(&seq->algo[0], "%s", algo); } else { sprintf(&seq->algo[0], "%s", &tmem.algo[0]); sprintf(&seq->name[0], "%s", &tmem.name[0]); } if (seq->count != tmem.count) printf("Sequence structure size mismatched %i vs %i\n", seq->count, tmem.count); if (tmem.count > seq->count) tmem.count = seq->count; seq->vers = tmem.vers; if (read(fd, &seq->param[0], tmem.count * sizeof(float)) < 0) printf("read failed\n"); close(fd); printf("loaded sequence\n"); return(0); } int loadMemory(guiSynth *synth, char *algo, char *name, int location, int active, int skip, int flags) { brightonEvent event; int i, fd, panel = 0, index = 0; memory tmem; memset(&event, 0, sizeof(brightonEvent)); /*printf("loadmemory %i: %s %x\n", location, synth->resources->name, flags); */ if (active == 0) active = synth->mem.active; synth->lmem = synth->cmem; synth->cmem = location; if (flags & BRISTOL_SEQLOAD) { if (BRISTOL_SID2) { if (loadSequence(&synth->seq2, algo, location, flags) >= 0) /* * These should now have given us a half valid arpeggioMemory * structure, pass it off to some code to do a sanity check * and then send the keys to the engine */ fillSequencer(synth, (arpeggiatorMemory *) synth->seq2.param, flags); else printf("sequencer memory not found\n"); } else { if (loadSequence(&synth->seq1, algo, location, flags) >= 0) fillSequencer(synth, (arpeggiatorMemory *) synth->seq1.param, flags); else printf("sequencer memory not found\n"); } } location += synth->mbi; if (location >= 0) { if ((fd = getMemoryLocation(algo, name, location, O_RDONLY)) < 0) return(-1); if (flags & BRISTOL_STAT) { close(fd); return(0); } if (read(fd, &tmem.algo[0], 32) < 0) { printf("read failed on params\n"); close(fd); return(-1); } if (read(fd, &tmem.name[0], 32) < 0) { printf("read failed on name\n"); close(fd); return(-1); } if (read(fd, &tmem.count, 4 * sizeof(short)) < 0) { printf("read failed opts\n"); close(fd); return(-1); } if (tmem.vers != 0) { /* * Future revisions to the memory structures should put hooks in * here */ printf("read failed: vers %i no supported\n", synth->mem.vers); close(fd); return(-1); } if (strcmp(&tmem.algo[0], algo) != 0) { if ((flags & BRISTOL_FORCE) == 0) { if (tmem.algo[0] == '\0') printf("Attempt to read (noname) into %s algorithm\n", algo); else printf("Attempt to read %s into %s algo\n", &tmem.algo[0], algo); close(fd); return(-1); } sprintf(&synth->mem.algo[0], "%s", algo); } else { sprintf(&synth->mem.algo[0], "%s", &tmem.algo[0]); sprintf(&synth->mem.name[0], "%s", &tmem.name[0]); } synth->mem.count = tmem.count; synth->mem.vers = tmem.vers; if (((synth->flags & REQ_DEBUG_MASK) > REQ_MIDI_DEBUG2) && (synth->mem.active != tmem.active)) printf("Active count changed. Overriding\n"); /* synth->mem.active = tmem.active; */ if (read(fd, &synth->mem.param[skip], active * sizeof(float)) < 0) printf("read failed\n"); close(fd); if (flags & BRISTOL_NOCALLS) return(0); } else memset(synth->mem.param, 0, active * sizeof(float)); synth->flags |= MEM_LOADING; /* * We now have to call the GUI to configure all these values. The GUI * will then call us back with the parameters to send to the synth. */ for (i = 0; i < active; i++) { event.type = BRIGHTON_FLOAT; event.value = synth->mem.param[i]; /* * We need to find which panel hosts this memory index. If we only * have one panel, this is easy, it has all the controls. If we have * multiple then we need to go through them all. */ if (synth->resources->nresources == 1) brightonParamChange(synth->win, synth->panel, i, &event); else { index = i; for (panel = 0; panel < synth->resources->nresources; panel++) { if ((index - synth->resources->resources[panel].ndevices) < 0) { /* * If this is a text panel, skip it. */ if (synth->resources->resources[panel].devlocn[index].device == 3) continue; /* * The next is odd, and could break a couple of the synth * memories, but if the value that is in the newly loaded * memory is outside of the configured range then we are * not going to set the value. */ if ((synth->resources->resources[panel].devlocn[index].from < synth->resources->resources[panel].devlocn[index].to) && ((synth->resources->resources[panel].devlocn[index].from > event.value) || (synth->resources->resources[panel].devlocn[index].to < event.value))) continue; brightonParamChange(synth->win, panel, index, &event); break; } else index -= synth->resources->resources[panel].ndevices; } } } synth->flags &= ~MEM_LOADING; return(0); } int saveSequence(guiSynth *synth, char *algo, int location, int flags) { memory *seq = &synth->seq1; int fd; if (flags & BRISTOL_SID2) seq = &synth->seq2; /* * Try and save our sequencer information. */ if (seq->param != NULL) { if ((fd = getMemoryLocation( algo, "seq", location, O_WRONLY|O_CREAT|O_TRUNC)) < 0) return(-1); if (checkSeqMem((arpeggiatorMemory *) seq->param) >= 0) { printf("Saving %i steps\n", (int) ((arpeggiatorMemory *) seq->param)->s_max); if (write(fd, seq, sizeof(struct Memory) - sizeof(float *)) < 0) printf("seq write failed 1\n"); if (write(fd, seq->param, sizeof(arpeggiatorMemory)) < 0) printf("seq write failed 2\n"); } else { printf("problem saving sequencer memory\n"); close(fd); return(-1); } close(fd); } return(0); } int saveMemory(guiSynth *synth, char *algo, char *name, int location, int skip) { int fd; if (location < 0) return(0); location += synth->mbi; if ((fd = getMemoryLocation(algo, name, location, O_WRONLY|O_CREAT|O_TRUNC)) < 0) return(-1); if (write(fd, &synth->mem, sizeof(struct Memory) - sizeof(float *)) < 0) printf("mem write failed 1\n"); if (write(fd, &synth->mem.param[skip], synth->mem.active * sizeof(float)) < 0) printf("mem write failed 2\n"); /* * Save global profile with controller registrations. No filename is given * so that the called code will take the cache copy. */ brightonWriteConfiguration(synth->win, algo, synth->midichannel, NULL); close(fd); return(0); } static void connectengine(guimain *global) { int flags; flags = BRISTOL_CONN_TCP|BRISTOL_DUPLEX|BRISTOL_CONN_NBLOCK| (global->flags & BRISTOL_CONN_FORCE); if ((global->controlfd = bristolMidiOpen(global->host, flags, global->port, -1, brightonMidiInput, global)) < 0) { printf("opening link to engine: %i\n", global->port); if ((global->controlfd = bristolMidiOpen(global->host, flags, global->port, -1, brightonMidiInput, global)) < 0) cleanupBristol(); } else printf("%s already active (%i)\n", BRISTOL_ENGINE, global->controlfd); } int initConnection(guimain *global, guiSynth *synth) { bristolMidiMsg msg; int sid = -1; connectengine(global); //printf("initConnection()\n"); /* * send a hello, with a voice count, then request starting of the * synthtype. All of these will require an ACK, and we should wait here * and read that ack before proceeding with each next step. */ bristolMidiSendMsg(global->controlfd, synth->midichannel, /* 127, 0, BRISTOL_HELLO|BRISTOL_VOICES|synth->voices); */ 127, 0, BRISTOL_HELLO|synth->voices); if (synth->sid > 0) synth->sid2 = global->controlfd + 1; if (bristolMidiRead(global->controlfd, &msg) != BRISTOL_OK) { printf("unacknowledged request on %i\n", global->controlfd); bristolMidiPrint(&msg); sleep(1); global->flags |= REQ_EXIT; return(-1); } /* * The returned value is the connection ID that we need to use for all * further system conversations. */ sid = (msg.params.bristol.valueMSB << 7) + msg.params.bristol.valueLSB; if (synth->flags & REQ_MIDI_DEBUG2) { printf("sid is %i (%i, %i)\n", sid, msg.params.bristol.valueMSB, msg.params.bristol.valueLSB); bristolMidiPrint(&msg); } bristolMidiSendMsg(global->controlfd, sid, 127, 0, BRISTOL_MIDICHANNEL|synth->midichannel); if (bristolMidiRead(global->controlfd, &msg) != BRISTOL_OK) { bristolMidiSendMsg(global->controlfd, sid, 127, 0, BRISTOL_MIDICHANNEL|synth->midichannel); if (bristolMidiRead(global->controlfd, &msg) != BRISTOL_OK) { printf("unacknowledged request on %i\n", sid); bristolMidiPrint(&msg); sleep(1); global->flags |= REQ_EXIT; return(-1); } } bristolMidiSendMsg(global->controlfd, sid, 127, 0, BRISTOL_REQSTART); if (bristolMidiRead(global->controlfd, &msg) != BRISTOL_OK) { printf("unacknowledged request on %i\n", sid); sleep(1); global->flags |= REQ_EXIT; return(-1); } /*printf(" initialising one connection of type %i\n", synth->synthtype); */ bristolMidiSendMsg(global->controlfd, sid, 127, 0, BRISTOL_INIT_ALGO|synth->synthtype); if (bristolMidiRead(global->controlfd, &msg) != BRISTOL_OK) { printf("unacknowledged request on %i\n", sid); sleep(1); global->flags |= REQ_EXIT; return(-1); } return(sid); } bristol-0.60.11/brighton/brightonVImages.h0000644000175000017500000027123011746476475015365 00000000000000 #define POLY_WHITE 0x00b8bab7 #define BLUE_WHITE 0x00d0d0ff #define BLUE_WHITE2 0x00c4e4ff #define OFF_WHITE 0x00d0d0d0 #define OFF_WHITER 0x00eeeeee bvgCoords potCoords[17] = { {28, 5}, {75, 100}, {-1, -1}, {7, 25}, {95, 75}, {-1, -1}, {72, 5}, {25, 100}, {-1, -1}, {93, 25}, {7, 75}, {-1, -1}, {0, 50}, {100, 50}, {-1, -1}, {50, 0}, {50, 50}, }; bvgVect pot = { 17, potCoords }; bvgCoords sharpCoords[11] = { {30, 10}, {30, 100}, {-1, -1}, {70, 0}, {70, 90}, {-1, -1}, {10, 30}, {100, 30}, {-1, -1}, {0, 80}, {90, 80}, }; bvgVect sharp = { 11, sharpCoords }; bvgCoords flatCoords[6] = { {0, 0}, {0, 80}, {20, 100}, {60, 60}, {40, 40}, {0, 60}, }; bvgVect flat = { 6, flatCoords }; bvgCoords invenvCoords[5] = { {0, 0}, {20, 0}, {20, 100}, {80, 0}, {100, 0}, }; bvgVect invenv = { 5, invenvCoords }; bvgCoords envCoords[5] = { {0, 100}, {20, 100}, {20, 0}, {80, 100}, {100, 100}, }; bvgVect env = { 5, envCoords }; bvgCoords gateCoords[6] = { {0, 100}, {10, 100}, {10, 0}, {80, 0}, {80, 100}, {100, 100}, }; bvgVect gate = { 6, gateCoords }; bvgCoords pulseWaveCoords[10] = { {0, 100}, {0, 0}, {40, 0}, {40, 100}, {100, 100}, {100, 0}, {-1, -1}, {50, 0}, {70, 0}, {70, 60}, }; bvgVect pulseWave = { 10, pulseWaveCoords }; bvgCoords pWaveCoords[6] = { {0, 100}, {0, 0}, {30, 0}, {30, 100}, {100, 100}, {100, 0}, }; bvgVect pWave = { 6, pWaveCoords }; bvgCoords sineWaveCoords[12] = { {0, 60}, {0, 40}, {16, 10}, // 16 {24, 0}, // 8 {32, 10}, // 8 {48, 40}, // 16 {48, 60}, {64, 94}, // 16 {72, 100},//8 {80, 94},//8 {96, 60}, {96, 30}, }; bvgVect sineWave = { 12, sineWaveCoords }; bvgCoords squareWaveCoords[6] = { {0, 100}, {0, 0}, {50, 0}, {50, 100}, {100, 100}, {100, 0}, }; bvgVect squareWave = { 6, squareWaveCoords }; bvgCoords triWaveCoords[3] = { {0, 100}, {50, 0}, {100, 100}, }; bvgVect triWave = { 3, triWaveCoords }; bvgCoords biRampWaveCoords[5] = { {0, 100}, {70, 20}, {70, 80}, {100, 0}, {100, 100}, }; bvgVect biRampWave = { 5, biRampWaveCoords }; bvgCoords sawWaveCoords[4] = { {0, 0}, {0, 100}, {100, 0}, {100, 100}, }; bvgVect sawWave = { 4, sawWaveCoords }; bvgCoords rampWaveCoords[4] = { {0, 100}, {0, 0}, {100, 100}, {100, 0}, }; bvgVect rampWave = { 4, rampWaveCoords }; /* * Stuff for the ARP. There will be lots, might break it out */ #define aPAC 103 bvgCoords arpPABoxCoords[aPAC] = { {14, 2}, {35, 2}, {35, 85}, {14, 85}, {14, 112}, {69, 112}, {69, 85}, {33, 85}, {-1, -1}, {69, 101}, {71, 101}, {71, 98}, {74, 101}, {71, 104}, {71, 99}, // Env Follower {-1, -1}, {2, 144}, {2, 170}, {43, 170}, {43, 144}, {2, 144}, {-1, -1}, {47, 144}, {47, 170}, {68, 170}, {68, 144}, {47, 144}, {-1, -1}, {69, 158}, {71, 158}, {71, 155}, {74, 158}, {71, 161}, {71, 155}, // First Arrow {-1, -1}, {9, 228}, {9, 179}, {7, 179}, {9, 174}, {11, 179}, {9, 179}, {-1, -1}, {27, 270}, {27, 179}, {25, 179}, {27, 174}, {29, 179}, {27, 179}, {-1, -1}, {46, 228}, {53, 205}, {53, 179}, {51, 179}, {53, 174}, {55, 179}, {51, 179}, {-1, -1}, {84, 228}, {63, 205}, {63, 179}, {61, 179}, {63, 174}, {65, 179}, {63, 179}, {-1, -1}, {0, 415}, {0, 447}, {18, 447}, {18, 415}, {0, 415}, {-1, -1}, {9, 415}, {9, 407}, {7, 407}, {9, 403}, {11, 407}, {9, 407}, {-1, -1}, {36, 415}, {36, 447}, {55, 447}, {55, 415}, {36, 415}, {-1, -1}, {45, 415}, {45, 407}, {43, 407}, {45, 403}, {47, 407}, {45, 407}, {-1, -1}, {75, 415}, {75, 447}, {93, 447}, {93, 415}, {75, 415}, {-1, -1}, {84, 415}, {84, 407}, {83, 407}, {84, 403}, {85, 407}, {84, 407}, }; bvgVect arpPABox = { aPAC, arpPABoxCoords }; /* * Stuff for the ARP. There will be lots, might break it out */ #define aVCO1 105 bvgCoords arpVCO1BoxCoords[aVCO1] = { {0, 10}, {0, 200}, {-1, -1}, {36, 82}, {36, 97}, {128, 97}, {128, 82}, {36, 82}, {-1, -1}, {128, 84}, {134, 84}, {138, 82}, {-1, -1}, {128, 95}, {134, 95}, {138, 97}, {-1, -1}, {12, 128}, {12, 115}, {58, 107}, {58, 100}, {55, 100}, {58, 98}, {61, 100}, {58, 100}, {-1, -1}, {68, 115}, {74, 107}, {74, 100}, {71, 100}, {74, 98}, {77, 100}, {71, 100}, {-1, -1}, {109, 115}, {92, 107}, {92, 100}, {89, 100}, {92, 98}, {95, 100}, {89, 100}, {-1, -1}, {152, 115}, {110, 107}, {110, 100}, {107, 100}, {110, 98}, {113, 100}, {107, 100}, {-1, -1}, {8, 187}, {8, 199}, {48, 199}, {48, 187}, {8, 187}, {28, 187}, {28, 184}, {26, 184}, {28, 182}, {30, 184}, {26, 184}, {-1, -1}, {52, 187}, {52, 199}, {87, 199}, {87, 187}, {52, 187}, {71, 187}, {71, 184}, {69, 184}, {71, 182}, {73, 184}, {69, 184}, {-1, -1}, {90, 187}, {90, 199}, {130, 199}, {130, 187}, {90, 187}, {110, 187}, {110, 184}, {108, 184}, {110, 182}, {112, 184}, {108, 184}, {-1, -1}, {136, 187}, {136, 199}, {175, 199}, {175, 187}, {136, 187}, {157, 187}, {157, 184}, {155, 184}, {157, 182}, {159, 184}, {155, 184}, {-1, -1}, {153, 169}, {153, 167}, {143, 167}, {-1, -1}, {26, 169}, {26, 167}, {36, 167}, }; bvgVect arpVCO1Box = { aVCO1, arpVCO1BoxCoords }; #define aVCO1a 19 bvgCoords arpVCO1aBoxCoords[aVCO1a] = { {179, 187}, {179, 199}, {215, 199}, {215, 187}, {179, 187}, {198, 187}, {198, 184}, {196, 184}, {198, 182}, {200, 184}, {198, 184}, {-1, -1}, {129, 87}, {180, 87}, {185, 84}, {-1, -1}, {129, 92}, {180, 92}, {185, 95}, }; bvgVect arpVCO1aBox = { aVCO1a, arpVCO1aBoxCoords }; #define aMOD 241 bvgCoords arpMODBoxCoords[aMOD] = { // NOISE {109, 4}, {109, 22}, {253, 22}, {253, 4}, {109, 4}, {-1, -1}, {270, 0}, {270, 290}, {-1, -1}, // VOLTAGE PROCESSING {385, 4}, {385, 22}, {554, 22}, {554, 4}, {385, 4}, {-1, -1}, {340, 65}, {386, 65}, {386, 62}, {394, 65}, {386, 68}, {386, 65}, {-1, -1}, {340, 123}, {386, 123}, {386, 120}, {394, 123}, {386, 126}, {386, 123}, {-1, -1}, {340, 180}, {386, 180}, {386, 177}, {394, 180}, {386, 183}, {386, 180}, {-1, -1}, {340, 235}, {386, 235}, {386, 232}, {394, 235}, {386, 238}, {386, 235}, {-1, -1}, {552, 65}, {655, 65}, {655, 42}, {633, 42}, {-1, -1}, {655, 65}, {655, 96}, {633, 96}, {-1, -1}, {655, 96}, {655, 123}, {552, 123}, {-1, -1}, {655, 80}, {665, 80}, {665, 75}, {675, 80}, {665, 85}, {665, 80}, {-1, -1}, {675, 80}, {685, 80}, {-1, -1}, {552, 180}, {635, 180}, {635, 175}, {645, 180}, {635, 185}, {635, 180}, {-1, -1}, {610, 180}, {610, 170}, {-1, -1}, {645, 180}, {675, 180}, {-1, -1}, {655, 180}, {655, 140}, {675, 140}, {-1, -1}, {552, 235}, {594, 235}, {594, 225}, {628, 225}, {628, 245}, {594, 245}, {594, 235}, {-1, -1}, {628, 235}, {675, 235}, {-1, -1}, {745, 0}, {745, 290}, {-1, -1}, // S&H {808, 12}, {812, 12}, {812, 9}, {819, 12}, {812, 15}, {812, 12}, {-1, -1}, {930, 12}, {936, 12}, {936, 9}, {943, 12}, {936, 15}, {936, 12}, {-1, -1}, {820, 4}, {820, 22}, {930, 22}, {930, 4}, {820, 4}, {-1, -1}, {755, 37}, {755, 68}, {815, 68}, {815, 37}, {755, 37}, {790, 37}, {790, 34}, {-1, -1}, {780, 155}, {770, 165}, {770, 285}, {936, 285}, {936, 233}, {-1, -1}, {780, 245}, {770, 255}, {-1, -1}, {790, 249}, {790, 260}, {872, 260}, {872, 30}, {869, 30}, {872, 25}, {875, 30}, {872, 30}, {-1, -1}, // The Electroswitch and connections {943, 100}, {940, 100}, {940, 187}, {955, 187}, {-1, -1}, {977, 143}, {983, 143}, {983, 187}, {970, 187}, {-1, -1}, {963, 182}, {963, 234}, {-1, -1}, {950, 198}, {946, 202}, {-1, -1}, {1004, 0}, {1004, 290}, {-1, -1}, // FX {1046, 4}, {1046, 22}, {1130, 22}, {1130, 4}, {1046, 4}, {-1, -1}, {1200, 4}, {1200, 22}, {1285, 22}, {1285, 4}, {1200, 4}, {-1, -1}, {1037, 70}, {1050, 45}, {1050, 28}, {1048, 28}, {1050, 25}, {1052, 28}, {1050, 28}, {-1, -1}, {1071, 70}, {1076, 45}, {1076, 28}, {1074, 28}, {1076, 25}, {1078, 28}, {1076, 28}, {-1, -1}, {1105, 70}, {1100, 45}, {1100, 28}, {1098, 28}, {1100, 25}, {1102, 28}, {1100, 28}, {-1, -1}, {1139, 70}, {1123, 45}, {1123, 28}, {1121, 28}, {1123, 25}, {1125, 28}, {1123, 28}, {-1, -1}, {1037 + 158, 70}, {1208, 45}, {1208, 28}, {1206, 28}, {1208, 25}, {1210, 28}, {1208, 28}, {-1, -1}, {158 + 1071, 70}, {158 + 1076, 45}, {158 + 1076, 28}, {158 + 1074, 28}, {158 + 1076, 25}, {158 + 1078, 28}, {158 + 1076, 28}, {-1, -1}, {158 + 1105, 70}, {158 + 1100, 45}, {158 + 1100, 28}, {158 + 1098, 28}, {158 + 1100, 25}, {158 + 1102, 28}, {158 + 1100, 28}, {-1, -1}, {158 + 1139, 70}, {158 + 1123, 45}, {158 + 1123, 28}, {158 + 1121, 28}, {158 + 1123, 25}, {158 + 1125, 28}, {158 + 1123, 28}, {-1, -1}, {1334, 0}, {1334, 290}, {-1, -1},// PROG // IN/OUT }; bvgVect arpMODBox = { aMOD, arpMODBoxCoords }; #define aMIX 158 bvgCoords arpMIXBoxCoords[aMIX] = { {0, 10}, {0, 200}, // Main Box {-1, -1}, {11, 83}, {11, 95}, {80, 95}, {80, 83}, {11, 83}, // Mix Arrows {-1, -1}, {26, 116}, {26, 114}, {24, 114}, {26, 112}, {28, 114}, {24, 114}, {-1, -1}, {68, 116}, {68, 114}, {66, 114}, {68, 112}, {70, 114}, {66, 114}, {-1, -1}, {26, 95}, {26, 98}, {24, 98}, {26, 100}, {28, 98}, {24, 98}, {-1, -1}, {68, 95}, {68, 98}, {66, 98}, {68, 100}, {70, 98}, {66, 98}, // Diverse lines {-1, -1}, {47, 83}, {47, 79}, {-1, -1}, {47, 68}, {47, 66}, {56, 61}, {-1, -1}, {76, 52}, {85, 47}, {-1, -1}, {110, 69}, {110, 64}, {73, 47}, {6, 47}, {6, 25}, {13, 25}, {13, 20}, {29, 25}, {13, 30}, {13, 22}, {-1, -1}, {6, 41}, {16, 41}, {-1, -1}, {6, 47}, {16, 52}, // Pan lines {-1, -1}, {77, 35}, {30, 35}, {30, 34}, {24, 35}, {30, 36}, {30, 35}, {-1, -1}, {110, 35}, {150, 35}, {150, 34}, {156, 35}, {150, 36}, {150, 35}, // Delay lines and box {-1, -1}, {95, 134}, {95, 143}, {165, 143}, {165, 134}, {95, 134}, {-1, -1}, {110, 134}, {110, 121}, {108, 121}, {110, 118}, {112, 121}, {110, 121}, {-1, -1}, {152, 134}, {152, 121}, {150, 121}, {152, 118}, {154, 121}, {152, 121}, {-1, -1}, {110, 170}, {110, 147}, {108, 147}, {110, 144}, {112, 147}, {110, 147}, // Outer line {-1, -1}, {163, 155}, {172, 152}, {172, 25}, {162, 25}, {162, 20}, {146, 25}, {162, 30}, {162, 25}, {-1, -1}, {172, 41}, {166, 41}, {-1, -1}, {172, 57}, {169, 57}, {-1, -1}, {172, 64}, {154, 70}, // Input Arrows {-1, -1}, {6, 187}, {6, 199}, {43, 199}, {43, 187}, {6, 187}, {27, 187}, {27, 184}, {25, 184}, {27, 182}, {29, 184}, {26, 184}, {-1, -1}, {47, 187}, {47, 199}, {87, 199}, {87, 187}, {47, 187}, {71, 187}, {71, 184}, {69, 184}, {71, 182}, {73, 184}, {69, 184}, {-1, -1}, {90, 187}, {90, 199}, {134, 199}, {134, 187}, {90, 187}, {110, 187}, {110, 184}, {108, 184}, {110, 182}, {112, 184}, {108, 184}, }; bvgVect arpMIXBox = { aMIX, arpMIXBoxCoords }; #define aVCA 97 bvgCoords arpVCABoxCoords[aVCA] = { {0, 10}, {0, 200}, // Main Box {-1, -1}, {38, 82}, {38, 97}, {126, 97}, {126, 82}, {38, 82}, {-1, -1}, {126, 90}, {132, 90}, {132, 89}, {139, 90}, {132, 91}, {132, 90}, // Input Arrows {-1, -1}, {28, 115}, {10, 96}, {10, 84}, {30, 84}, {30, 83}, {37, 84}, {30, 85}, {30, 84}, {-1, -1}, {70, 115}, {21, 96}, {21, 93}, {30, 93}, {30, 92}, {37, 93}, {30, 94}, {30, 93}, {-1, -1}, {110, 115}, {68, 102}, {68, 100}, {66, 100}, {68, 98}, {70, 100}, {68, 100}, {-1, -1}, {150, 115}, {108, 102}, {108, 100}, {106, 100}, {108, 98}, {110, 100}, {108, 100}, {-1, -1}, {6, 187}, {6, 199}, {43, 199}, {43, 187}, {6, 187}, {27, 187}, {27, 184}, {25, 184}, {27, 182}, {29, 184}, {26, 184}, {-1, -1}, {47, 187}, {47, 199}, {87, 199}, {87, 187}, {47, 187}, {71, 187}, {71, 184}, {69, 184}, {71, 182}, {73, 184}, {69, 184}, {-1, -1}, {90, 187}, {90, 199}, {130, 199}, {130, 187}, {90, 187}, {110, 187}, {110, 184}, {108, 184}, {110, 182}, {112, 184}, {108, 184}, {-1, -1}, {134, 187}, {134, 199}, {173, 199}, {173, 187}, {134, 187}, {152, 187}, {152, 184}, {150, 184}, {152, 182}, {154, 184}, {153, 184}, }; bvgVect arpVCABox = { aVCA, arpVCABoxCoords }; /* * Stuff for the ARP. There will be lots, might break it out */ #define aVCF 196 bvgCoords arpVCFBoxCoords[aVCF] = { {0, 10}, {0, 200}, // Main Box {-1, -1}, {156, 82}, {156, 97}, {284, 97}, {284, 82}, {156, 82}, {-1, -1}, {284, 90}, {293, 90}, {293, 89}, {300, 90}, {293, 91}, {293, 90}, // Input Arrows {-1, -1}, {30, 115}, {30, 110}, {98, 84}, //{152, 84}, {147, 84}, {147, 83}, {152, 84}, {147, 85}, {147, 84}, {-1, -1}, {70, 115}, {70, 110}, {102, 87}, {147, 87}, {147, 86}, {152, 87}, {147, 88}, {147, 87}, {-1, -1}, {110, 115}, {110, 110}, {110, 90}, {147, 90}, {147, 89}, {152, 90}, {147, 91}, {147, 90}, {-1, -1}, {152, 115}, {152, 110}, {123, 93}, {147, 93}, {147, 92}, {152, 93}, {147, 94}, {-1, -1}, {194, 115}, {194, 110}, {135, 96}, {147, 96}, {147, 95}, {152, 96}, {147, 97}, {147, 96}, {-1, -1}, {237, 115}, {237, 100}, {234, 100}, {237, 98}, {240, 100}, {237, 100}, {-1, -1}, {280, 115}, {280, 112}, {254, 106}, {254, 100}, {251, 100}, {254, 98}, {257, 100}, {254, 100}, {-1, -1}, {321, 115}, {321, 112}, {270, 106}, {270, 100}, {267, 100}, {270, 98}, {273, 100}, {270, 100}, {-1, -1}, {27, 170}, {27, 167}, {81, 167}, {-1, -1}, {194, 170}, {194, 167}, {139, 167}, {-1, -1}, {235, 170}, {235, 167}, {244, 167}, {-1, -1}, {320, 170}, {320, 167}, {313, 167}, {-1, -1}, {6, 187}, {6, 199}, {48, 199}, {48, 187}, {6, 187}, {27, 187}, {27, 184}, {25, 184}, {27, 182}, {29, 184}, {26, 184}, {-1, -1}, {52, 187}, {52, 199}, {87, 199}, {87, 187}, {52, 187}, {71, 187}, {71, 184}, {69, 184}, {71, 182}, {73, 184}, {69, 184}, {-1, -1}, {90, 187}, {90, 199}, {130, 199}, {130, 187}, {90, 187}, {110, 187}, {110, 184}, {108, 184}, {110, 182}, {112, 184}, {108, 184}, {-1, -1}, {134, 187}, {134, 199}, {170, 199}, {170, 187}, {134, 187}, {152, 187}, {152, 184}, {150, 184}, {152, 182}, {154, 184}, {153, 184}, {-1, -1}, {174, 187}, {174, 199}, {216, 199}, {216, 187}, {174, 187}, {195, 187}, {195, 184}, {191, 184}, {195, 182}, {197, 184}, {193, 184}, {-1, -1}, {220, 187}, {220, 199}, {256, 199}, {256, 187}, {220, 187}, {232, 187}, {232, 184}, {230, 184}, {232, 182}, {234, 184}, {232, 184}, {-1, -1}, {260, 187}, {260, 199}, {302, 199}, {302, 187}, {260, 187}, {278, 187}, {278, 184}, {276, 184}, {278, 182}, {280, 184}, {278, 184}, {-1, -1}, {306, 187}, {306, 199}, {344, 199}, {344, 187}, {306, 187}, {321, 187}, {321, 184}, {319, 184}, {321, 182}, {323, 184}, {321, 184}, }; bvgVect arpVCFBox = { aVCF, arpVCFBoxCoords }; #define aADSR 85 bvgCoords arpADSRBoxCoords[aADSR] = { {0, 10}, {0, 200}, {-1, -1}, {15, 82}, {15, 97}, {110, 97}, {110, 82}, {15, 82}, {-1, -1}, {110, 90}, {120, 90}, {120, 89}, {127, 90}, {120, 91}, {120, 89}, {-1, -1}, {72, 153}, {72, 165}, {140, 165}, {140, 153}, {72, 153}, {105, 153}, {105, 149}, {80, 149}, {80, 150}, {72, 149}, {80, 148}, {80, 150}, {-1, -1}, {87, 165}, {87, 167}, {96, 170}, {-1, -1}, {125, 165}, {125, 167}, {134, 170}, {-1, -1}, {66, 170}, {58, 167}, {58, 160}, {56, 160}, {58, 158}, {60, 160}, {58, 160}, // AR BOX {-1, -1}, {55, 129}, {55, 140}, {130, 140}, {130, 129}, {55, 129}, {-1, -1}, {58, 145}, {58, 143}, {56, 143}, {58, 141}, {60, 143}, {58, 140}, {-1, -1}, {110, 129}, {110, 127}, {-1, -1}, {105, 193}, {107, 193}, {107, 191}, {114, 191}, {114, 193}, {116, 193}, {-1, -1}, {140, 193}, {142, 193}, {142, 191}, {142, 193}, {155, 193}, {-1, -1}, {48, 187}, {48, 199}, {87, 199}, {87, 187}, {48, 187}, {71, 187}, {71, 184}, {69, 184}, {71, 182}, {73, 184}, {69, 184}, }; bvgVect arpADSRBox = { aADSR, arpADSRBoxCoords }; bvgImage arpImage = { 1771, 1000, 0x00000000, 204, { {{BVG_STRING, BLUE_WHITE2, 47, 74, 20, 8, "on"}}, // ODD MODS {{BVG_STRING, BLUE_WHITE2, 113, 135, 130, 8, "MAX GLIDE"}}, {{BVG_STRING, BLUE_WHITE2, 75, 214, 110, 8, "PREAMPLIFIER"}}, {{BVG_STRING, BLUE_WHITE2, 195, 245, 25, 6, "OUT"}}, {{BVG_VECT, BLUE_WHITE2, 38, 101, 200, 120, (char *) &arpPABox}}, {{BVG_STRING, BLUE_WHITE2, 47, 278, 80, 8, "ENVELOPE"}}, {{BVG_STRING, BLUE_WHITE2, 47, 290, 80, 8, "FOLLOWER"}}, {{BVG_STRING, BLUE_WHITE2, 136, 278, 40, 8, "RING"}}, {{BVG_STRING, BLUE_WHITE2, 140, 290, 30, 8, "MOD"}}, {{BVG_STRING, BLUE_WHITE2, 195, 310, 25, 6, "OUT"}}, {{BVG_STRING, BLUE_WHITE2, 185, 345, 45, 8, "AUDIO"}}, {{BVG_STRING, BLUE_WHITE2, 82, 470, 25, 6, "OUT"}}, {{BVG_STRING, BLUE_WHITE2, 199, 533, 18, 7, "DC"}}, {{BVG_STRING, BLUE_WHITE2, 44, 607, 28, 8, "PRE"}}, {{BVG_STRING, BLUE_WHITE2, 44, 621, 28, 8, "AMP"}}, {{BVG_STRING, BLUE_WHITE2, 115, 607, 36, 8, "VCO1"}}, {{BVG_STRING, BLUE_WHITE2, 190, 607, 36, 8, "VCO2"}}, {{BVG_VECT|2, BLUE_WHITE2, 116, 620, 24, 9, (char *) &rampWave}}, {{BVG_VECT|2, BLUE_WHITE2, 195, 620, 24, 9, (char *) &sineWave}}, {{BVG_STRING, BLUE_WHITE2, 240, 45, 200, 8, "INITIAL OSC FREQUENCY"}}, {{BVG_STRING, BLUE_WHITE2, 240, 63, 200, 8, " -7 +7 "}}, {{BVG_STRING, BLUE_WHITE2, 240, 74, 200, 8, " .03 0.3 3.0 30 "}}, {{BVG_STRING, BLUE_WHITE2, 240, 115, 200, 8, " FINE TUNE "}}, {{BVG_STRING, BLUE_WHITE2, 240, 155, 200, 8, " OSCILLATOR SYNC "}}, {{BVG_STRING, BLUE_WHITE2, 304, 200, 80, 8, "1<-2 SYNC"}}, {{BVG_STRING, BLUE_WHITE2, 258, 185, 25, 8, "2'"}}, {{BVG_STRING, BLUE_WHITE2, 258, 201, 25, 8, "4'"}}, {{BVG_STRING, BLUE_WHITE2, 258, 218, 25, 8, "8'"}}, {{BVG_STRING, BLUE_WHITE2, 258, 234, 30, 8, "16'"}}, {{BVG_STRING, BLUE_WHITE2, 258, 252, 35, 8, "32'"}}, {{BVG_STRING, BLUE_WHITE2, 372, 230, 30, 6, "SAW"}}, {{BVG_STRING, BLUE_WHITE2, 372, 288, 30, 6, "OUT"}}, {{BVG_STRING, BLUE_WHITE2, 358, 346, 60, 6, "SQUARE"}}, {{BVG_VECT, BLUE_WHITE2, 232, 10, 100, 315, (char *) &arpVCO1Box}}, {{BVG_STRING|3, BLUE_WHITE2, 278, 280, 85, 20, "VCO1"}}, {{BVG_STRING, BLUE_WHITE2, 258, 430, 30, 8, "LFO"}}, {{BVG_STRING, BLUE_WHITE2, 258, 445, 40, 8, "AUDIO"}}, {{BVG_STRING, BLUE_WHITE2, 258, 460, 30, 8, "KBD"}}, {{BVG_STRING, BLUE_WHITE2, 280, 530, 100, 8, "FM CONTROL"}}, {{BVG_STRING, BLUE_WHITE2, 250, 607, 28, 8, "KBD"}}, {{BVG_STRING, BLUE_WHITE2, 254, 621, 18, 8, "CV"}}, {{BVG_STRING, BLUE_WHITE2, 290, 607, 28, 8, "S/H"}}, {{BVG_STRING, BLUE_WHITE2, 290, 621, 28, 8, "OUT"}}, {{BVG_STRING, BLUE_WHITE2, 326, 612, 36, 8, "ADSR"}}, {{BVG_STRING, BLUE_WHITE2, 372, 607, 36, 8, "VCO2"}}, {{BVG_VECT|2, BLUE_WHITE2, 374, 620, 24, 9, (char *) &sineWave}}, {{BVG_VECT, BLUE_WHITE2, 413, 10, 100, 315, (char *) &arpVCO1Box}}, {{BVG_STRING|3, BLUE_WHITE2, 454, 280, 85, 20, "VCO2"}}, {{BVG_STRING, BLUE_WHITE2, 440, 45, 200, 8, "INITIAL OSC FREQUENCY"}}, {{BVG_STRING, BLUE_WHITE2, 440, 63, 200, 8, " -7 +7 "}}, {{BVG_STRING, BLUE_WHITE2, 440, 74, 200, 8, " .03 0.3 3.0 30 "}}, {{BVG_STRING, BLUE_WHITE2, 440, 115, 200, 8, " FINE TUNE "}}, {{BVG_STRING, BLUE_WHITE2, 440, 165, 200, 8, " 10% 50% 90% "}}, {{BVG_STRING, BLUE_WHITE2, 440, 190, 200, 8, " PULSE WIDTH "}}, {{BVG_STRING, BLUE_WHITE2, 438, 185, 25, 8, "2'"}}, {{BVG_STRING, BLUE_WHITE2, 438, 201, 25, 8, "4'"}}, {{BVG_STRING, BLUE_WHITE2, 438, 218, 25, 8, "8'"}}, {{BVG_STRING, BLUE_WHITE2, 438, 234, 30, 8, "16'"}}, {{BVG_STRING, BLUE_WHITE2, 438, 252, 35, 8, "32'"}}, {{BVG_STRING, BLUE_WHITE2, 547, 230, 100, 6, "TRIANGLE SAW"}}, {{BVG_STRING, BLUE_WHITE2, 552, 288, 30, 6, "OUT"}}, {{BVG_STRING, BLUE_WHITE2, 552, 346, 90, 6, "SINE PULSE"}}, {{BVG_STRING, BLUE_WHITE2, 552, 360, 90, 6, " PWM "}}, {{BVG_STRING, BLUE_WHITE2, 438, 430, 30, 8, "LFO"}}, {{BVG_STRING, BLUE_WHITE2, 438, 445, 40, 8, "AUDIO"}}, {{BVG_STRING, BLUE_WHITE2, 438, 460, 30, 8, "KBD"}}, {{BVG_STRING, BLUE_WHITE2, 455, 530, 190, 8, "FM CONTROL PWM"}}, {{BVG_STRING, BLUE_WHITE2, 430, 607, 28, 8, "KBD"}}, // 180 {{BVG_STRING, BLUE_WHITE2, 434, 621, 18, 8, "CV"}}, {{BVG_STRING, BLUE_WHITE2, 470, 607, 28, 8, "S/H"}}, {{BVG_STRING, BLUE_WHITE2, 470, 621, 28, 8, "OUT"}}, {{BVG_STRING, BLUE_WHITE2, 506, 612, 36, 8, "ADSR"}}, {{BVG_STRING, BLUE_WHITE2, 553, 607, 36, 8, "VCO1"}}, {{BVG_VECT|2, BLUE_WHITE2, 554, 620, 24, 9, (char *) &squareWave}}, {{BVG_STRING, BLUE_WHITE2, 596, 607, 36, 8, "NOISE"}}, {{BVG_STRING, BLUE_WHITE2, 596, 621, 36, 8, " GEN "}}, {{BVG_VECT, BLUE_WHITE2, 413, 10, 100, 315, (char *) &arpVCO1aBox}}, {{BVG_VECT, BLUE_WHITE2, 635, 10, 100, 315, (char *) &arpVCO1Box}}, {{BVG_STRING|3, BLUE_WHITE2, 222 + 454, 280, 85, 20, "VCO3"}}, {{BVG_STRING, BLUE_WHITE2, 222 + 440, 45, 200, 8, "INITIAL OSC FREQUENCY"}}, {{BVG_STRING, BLUE_WHITE2, 222 + 440, 63, 200, 8, " -7 +7 "}}, {{BVG_STRING, BLUE_WHITE2, 222 + 440, 74, 200, 8, " .03 0.3 3.0 30 "}}, {{BVG_STRING, BLUE_WHITE2, 222 + 440, 115, 200, 8, " FINE TUNE "}}, {{BVG_STRING, BLUE_WHITE2, 222 + 440, 165, 200, 8, " 10% 50% 90% "}}, {{BVG_STRING, BLUE_WHITE2, 222 + 440, 190, 200, 8, " PULSE WIDTH "}}, {{BVG_STRING, BLUE_WHITE2, 222 + 438, 185, 25, 8, "2'"}}, {{BVG_STRING, BLUE_WHITE2, 222 + 438, 201, 25, 8, "4'"}}, {{BVG_STRING, BLUE_WHITE2, 222 + 438, 218, 25, 8, "8'"}}, {{BVG_STRING, BLUE_WHITE2, 222 + 438, 234, 30, 8, "16'"}}, {{BVG_STRING, BLUE_WHITE2, 222 + 438, 252, 35, 8, "32'"}}, {{BVG_STRING, BLUE_WHITE2, 222 + 547, 230, 100, 6, "TRIANGLE SAW"}}, {{BVG_STRING, BLUE_WHITE2, 222 + 552, 288, 30, 6, "OUT"}}, {{BVG_STRING, BLUE_WHITE2, 222 + 552, 346, 90, 6, "SINE PULSE"}}, {{BVG_STRING, BLUE_WHITE2, 222 + 552, 360, 90, 6, " PWM "}}, {{BVG_STRING, BLUE_WHITE2, 222 + 438, 430, 30, 8, "LFO"}}, {{BVG_STRING, BLUE_WHITE2, 222 + 438, 445, 40, 8, "AUDIO"}}, {{BVG_STRING, BLUE_WHITE2, 222 + 438, 460, 30, 8, "KBD"}}, {{BVG_STRING, BLUE_WHITE2, 222 + 455, 530, 190, 8, "FM CONTROL PWM"}}, {{BVG_STRING, BLUE_WHITE2, 222 + 430, 607, 28, 8, "KBD"}}, // 180 {{BVG_STRING, BLUE_WHITE2, 222 + 434, 621, 18, 8, "CV"}}, {{BVG_STRING, BLUE_WHITE2, 222 + 467, 607, 36, 8, "NOISE"}}, {{BVG_STRING, BLUE_WHITE2, 222 + 471, 621, 28, 8, "GEN"}}, {{BVG_STRING, BLUE_WHITE2, 222 + 506, 612, 36, 8, "ADSR"}}, {{BVG_STRING, BLUE_WHITE2, 222 + 553, 607, 36, 8, "VCO2"}}, {{BVG_VECT|2, BLUE_WHITE2, 222 + 554, 620, 24, 9, (char *) &sineWave}}, {{BVG_STRING, BLUE_WHITE2, 222 + 596, 607, 36, 8, "VCO2"}}, {{BVG_VECT|2, BLUE_WHITE2, 222 + 596, 620, 24, 9, (char *) &triWave}}, {{BVG_VECT, BLUE_WHITE2, 222 + 413, 10, 100, 315, (char *) &arpVCO1aBox}}, {{BVG_VECT, BLUE_WHITE2, 857, 10, 100, 315, (char *) &arpVCFBox}}, {{BVG_STRING, BLUE_WHITE2, 950, 45, 200, 8, "INITIAL FILT FREQUENCY"}}, {{BVG_STRING, BLUE_WHITE2, 950, 74, 200, 8, "10HZ 100HZ 1KHZ 10KHZ"}}, {{BVG_STRING, BLUE_WHITE2, 950, 115, 200, 8, " RESONANCE "}}, {{BVG_STRING|3, BLUE_WHITE2, 1038, 280, 85, 20, "VCF"}}, {{BVG_STRING, BLUE_WHITE2, 1168, 315, 30, 6, "OUT"}}, {{BVG_STRING, BLUE_WHITE2, 946, 530, 250, 8, "AUDIO CONTROL"}}, {{BVG_STRING, BLUE_WHITE2, 869, 607, 36, 8, "RING"}}, // 180 {{BVG_STRING, BLUE_WHITE2, 872, 621, 28, 8, "MOD"}}, {{BVG_STRING, BLUE_WHITE2, 913, 607, 36, 8, "VCO1"}}, {{BVG_VECT|2, BLUE_WHITE2, 913, 620, 24, 9, (char *) &squareWave}}, {{BVG_STRING, BLUE_WHITE2, 951, 607, 36, 8, "VCO2"}}, {{BVG_VECT|2, BLUE_WHITE2, 951, 620, 24, 9, (char *) &squareWave}}, {{BVG_STRING, BLUE_WHITE2, 995, 607, 36, 8, "VCO3"}}, {{BVG_VECT|2, BLUE_WHITE2, 996, 620, 24, 9, (char *) &triWave}}, {{BVG_STRING, BLUE_WHITE2, 1036, 607, 36, 8, "NOISE"}}, {{BVG_STRING, BLUE_WHITE2, 1038, 621, 28, 8, "GEN"}}, {{BVG_STRING, BLUE_WHITE2, 1083, 607, 28, 8, "KBD"}}, {{BVG_STRING, BLUE_WHITE2, 1087, 621, 20, 8, "CV"}}, {{BVG_STRING, BLUE_WHITE2, 1122, 612, 36, 8, "ADSR"}}, {{BVG_STRING, BLUE_WHITE2, 1166, 607, 36, 8, "VCO2"}}, {{BVG_VECT|2, BLUE_WHITE2, 1168, 620, 24, 9, (char *) &sineWave}}, {{BVG_VECT, BLUE_WHITE2, 1205, 10, 100, 315, (char *) &arpADSRBox}}, {{BVG_STRING, BLUE_WHITE2, 1210, 52, 200, 8, " A D S R "}}, {{BVG_STRING, BLUE_WHITE2, 1210, 74, 200, 8, "TIME TIME VOLT TIME"}}, {{BVG_STRING|3, BLUE_WHITE2, 1225, 280, 85, 20, "ADSR"}}, {{BVG_STRING, BLUE_WHITE2, 1348, 315, 30, 6, "OUT"}}, {{BVG_STRING, BLUE_WHITE2, 1210, 342, 200, 8, " A MANUAL R "}}, {{BVG_STRING, BLUE_WHITE2, 1210, 360, 200, 8, "TIME START OUT TIME"}}, {{BVG_STRING|3, BLUE_WHITE2, 1275, 425, 45, 16, "AR"}}, {{BVG_STRING, BLUE_WHITE2, 1283, 498, 70, 8, "KEYBOARD"}}, {{BVG_STRING, BLUE_WHITE2, 1284, 513, 70, 8, "GATE/TRIG"}}, {{BVG_STRING, BLUE_WHITE2, 1295, 583, 90, 8, "GATE TRIG"}}, {{BVG_STRING, BLUE_WHITE2, 1260, 607, 28, 8, "S/H"}}, {{BVG_STRING, BLUE_WHITE2, 1256, 621, 36, 8, "GATE"}}, {{BVG_VECT, BLUE_WHITE2, 1382, 10, 100, 315, (char *) &arpVCABox}}, {{BVG_STRING, BLUE_WHITE2, 1400, 72, 200, 8, "MASTER VOLUME "}}, {{BVG_STRING, BLUE_WHITE2, 1400, 115, 200, 8, "PROGRAM VOLUME "}}, {{BVG_STRING, BLUE_WHITE2, 1400, 160, 200, 8, "INITIAL VOLUME "}}, {{BVG_STRING, BLUE_WHITE2, 1530, 315, 30, 6, "OUT"}}, {{BVG_STRING|3, BLUE_WHITE2, 1430, 280, 70, 20, "VCA"}}, {{BVG_STRING, BLUE_WHITE2, 1410, 530, 50, 8, "AUDIO"}}, {{BVG_STRING, BLUE_WHITE2, 1396, 612, 28, 8, "VCF"}}, {{BVG_STRING, BLUE_WHITE2, 1432, 607, 36, 8, "RING"}}, {{BVG_STRING, BLUE_WHITE2, 1436, 621, 28, 8, "MOD"}}, {{BVG_STRING, BLUE_WHITE2, 1476, 612, 36, 8, " AR "}}, {{BVG_STRING, BLUE_WHITE2, 1520, 612, 36, 8, "ADSR"}}, {{BVG_VECT, BLUE_WHITE2, 1562, 10, 100, 315, (char *) &arpMIXBox}}, {{BVG_STRING, BLUE_WHITE2, 1585, 45, 160, 10, "LEFT RIGHT"}}, {{BVG_STRING, BLUE_WHITE2, 1585, 62, 160, 8, " OUT OUT "}}, {{BVG_STRING, BLUE_WHITE2, 1645, 115, 28, 8, "PAN"}}, {{BVG_STRING, BLUE_WHITE2, 1575, 207, 190, 8, "LEFT RIGHT "}}, {{BVG_STRING|2, BLUE_WHITE2, 1580, 285, 60, 10, "MIXER"}}, {{BVG_STRING|2, BLUE_WHITE2, 1667, 440, 60, 10, "DELAY"}}, {{BVG_STRING, BLUE_WHITE2, 1584, 530, 50, 8, "AUDIO"}}, {{BVG_STRING, BLUE_WHITE2, 1574, 612, 28, 8, "VCF"}}, {{BVG_STRING, BLUE_WHITE2, 1618, 612, 28, 8, "VCA"}}, {{BVG_STRING, BLUE_WHITE2, 1658, 607, 40, 8, "MIXER"}}, {{BVG_STRING, BLUE_WHITE2, 1658, 621, 40, 8, " OUT "}}, {{BVG_VECT, BLUE_WHITE2, 40, 660, 100, 100, (char *) &arpMODBox}}, {{BVG_STRING, BLUE_WHITE2, 155, 669, 160, 10, "NOISE GENERATOR"}}, {{BVG_STRING, BLUE_WHITE2, 175, 717, 88, 8, "WHITE MAX"}}, {{BVG_STRING, BLUE_WHITE2, 145, 795, 42, 8, "PINK"}}, {{BVG_STRING, BLUE_WHITE2, 165, 883, 96, 8, "LO-FREQ MIN"}}, {{BVG_STRING, BLUE_WHITE2, 245, 774, 52, 6, "NOISE"}}, {{BVG_STRING, BLUE_WHITE2, 255, 825, 30, 6, "OUT"}}, {{BVG_STRING, BLUE_WHITE2, 430, 669, 180, 10, "VOLTAGE PROCESSORS"}}, {{BVG_STRING, BLUE_WHITE2, 450, 755, 160, 10, "INVERTING MIXER"}}, {{BVG_STRING, BLUE_WHITE2, 450, 853, 160, 10, "INVERTING MIXER"}}, {{BVG_STRING, BLUE_WHITE2, 460, 907, 140, 10, "LAG PROCESSOR"}}, {{BVG_STRING, BLUE_WHITE2, 640, 888, 28, 10, "LAG"}}, {{BVG_STRING, BLUE_WHITE2, 750, 767, 28, 10, "OUT"}}, {{BVG_STRING, BLUE_WHITE2, 750, 860, 28, 10, "OUT"}}, {{BVG_STRING, BLUE_WHITE2, 867, 669, 120, 10, "SAMPLE+HOLD"}}, {{BVG_STRING, BLUE_WHITE2, 800, 700, 58, 10, "NOISE"}}, {{BVG_STRING, BLUE_WHITE2, 800, 715, 58, 10, " GEN "}}, {{BVG_STRING, BLUE_WHITE2, 880, 718, 90, 10, "LVL RATE"}}, {{BVG_STRING, BLUE_WHITE2, 973, 718, 70, 8, "ELECTRO"}}, {{BVG_STRING, BLUE_WHITE2, 974, 730, 70, 8, "SWITCH"}}, {{BVG_STRING, BLUE_WHITE2, 953, 828, 30, 8, "EXT"}}, {{BVG_STRING, BLUE_WHITE2, 953, 840, 30, 8, "CLK"}}, {{BVG_STRING, BLUE_WHITE2, 810, 758, 58, 8, "CLOCK"}}, {{BVG_STRING, BLUE_WHITE2, 810, 773, 58, 8, " OUT "}}, {{BVG_STRING, BLUE_WHITE2, 923, 902, 50, 8, "SYNC"}}, {{BVG_STRING, BLUE_WHITE2, 850, 888, 58, 8, "CLOCK"}}, {{BVG_STRING, BLUE_WHITE2, 850, 903, 58, 8, " IN "}}, {{BVG_STRING, BLUE_WHITE2, 1020, 755, 10, 8, "A"}}, {{BVG_STRING, BLUE_WHITE2, 1020, 793, 10, 8, "B"}}, {{BVG_STRING, BLUE_WHITE2, 1020, 895, 10, 8, "C"}}, {{BVG_STRING, BLUE_WHITE2, 850, 950, 120, 8, "INTERNAL CLOCK"}}, {{BVG_STRING, BLUE_WHITE2, 1095, 669, 80, 10, "CHORUS"}}, {{BVG_STRING, BLUE_WHITE2, 1252, 669, 70, 10, "DELAY"}}, {{BVG_STRING, BLUE_WHITE2, 1060, 885, 160, 8, "RATE DEPTH SPIN GAIN"}}, {{BVG_STRING, BLUE_WHITE2, 1220, 885, 160, 8, "TIME FEED CROSS GAIN"}}, {{BVG_STRING, BLUE_WHITE2, 1480, 885, 50, 8, "PROG"}}, {{BVG_STRING, BLUE_WHITE2, 1480, 910, 50, 8, "MIDI"}}, } }; bvgImage odysseyMemImage = { 1200, 100, 0x00000000, 4, { {{BVG_STRING, BVG_WHITE, 20, 80, 200, 12, "MARK I/II DOWN UP"}}, {{BVG_STRING, BVG_WHITE, 148, 45, 35, 12, "MIDI"}}, {{BVG_STRING, BVG_WHITE, 225, 80, 440, 12, "LOAD 1 2 3 4 5 6 7 8"}}, {{BVG_STRING, BVG_WHITE, 643, 80, 440, 12, "1 2 3 4 5 6 7 8 SAVE"}}, } }; bvgImage odysseyImage = { 1200, 600, 0x00000000, 68, { {{BVG_STRING, BVG_WHITE, 150, 22, 360, 8, "FREQUENCY FREQUENCY "}}, {{BVG_STRING, BVG_WHITE, 94, 35, 420, 8, "NOISE COARSE FINE KBD COARSE FINE SYNC"}}, {{BVG_STRING, BVG_WHITE, 60, 60, 40, 8, "PINK"}}, {{BVG_STRING, BVG_WHITE, 55, 77, 45, 8, "WHITE"}}, {{BVG_STRING, BVG_WHITE, 94, 103, 420, 8, " LFO OFF "}}, {{BVG_STRING, BVG_WHITE, 420, 196, 40, 8, "DUAL"}}, {{BVG_STRING, BVG_WHITE, 96, 230, 420, 8, " VOLTAGE VOLTAGE "}}, {{BVG_STRING, BVG_WHITE, 96, 242, 420, 8, " CONTROLLED CONTROLLED "}}, {{BVG_STRING, BVG_WHITE, 96, 254, 420, 8, " OSCILLATOR OSCILLATOR "}}, {{BVG_STRING, BVG_WHITE, 96, 266, 420, 8, " 1 2 "}}, {{BVG_STRING, BVG_WHITE, 240, 307, 360, 8, "PW PWM PW PWM "}}, {{BVG_VECT|2, OFF_WHITE, 280, 230, 24, 10, (char *) &sawWave}}, {{BVG_VECT|2, OFF_WHITE, 280, 270, 24, 10, (char *) &squareWave}}, {{BVG_VECT|2, OFF_WHITE, 460, 230, 24, 10, (char *) &sawWave}}, {{BVG_VECT|2, OFF_WHITE, 460, 270, 24, 10, (char *) &squareWave}}, {{BVG_VECT|2, OFF_WHITE, 617, 100, 16, 10, (char *) &sineWave}}, {{BVG_VECT|2, OFF_WHITE, 617, 140, 16, 10, (char *) &squareWave}}, {{BVG_STRING, BVG_WHITE, 63, 307, 90, 8, "TRANSPOSE"}}, {{BVG_STRING, BVG_WHITE, 100, 345, 20, 8, "+1"}}, {{BVG_STRING, BVG_WHITE, 100, 445, 20, 8, "-1"}}, {{BVG_STRING, BVG_WHITE, 25, 463, 50, 8, "GLIDE"}}, {{BVG_STRING, BVG_WHITE, 25, 560, 130, 8, "PITCH CONTROL"}}, {{BVG_STRING, BVG_WHITE, 507, 19, 800, 8, " LFO VCF VCF HPF VCA ENV "}}, {{BVG_STRING, BVG_WHITE, 507, 35, 800, 8, " FREQ FREQ RES FREQ GAIN A R "}}, {{BVG_STRING, BVG_WHITE, 510, 290, 800, 8, " ENV "}}, {{BVG_STRING, BVG_WHITE, 510, 109, 800, 8, " LOW "}}, {{BVG_STRING, BVG_WHITE, 512, 123, 800, 8, " FREQUENCY "}}, {{BVG_STRING, BVG_WHITE, 510, 137, 800, 8, " OSCILLATOR "}}, {{BVG_STRING, BVG_WHITE, 510, 236, 800, 8, " VOLTAGE HIGH VOLTAGE "}}, {{BVG_STRING, BVG_WHITE, 510, 250, 800, 8, " SH SH AUDIO CONTROLLED PASS CONTROLLED "}}, {{BVG_STRING, BVG_WHITE, 510, 264, 800, 8, " MIXER MIXER FILTER FILTER AMPLIFIER "}}, {{BVG_STRING, BVG_WHITE, 510, 307, 800, 8, " OUTPUT A D S R "}}, {{BVG_STRING, BVG_WHITE, 155, 465, 420, 8, " FM FM "}}, {{BVG_STRING, BVG_WHITE, 153, 481, 420, 8, " LFO SH LFO LFO SH LFO "}}, {{BVG_VECT|2, OFF_WHITE, 158, 495, 20, 10, (char *) &sineWave}}, {{BVG_VECT|2, OFF_WHITE, 280, 495, 20, 10, (char *) &sineWave}}, {{BVG_VECT|2, OFF_WHITE, 342, 495, 20, 10, (char *) &sineWave}}, {{BVG_VECT|2, OFF_WHITE, 462, 495, 20, 10, (char *) &sineWave}}, {{BVG_VECT|2, OFF_WHITE, 522, 495, 20, 10, (char *) &sawWave}}, {{BVG_VECT|2, OFF_WHITE, 726, 495, 20, 10, (char *) &sawWave}}, {{BVG_VECT|2, OFF_WHITE, 766, 495, 20, 10, (char *) &sawWave}}, {{BVG_STRING, BVG_WHITE, 155, 560, 420, 8, " LFO ADSR ADSR SH ADSR ADSR "}}, {{BVG_VECT|2, OFF_WHITE, 158, 574, 20, 10, (char *) &squareWave}}, {{BVG_VECT|2, OFF_WHITE, 198, 574, 20, 10, (char *) &env}}, {{BVG_VECT|2, OFF_WHITE, 282, 574, 20, 10, (char *) &env}}, {{BVG_VECT|2, OFF_WHITE, 376, 574, 20, 10, (char *) &env}}, {{BVG_VECT|2, OFF_WHITE, 465, 574, 20, 10, (char *) &env}}, {{BVG_VECT|2, OFF_WHITE, 524, 574, 20, 10, (char *) &squareWave}}, {{BVG_VECT|2, OFF_WHITE, 562, 574, 20, 10, (char *) &squareWave}}, {{BVG_VECT|2, OFF_WHITE, 727, 574, 20, 10, (char *) &squareWave}}, {{BVG_VECT|2, OFF_WHITE, 768, 574, 20, 10, (char *) &squareWave}}, {{BVG_VECT|2, OFF_WHITE, 850, 574, 20, 10, (char *) &sineWave}}, {{BVG_VECT|2, OFF_WHITE, 889, 495, 20, 10, (char *) &env}}, {{BVG_VECT|2, OFF_WHITE, 985, 495, 20, 10, (char *) &env}}, {{BVG_VECT|2, OFF_WHITE, 889, 574, 20, 10, (char *) &env}}, {{BVG_VECT|2, OFF_WHITE, 985, 574, 20, 10, (char *) &env}}, {{BVG_VECT|2, OFF_WHITE, 1028, 574, 20, 10, (char *) &squareWave}}, {{BVG_VECT|2, OFF_WHITE, 1150, 574, 20, 10, (char *) &squareWave}}, {{BVG_STRING, BVG_WHITE, 155, 574, 420, 8, " MIX "}}, {{BVG_STRING, BVG_WHITE, 510, 481, 800, 8, " VCO1 NOISE TRIG NOISE VCO1 VCO2 KBD SH ADSR AR ADSR AR "}}, {{BVG_STRING, BVG_WHITE, 510, 495, 800, 8, " KBD KBD KBD KBD "}}, {{BVG_STRING, BVG_WHITE, 507, 560, 800, 8, " RING VCO1 VCO2 SH LFO AR ADSR REPEAT AUTO REPEAT "}}, {{BVG_STRING, BVG_WHITE, 507, 574, 800, 8, " MOD MIX "}}, {{BVG_VECT|2, OFF_WHITE, 1060, 16, 20, 10, (char *) &env}}, {{BVG_VECT|2, OFF_WHITE, 1100, 285, 20, 10, (char *) &env}}, {{BVG_VECT, OFF_WHITE, 40, 495, 12, 10, (char *) &flat}}, {{BVG_VECT, OFF_WHITE, 73, 495, 16, 10, (char *) &sineWave}}, {{BVG_VECT, OFF_WHITE, 106, 495, 10, 10, (char *) &sharp}}, } }; bvgImage subMiniImage = { 680, 400, 0x00000000, 2, { {{BVG_VECT, OFF_WHITE, 0, 0, 34, 53, (char *) &pot}}, {{BVG_STRING, OFF_WHITE, 4, 55, 35, 8, "O 1O"}}, } }; bvgImage subMiniImage2 = { 680, 400, 0x00000000, 3, { {{BVG_VECT, BVG_WHITE, 0, 0, 46, 70, (char *) &pot}}, {{BVG_STRING, OFF_WHITE, 0, 4, 57, 8, "-3 3"}}, {{BVG_STRING, OFF_WHITE, 0, 75, 55, 8, "-7 7"}}, } }; bvgImage subMiniImage3 = { 680, 400, 0x00000000, 3, { {{BVG_STRING, OFF_WHITE, 8, 0, 38, 8, "8 4"}}, {{BVG_STRING, OFF_WHITE, 0, 25, 55, 8, "16 2"}}, {{BVG_STRING, OFF_WHITE, 7, 50, 45, 8, "32 1"}}, } }; bvgImage subMiniImage4 = { 680, 400, 0x00000000, 6, { {{BVG_VECT, OFF_WHITE, 5, 48, 7, 8, (char *) &sineWave}}, {{BVG_VECT, OFF_WHITE, 0, 23, 7, 8, (char *) &squareWave}}, {{BVG_VECT, OFF_WHITE, 5, 0, 7, 8, (char *) &pWave}}, {{BVG_VECT, OFF_WHITE, 30, 0, 7, 8, (char *) &rampWave}}, {{BVG_VECT, OFF_WHITE, 37, 23, 7, 8, (char *) &triWave}}, {{BVG_VECT, BVG_WHITE, 34, 48, 7, 8, (char *) &biRampWave}}, } }; bvgImage pro1Pot = { 1000, 600, 0x00000000, 6, { {{BVG_STRING, BVG_WHITE, 45, 17, 8, 9, "5"}}, {{BVG_STRING, BVG_WHITE, 29, 21, 60, 9, " 4 6 "}}, {{BVG_STRING, BVG_WHITE, 20, 36, 80, 9, " 3 7 "}}, {{BVG_STRING, BVG_WHITE, 15, 56, 90, 9, " 2 8 "}}, {{BVG_STRING, BVG_WHITE, 21, 78, 80, 9, " 1 9 "}}, {{BVG_STRING, BVG_WHITE, 32, 93, 50, 9, " O 1O"}}, } }; bvgImage pro1ModPot = { 1000, 600, 0x00000000, 10, { {{BVG_STRING, BVG_WHITE, 45, 17, 8, 9, "5"}}, {{BVG_STRING, BVG_WHITE, 29, 21, 60, 9, " 4 6 "}}, {{BVG_STRING, BVG_WHITE, 20, 36, 80, 9, " 3 7 "}}, {{BVG_STRING, BVG_WHITE, 15, 56, 90, 9, " 2 8 "}}, {{BVG_STRING, BVG_WHITE, 21, 78, 80, 9, " 1 9 "}}, {{BVG_STRING, BVG_WHITE, 32, 93, 50, 9, " O 1O"}}, {{BVG_STRING, BVG_WHITE, 30, 117, 55, 10, "AMOUNT"}}, {{BVG_STRING, BVG_WHITE, 84, 16, 45, 9, "WHEEL"}}, {{BVG_STRING, BVG_WHITE, 85, 100, 45, 9, "DIRECT"}}, {{BVG_STRING, BVG_WHITE, 85, 117, 45, 9, "ROUTE"}}, } }; bvgImage pro1ModSwitch = { 1000, 600, 0x00000000, 3, { {{BVG_STRING, BVG_WHITE, 0, 0, 40, 9, "WHEEL"}}, {{BVG_STRING, BVG_WHITE, 0, 25, 40, 9," OFF "}}, {{BVG_STRING, BVG_WHITE, 0, 50, 40, 9,"ROUTE"}}, } }; bvgImage bmeEnvSel = { 1000, 400, 0x00000000, 2, { {{BVG_VECT|2, OFF_WHITE, 1, 0, 30, 12, (char *) &triWave}}, {{BVG_VECT|2, OFF_WHITE, 1, 74, 30, 12, (char *) &squareWave}}, } }; bvgCoords obxLogoCoords[31] = { {0, 0}, {40, 0}, {50, 5}, {64, 14}, {64, 28}, {54, 39}, {66, 48}, {74, 70}, {74, 82}, {70, 90}, {60, 100}, {0, 100}, {14, 96}, {14, 4}, {0, 0}, {-1, -1}, {28, 12}, {36, 12}, {46, 20}, {46, 29}, {35, 37}, {28, 37}, {28, 12}, {-1, -1}, {28, 52}, {41, 52}, {51, 70}, {51, 79}, {40, 92}, {28, 92}, {28, 52}, }; bvgVect obxLogo = { 31, obxLogoCoords }; bvgCoords obxXCoords[21] = { {0, 0}, {40, 0}, {38, 10}, {53, 34}, {70, 15}, {75, 0}, {85, 0}, {80, 15}, {57, 40}, {90, 96}, {100, 100}, {60, 100}, {62, 90}, {43, 56}, {15, 85}, {10, 100}, {00, 100}, {5, 85}, {40, 49}, {15, 10}, {0, 0}, }; bvgVect obxX = { 21, obxXCoords }; bvgCoords obxHiphenCoords[7] = { {30, 40}, {70, 40}, {60, 45}, {50, 60}, {0, 60}, {20, 55}, {30, 40}, }; bvgVect obxHiphen = { 7, obxHiphenCoords }; bvgImage obxLogoImage = { 900, 150, 0x00000000, 4, { {{BVG_VECT, OFF_WHITE, 200, 5, 45, 120, (char *) &obxLogo}}, {{BVG_VECT, OFF_WHITE, 230, 5, 45, 120, (char *) &obxLogo}}, {{BVG_VECT, OFF_WHITE, 265, 5, 35, 120, (char *) &obxHiphen}}, {{BVG_VECT, OFF_WHITE, 278, 5, 45, 120, (char *) &obxX}}, } }; bvgImage obxModImage = { 200, 200, 0x00000000, 1, { {{BVG_STRING, BVG_WHITE, 15, 140, 190, 10, "NARROW OSC2 TRANS"}}, } }; #define obxText(x, y, w, h, W, text) \ {{BVG_SQUARE, BVG_BLACK, x - 1, y - 1, x + W + 1, y + h + 1}}, \ {{BVG_STRING, BVG_WHITE, x, y, w, h, text}} bvgImage obxImage = { 750, 200, 0x00000000, 81, { {{BVG_STRING, BVG_WHITE, 54, 10, 40, 5, "MANUAL"}}, obxText(54, 30, 40, 5, 28, "VOLUME"), obxText(39, 75, 80, 5, 58, "AUTO HOLD RESET"), obxText(50, 110, 50, 5, 38, "MASTERTUNE"), {{BVG_STRING, BVG_WHITE, 127, 10, 45, 5, "CONTROL"}}, obxText(130, 30, 30, 5, 23, "GLIDE"), obxText(127, 75, 40, 5, 28, "UNISON"), obxText(122, 110, 60, 5, 42, "OSC2 DETUNE"), {{BVG_STRING, BVG_WHITE, 210, 10, 65, 5, "MODULATION"}}, obxText(184, 30, 23, 5, 17, "LFO"), obxText(183, 75, 25, 5, 19, "SINE"), obxText(178, 110, 45, 5, 35, "SQUARE"), obxText(184, 144, 23, 5, 17, "S/H"), obxText(223, 30, 38, 5, 29, "DEPTH"), obxText(229, 75, 25, 5, 17, "OSC1"), obxText(229, 110, 25, 5, 19, "OSC2"), obxText(229, 144, 23, 5, 15, "FILT"), obxText(269, 30, 23, 5, 17, "PWM"), obxText(268, 75, 25, 5, 17, "OSC1"), obxText(268, 110, 25, 5, 19, "OSC2"), {{BVG_STRING, BVG_WHITE, 350, 10, 75, 5, "OSCILLATORS"}}, obxText(308, 30, 35, 5, 26, "FREQ1"), obxText(303, 75, 45, 5, 35, "SAW PULSE"), obxText(342, 30, 60, 5, 48, "PULSEWIDTH"), obxText(345, 75, 55, 5, 42, "XMOD SYNC"), obxText(398, 30, 35, 5, 29, "FREQ2"), obxText(393, 75, 45, 5, 35, "SAW PULSE"), {{BVG_STRING, BVG_WHITE, 477, 10, 50, 5, "FILTER"}}, obxText(443, 30, 30, 5, 23, "FREQ"), obxText(434, 75, 55, 5, 39, "OSC1 KBD"), obxText(475, 30, 55, 5, 43, "RESONANCE"), obxText(480, 75, 45, 5, 35, "HALF FULL"), obxText(535, 30, 25, 5, 20, "MOD"), obxText(527, 75, 45, 5, 35, "HALF FULL"), {{BVG_STRING, BVG_WHITE, 612, 10, 100, 5, "FILTER ENVELOPE"}}, obxText(580, 30, 180, 5, 139, "ATTACK DECAY SUSTAIN RELEASE"), obxText(580, 75, 180, 5, 139, "ATTACK DECAY SUSTAIN RELEASE"), {{BVG_STRING, BVG_WHITE, 608, 115, 110, 5, "AMPLIFIER ENVELOPE"}}, {{BVG_STRING, BVG_WHITE, 450, 135, 65, 5, "PROGRAMMER"}}, obxText(310, 144, 25, 5, 18, "LOAD"), obxText(338, 144, 170, 5, 130, "1 2 3 4 5 6 7 8"), obxText(485, 144, 170, 5, 130, "1 2 3 4 5 6 7 8"), obxText(628, 144, 25, 5, 18, "SAVE"), {{BVG_STRING, BVG_WHITE, 692, 135, 25, 5, "MIDI"}}, obxText(686, 144, 45, 5, 34, "DOWN UP"), } }; bvgImage BME700ModImage = { 100, 100, 0x00000000, 4, { {{BVG_STRING|2, BVG_WHITE, 28, 8, 55, 6, "MEMORY"}}, {{BVG_STRING, BVG_WHITE, 15, 33, 110, 3, " 1 2 3 4 "}}, {{BVG_STRING, BVG_WHITE, 15, 58, 110, 3, " 5 6 7 8 "}}, {{BVG_STRING, BVG_WHITE, 18, 83, 110, 3, "LOAD SAVE UP MOD "}}, } }; bvgImage BME700Image = { 1000, 400, 0x00000000, 51, { {{BVG_STRING|2, BVG_WHITE, 59, 5, 60, 15, "MOD1"}}, {{BVG_STRING|2, BVG_WHITE, 193, 5, 60, 15, "MOD2"}}, {{BVG_IMAGE, BVG_WHITE, 48, 36, 48, 70, (char *) &bmeEnvSel}}, {{BVG_IMAGE, BVG_WHITE, 243, 36, 48, 70, (char *) &bmeEnvSel}}, {{BVG_STRING, BVG_WHITE, 102, 25, 120, 8, "CYCLE CYCLE"}}, {{BVG_STRING, BVG_WHITE, 91, 90, 140, 8, "1Oms 1Os 1Oms 1Os"}}, {{BVG_STRING, BVG_WHITE, 263, 63, 25, 8, "PWM"}}, {{BVG_STRING, BVG_WHITE, 122, 112, 70, 8, "VIBRA MIX"}}, {{BVG_STRING, BVG_WHITE, 220, 122, 40, 8, "SINGLE"}}, {{BVG_IMAGE, BVG_WHITE, 256, 122, 48, 70, (char *) &bmeEnvSel}}, {{BVG_STRING, BVG_WHITE, 78, 176, 210, 8, "ENV1 MOD2 MOD2 DOUBLE"}}, {{BVG_STRING|2, BVG_WHITE, 391, 5, 70, 15, "MIXER"}}, {{BVG_STRING, BVG_WHITE, 395, 28, 70, 8, "S/N RATIO"}}, {{BVG_STRING, BVG_WHITE, 356, 87, 180, 8, "WHITE NOISE VCO OUTPUT"}}, {{BVG_STRING|2, BVG_WHITE, 630, 5, 60, 15, "ENV1"}}, {{BVG_STRING, BVG_WHITE, 578, 25, 200, 7, "MODE RISE FALL "}}, {{BVG_STRING, BVG_WHITE, 630, 90, 140, 7, "2ms 2Os 2Oms 2s"}}, {{BVG_STRING, BVG_WHITE, 630, 112, 70, 8, "ENV MIX VCF"}}, {{BVG_STRING, BVG_WHITE, 630, 177, 70, 8, "ENV1/ENV2"}}, {{BVG_STRING|2, BVG_WHITE, 865, 5, 60, 15, "ENV2"}}, {{BVG_STRING, BVG_WHITE, 820, 25, 200, 7, "MODE RISE FALL "}}, {{BVG_STRING, BVG_WHITE, 872, 90, 140, 7, "2ms 2Os 2Oms 2s"}}, {{BVG_STRING, BVG_WHITE, 865, 112, 70, 8, "ENV MIX VCF"}}, {{BVG_STRING, BVG_WHITE, 866, 177, 70, 8, "ENV1/ENV2"}}, {{BVG_STRING|2, BVG_WHITE, 131, 189, 50, 15, "VCO"}}, {{BVG_STRING, BVG_WHITE, 40, 208, 280, 8, "SPEED RATIO VIBRA - + "}}, {{BVG_STRING, BVG_WHITE, 40, 297, 280, 8, "GLIDE PULSE SHAPE TUNE "}}, {{BVG_STRING, BVG_WHITE, 40, 310, 280, 7, " ON MAN ENV 8 16"}}, {{BVG_STRING, BVG_WHITE, 40, 362, 280, 7, " OFF AUTO MOD 4"}}, {{BVG_VECT|2, OFF_WHITE, 160, 360, 10, 8, (char *) &squareWave}}, {{BVG_VECT|2, OFF_WHITE, 200, 360, 10, 8, (char *) &triWave}}, {{BVG_STRING|2, BVG_WHITE, 388, 189, 80, 15, "RES FILT"}}, {{BVG_STRING, BVG_WHITE, 410, 208, 30, 8, "MODE"}}, {{BVG_STRING, BVG_WHITE, 408, 221, 36, 8, "SHARP"}}, {{BVG_STRING, BVG_WHITE, 410, 276, 30, 8, "FLAT"}}, {{BVG_STRING, BVG_WHITE, 395, 295, 70, 8, "FREQUENCY"}}, {{BVG_STRING, BVG_WHITE, 360, 310, 160, 7, "1 2 4 8 16 "}}, {{BVG_STRING, BVG_WHITE, 360, 362, 160, 7, "O O O O O "}}, {{BVG_STRING|2, BVG_WHITE, 631, 189, 50, 15, "VCF"}}, {{BVG_STRING, BVG_WHITE, 563, 208, 200, 7, "RESONANCE BASIS ENV"}}, {{BVG_STRING, BVG_WHITE, 561, 272, 220, 7, " O 6 O 6 MOD ENV "}}, {{BVG_STRING, BVG_WHITE, 561, 296, 220, 7, " MOD MIX "}}, {{BVG_IMAGE, BVG_WHITE, 582, 310, 48, 70, (char *) &bmeEnvSel}}, {{BVG_STRING, BVG_WHITE, 561, 310, 220, 7, " MOD1 KBD "}}, {{BVG_STRING, BVG_WHITE, 561, 362, 220, 7, " MOD2 MOD MOD ENV "}}, {{BVG_STRING|2, BVG_WHITE, 868, 189, 50, 15, "VCA"}}, {{BVG_STRING, BVG_WHITE, 805, 208, 220, 7, "FILTER-MIX OUTPUT MOD-MIX"}}, {{BVG_STRING, BVG_WHITE, 803, 272, 220, 7, "VCF RES O 6 MOD ENV "}}, {{BVG_STRING, BVG_WHITE, 803, 310, 220, 7, " MOD1 "}}, {{BVG_STRING, BVG_WHITE, 803, 362, 220, 7, " MOD2 "}}, {{BVG_IMAGE, BVG_WHITE, 923, 310, 48, 70, (char *) &bmeEnvSel}}, {{BVG_STRING|2, BVG_RED, 290, 110, 60, 15, "MOD2"}}, {{BVG_STRING|2, BVG_GREEN, 290, 110, 60, 15, "MOD2"}}, {{BVG_STRING|2, BVG_GREEN, 290, 110, 60, 15, "MOD2"}}, {{BVG_STRING|2, BVG_GREEN, 290, 110, 60, 15, "MOD2"}}, {{BVG_STRING|2, BVG_GREEN, 290, 110, 60, 15, "MOD2"}}, {{BVG_STRING|2, BVG_GREEN, 290, 110, 60, 15, "MOD2"}}, {{BVG_STRING|2, BVG_GREEN, 290, 110, 60, 15, "MOD2"}}, {{BVG_STRING|2, BVG_GREEN, 290, 110, 60, 15, "MOD2"}}, {{BVG_STRING|2, BVG_GREEN, 290, 110, 60, 15, "MOD2"}}, {{BVG_STRING|2, BVG_GREEN, 290, 110, 60, 15, "MOD2"}}, } }; bvgImage Prophet1Image = { 1000, 600, 0x00000000, 100, { {{BVG_STRING, BVG_WHITE, 61, 34, 70, 10, "MODULATION"}}, {{BVG_STRING, BVG_WHITE, 54, 53, 30, 8, "FROM"}}, {{BVG_STRING, BVG_WHITE, 134, 53, 15, 8, "TO"}}, {{BVG_IMAGE, BVG_BLACK, 10, 70, 85, 84, (char *) &pro1ModPot}}, {{BVG_IMAGE, BVG_BLACK, 10, 218, 85, 84, (char *) &pro1ModPot}}, {{BVG_IMAGE, BVG_BLACK, 10, 366, 85, 84, (char *) &pro1ModPot}}, {{BVG_IMAGE, BVG_BLACK, 118, 71, 85, 84, (char *) &pro1ModSwitch}}, {{BVG_IMAGE, BVG_BLACK, 118, 159, 85, 84, (char *) &pro1ModSwitch}}, {{BVG_IMAGE, BVG_BLACK, 118, 242, 85, 84, (char *) &pro1ModSwitch}}, {{BVG_IMAGE, BVG_BLACK, 118, 330, 85, 84, (char *) &pro1ModSwitch}}, {{BVG_IMAGE, BVG_BLACK, 118, 413, 85, 84, (char *) &pro1ModSwitch}}, {{BVG_STRING, BVG_WHITE, 35, 180, 60, 10, "FILTER ENV"}}, {{BVG_STRING, BVG_WHITE, 35, 330, 35, 10, "OSC-B"}}, {{BVG_STRING, BVG_WHITE, 35, 478, 25, 10, "LFO"}}, {{BVG_STRING, BVG_WHITE, 118, 130, 50, 9, "OSC-A FREQ"}}, {{BVG_STRING, BVG_WHITE, 118, 214, 50, 9, "OSC-A PW"}}, {{BVG_STRING, BVG_WHITE, 118, 300, 50, 9, "OSC-B FREQ"}}, {{BVG_STRING, BVG_WHITE, 118, 386, 50, 9, "OSC-B PW"}}, {{BVG_STRING, BVG_WHITE, 125, 470, 35, 9, "FILTER"}}, {{BVG_STRING, BVG_WHITE, 287, 53, 76, 10, "OSCILLATOR A"}}, {{BVG_STRING, BVG_WHITE, 245, 75, 76, 8, " 1 2 "}}, {{BVG_STRING, BVG_WHITE, 245, 89, 76, 8, "O 3"}}, {{BVG_VECT|2, OFF_WHITE, 310, 80, 12, 12, (char *) &sawWave}}, {{BVG_VECT|2, OFF_WHITE, 340, 80, 12, 12, (char *) &squareWave}}, {{BVG_STRING, BVG_WHITE, 185, 170, 60, 9, "FREQUENCY"}}, {{BVG_STRING, BVG_WHITE, 368, 170, 66, 9, "PULSE WIDTH"}}, {{BVG_STRING, BVG_WHITE, 258, 150, 40, 8, "OCTAVE"}}, {{BVG_STRING, BVG_WHITE, 321, 150, 27, 8, "SHAPE"}}, {{BVG_STRING, BVG_WHITE, 430, 88, 25, 8, "SYNC"}}, {{BVG_STRING, BVG_WHITE, 433, 150, 20, 8, "OFF"}}, {{BVG_STRING, BVG_WHITE, 550, 53, 30, 10, "MIXER"}}, {{BVG_STRING, BVG_WHITE, 480, 170, 210, 9, "OSC A OSC B NOISE "}}, {{BVG_STRING, BVG_WHITE, 317, 200, 76, 10, "OSCILLATOR B"}}, {{BVG_STRING, BVG_WHITE, 245, 222, 76, 8, " 1 2 "}}, {{BVG_STRING, BVG_WHITE, 245, 237, 76, 8, "O 3"}}, {{BVG_VECT|2, OFF_WHITE, 310, 227, 12, 12, (char *) &sawWave}}, {{BVG_VECT|2, OFF_WHITE, 340, 227, 12, 12, (char *) &triWave}}, {{BVG_VECT|2, OFF_WHITE, 370, 227, 12, 12, (char *) &squareWave}}, {{BVG_STRING, BVG_WHITE, 185, 317, 60, 9, "FREQUENCY"}}, {{BVG_STRING, BVG_WHITE, 400, 317, 66, 9, "PULSE WIDTH"}}, {{BVG_STRING, BVG_WHITE, 258, 297, 40, 8, "OCTAVE"}}, {{BVG_STRING, BVG_WHITE, 337, 297, 27, 8, "SHAPE"}}, {{BVG_STRING, BVG_WHITE, 460, 234, 60, 8, "LOFREQ KEY"}}, {{BVG_STRING, BVG_WHITE, 460, 297, 60, 8, "NORMAL OFF"}}, {{BVG_STRING, BVG_WHITE, 579, 200, 35, 10, "GLIDE"}}, {{BVG_STRING, BVG_WHITE, 610, 234, 40, 8, " KEY "}}, {{BVG_STRING, BVG_WHITE, 605, 297, 44, 8, "NORMAL"}}, {{BVG_STRING, BVG_WHITE, 565, 317, 30, 9, "RATE"}}, {{BVG_STRING, BVG_WHITE, 780, 53, 36, 10, "FILTER"}}, {{BVG_STRING, BVG_WHITE, 680, 170, 300, 9, "CUTOFF RESONANCE ENVELOPE KEYBOARD "}}, {{BVG_STRING, BVG_WHITE, 680, 183, 300, 9, " AMOUNT AMOUNT "}}, {{BVG_STRING, BVG_WHITE, 680, 318, 350, 9, "ATTACK DECAY SUSTAIN RELEASE TUNE "}}, {{BVG_STRING, BVG_WHITE, 245, 350, 18, 10, "LFO"}}, {{BVG_VECT|2, OFF_WHITE, 247, 374, 12, 12, (char *) &sawWave}}, {{BVG_VECT|2, OFF_WHITE, 276, 374, 12, 12, (char *) &triWave}}, {{BVG_VECT|2, OFF_WHITE, 307, 374, 12, 12, (char *) &squareWave}}, {{BVG_STRING, BVG_WHITE, 185, 467, 60, 9, "FREQUENCY"}}, {{BVG_STRING, BVG_WHITE, 274, 444, 27, 8, "SHAPE"}}, {{BVG_STRING, BVG_WHITE, 371, 350, 64, 10, "SEQUENCER"}}, {{BVG_STRING, BVG_WHITE, 370, 375, 80, 8, "ON RECORD"}}, {{BVG_STRING, BVG_WHITE, 370, 450, 80, 8, "OFF PLAY "}}, {{BVG_STRING, BVG_WHITE, 451, 350, 60, 10, "ARPEGGIATE"}}, {{BVG_STRING, BVG_WHITE, 460, 375, 50, 8, " UP "}}, {{BVG_STRING, BVG_WHITE, 490, 415, 50, 8, "OFF "}}, {{BVG_STRING, BVG_WHITE, 460, 460, 50, 8, "UP/DOWN"}}, {{BVG_STRING, BVG_WHITE, 577, 350, 30, 10, "MODE"}}, {{BVG_STRING, BVG_WHITE, 536, 375, 140, 8, "RETRIG REPEAT DRONE"}}, {{BVG_STRING, BVG_WHITE, 536, 450, 140, 8, "NORMAL NORMAL OFF "}}, {{BVG_STRING, BVG_WHITE, 774, 350, 56, 10, "AMPLIFIER"}}, {{BVG_STRING, BVG_WHITE, 680, 467, 350, 9, "ATTACK DECAY SUSTAIN RELEASE VOLUME"}}, {{BVG_STRING, BVG_WHITE, 28, 530, 100, 9, "DOWN UP"}}, {{BVG_STRING, BVG_WHITE, 59, 550, 30, 9, "MIDI"}}, {{BVG_STRING, BVG_WHITE, 50, 565, 50, 9, "CHANNEL"}}, {{BVG_STRING, BVG_WHITE, 183, 530, 100, 9, "LOAD SAVE BANK"}}, {{BVG_STRING, BVG_WHITE, 335, 530, 100, 9, " PROGRAMMER "}}, {{BVG_STRING, BVG_WHITE, 494, 530, 180, 9, "1 2 3 4 5 6 7 8"}}, {{BVG_STRING, BVG_WHITE, 655, 530, 100, 9, "DOWN UP FIND"}}, {{BVG_IMAGE, BVG_BLACK, 166, 70, 85, 84, (char *) &pro1Pot}}, {{BVG_IMAGE, BVG_BLACK, 355, 70, 85, 84, (char *) &pro1Pot}}, {{BVG_IMAGE, BVG_BLACK, 456, 70, 85, 84, (char *) &pro1Pot}}, {{BVG_IMAGE, BVG_BLACK, 520, 70, 85, 84, (char *) &pro1Pot}}, {{BVG_IMAGE, BVG_BLACK, 582, 70, 85, 84, (char *) &pro1Pot}}, {{BVG_IMAGE, BVG_BLACK, 535, 218, 85, 84, (char *) &pro1Pot}}, {{BVG_IMAGE, BVG_BLACK, 166, 218, 85, 84, (char *) &pro1Pot}}, {{BVG_IMAGE, BVG_BLACK, 384, 218, 85, 84, (char *) &pro1Pot}}, {{BVG_IMAGE, BVG_BLACK, 166, 368, 85, 84, (char *) &pro1Pot}}, {{BVG_IMAGE, BVG_BLACK, 657, 70, 85, 84, (char *) &pro1Pot}}, {{BVG_IMAGE, BVG_BLACK, 720, 70, 85, 84, (char *) &pro1Pot}}, {{BVG_IMAGE, BVG_BLACK, 782, 70, 85, 84, (char *) &pro1Pot}}, {{BVG_IMAGE, BVG_BLACK, 845, 70, 85, 84, (char *) &pro1Pot}}, {{BVG_IMAGE, BVG_BLACK, 657, 218, 85, 84, (char *) &pro1Pot}}, {{BVG_IMAGE, BVG_BLACK, 720, 218, 85, 84, (char *) &pro1Pot}}, {{BVG_IMAGE, BVG_BLACK, 782, 218, 85, 84, (char *) &pro1Pot}}, {{BVG_IMAGE, BVG_BLACK, 845, 218, 85, 84, (char *) &pro1Pot}}, {{BVG_IMAGE, BVG_BLACK, 657, 368, 85, 84, (char *) &pro1Pot}}, {{BVG_IMAGE, BVG_BLACK, 720, 368, 85, 84, (char *) &pro1Pot}}, {{BVG_IMAGE, BVG_BLACK, 782, 368, 85, 84, (char *) &pro1Pot}}, {{BVG_IMAGE, BVG_BLACK, 845, 368, 85, 84, (char *) &pro1Pot}}, {{BVG_IMAGE, BVG_BLACK, 917, 218, 85, 84, (char *) &pro1Pot}}, {{BVG_IMAGE, BVG_BLACK, 917, 368, 85, 84, (char *) &pro1Pot}}, {{BVG_VECT, BVG_GREEN, 500, 300, 20, 10, (char *) &biRampWave}}, {{BVG_VECT, BVG_GREEN, 500, 300, 20, 10, (char *) &biRampWave}}, {{BVG_VECT, BVG_GREEN, 500, 300, 20, 10, (char *) &biRampWave}}, {{BVG_VECT, BVG_GREEN, 500, 300, 20, 10, (char *) &biRampWave}}, {{BVG_VECT, BVG_GREEN, 500, 300, 20, 10, (char *) &biRampWave}}, {{BVG_VECT, BVG_GREEN, 500, 300, 20, 10, (char *) &biRampWave}}, {{BVG_VECT, BVG_GREEN, 500, 300, 20, 10, (char *) &biRampWave}}, {{BVG_VECT, BVG_GREEN, 500, 300, 20, 10, (char *) &biRampWave}}, {{BVG_VECT, BVG_GREEN, 500, 300, 20, 10, (char *) &biRampWave}}, {{BVG_VECT, BVG_GREEN, 500, 300, 20, 10, (char *) &biRampWave}}, } }; bvgImage Prophet52Image = { 1024, 400, 0x00000000, 39, { {{BVG_STRING, OFF_WHITE, 70, 34, 85, 10, "POLY MOD"}}, {{BVG_STRING, OFF_WHITE, 115, 50, 100, 10, "FREQA PWA FILT"}}, {{BVG_STRING, OFF_WHITE, 9, 109, 120, 10, "FILT OSCB"}}, {{BVG_STRING, OFF_WHITE, 39, 119, 50, 10, "AMOUNT"}}, {{BVG_STRING, OFF_WHITE, 145, 114, 35, 10, "DEST"}}, {{BVG_STRING, OFF_WHITE, 266, 34, 110, 10, "OSCILLATOR A"}}, {{BVG_VECT, OFF_WHITE, 263, 50, 10, 10, (char *) &rampWave}}, {{BVG_VECT, OFF_WHITE, 294, 50, 10, 10, (char *) &squareWave}}, {{BVG_STRING, OFF_WHITE, 218, 111, 220, 10, "FREQ SHAPE PULSE SYNC"}}, {{BVG_STRING, OFF_WHITE, 468, 34, 45, 10, "MIXER"}}, {{BVG_STRING, OFF_WHITE, 419, 111, 155, 10, "OSC-A OSC-B NOISE"}}, {{BVG_STRING, OFF_WHITE, 642, 34, 50, 10, "FILTER"}}, {{BVG_STRING, OFF_WHITE, 575, 111, 200, 10, "CUTOFF RES ENV KBD"}}, {{BVG_STRING, OFF_WHITE, 572, 226, 220, 10, "ATTACK DECAY SUSTAIN RELEASE"}}, {{BVG_STRING, OFF_WHITE, 910, 34, 40, 10, "MIDI"}}, {{BVG_STRING, OFF_WHITE, 778, 111, 280, 10, "TUNE A440 DOWN UP TUNE"}}, {{BVG_STRING, OFF_WHITE, 110, 145, 22, 10, "LFO"}}, {{BVG_VECT, OFF_WHITE, 120, 160, 10, 10, (char *) &rampWave}}, {{BVG_VECT, OFF_WHITE, 150, 160, 10, 10, (char *) &triWave}}, {{BVG_VECT, OFF_WHITE, 180, 160, 10, 10, (char *) &squareWave}}, {{BVG_STRING, OFF_WHITE, 65, 226, 130, 10, "FREQ SHAPE"}}, {{BVG_STRING, OFF_WHITE, 305, 145, 110, 10, "OSCILLATOR B"}}, {{BVG_VECT, OFF_WHITE, 320, 160, 10, 10, (char *) &rampWave}}, {{BVG_VECT, OFF_WHITE, 350, 160, 10, 10, (char *) &triWave}}, {{BVG_VECT, OFF_WHITE, 382, 160, 10, 10, (char *) &squareWave}}, {{BVG_STRING, OFF_WHITE, 222, 226, 350, 10, "FREQ FINE SHAPE PULSE LFO KBD"}}, {{BVG_STRING, OFF_WHITE, 837, 145, 80, 10, "AMPLIFIER"}}, {{BVG_STRING, OFF_WHITE, 765, 226, 280, 10, " ATTACK DECAY SUSTAIN RELEASE REL"}}, {{BVG_STRING, OFF_WHITE, 60, 256, 90, 10, "WHEEL MOD"}}, {{BVG_STRING, OFF_WHITE, 62, 274, 180, 10, "FRQA FRQB PWA PWB FILT"}}, {{BVG_STRING, OFF_WHITE, 21, 340, 150, 10, "MIX DEST"}}, {{BVG_STRING, OFF_WHITE, 220, 340, 120, 10, "GLIDE UNISON"}}, {{BVG_STRING, OFF_WHITE, 528, 256, 90, 10, "PROGRAMMER"}}, {{BVG_STRING, OFF_WHITE, 590, 274, 180, 10, "1 2 3 4 5 6 7 8"}}, {{BVG_STRING, OFF_WHITE, 366, 340, 110, 10, "LOAD SAVE BANK"}}, {{BVG_STRING, OFF_WHITE, 652, 340, 50, 10, "SELECT"}}, {{BVG_STRING, OFF_WHITE, 847, 256, 50, 10, "CHORUS"}}, {{BVG_STRING, OFF_WHITE, 775, 340, 230, 10, "SPEED DEPTH PHASE GAIN"}}, {{BVG_STRING, OFF_WHITE, 980, 340, 50, 10, "VOLUME"}}, } }; bvgImage ProphetImage = { 1024, 400, 0x00000000, 37, { {{BVG_STRING, OFF_WHITE, 75, 34, 85, 10, "POLY MOD"}}, {{BVG_STRING, OFF_WHITE, 120, 50, 100, 10, "FREQA PWA FILT"}}, {{BVG_STRING, OFF_WHITE, 10, 109, 120, 10, "FILT OSCB"}}, {{BVG_STRING, OFF_WHITE, 42, 119, 50, 10, "AMOUNT"}}, {{BVG_STRING, OFF_WHITE, 150, 114, 35, 10, "DEST"}}, {{BVG_STRING, OFF_WHITE, 286, 34, 110, 10, "OSCILLATOR A"}}, {{BVG_VECT, OFF_WHITE, 283, 50, 10, 10, (char *) &rampWave}}, {{BVG_VECT, OFF_WHITE, 315, 50, 10, 10, (char *) &squareWave}}, {{BVG_STRING, OFF_WHITE, 240, 111, 220, 10, "FREQ SHAPE PULSE SYNC"}}, {{BVG_STRING, OFF_WHITE, 494, 34, 45, 10, "MIXER"}}, {{BVG_STRING, OFF_WHITE, 449, 111, 155, 10, "OSC-A OSC-B NOISE"}}, {{BVG_STRING, OFF_WHITE, 672, 34, 50, 10, "FILTER"}}, {{BVG_STRING, OFF_WHITE, 605, 111, 200, 10, "CUTOFF RES ENV KBD"}}, {{BVG_STRING, OFF_WHITE, 602, 226, 220, 10, "ATTACK DECAY SUSTAIN RELEASE"}}, {{BVG_STRING, OFF_WHITE, 952, 34, 40, 10, "MIDI"}}, {{BVG_STRING, OFF_WHITE, 818, 111, 220, 10, "TUNE A440 DOWN UP"}}, {{BVG_STRING, OFF_WHITE, 115, 145, 22, 10, "LFO"}}, {{BVG_VECT, OFF_WHITE, 124, 160, 10, 10, (char *) &rampWave}}, {{BVG_VECT, OFF_WHITE, 155, 160, 10, 10, (char *) &triWave}}, {{BVG_VECT, OFF_WHITE, 185, 160, 10, 10, (char *) &squareWave}}, {{BVG_STRING, OFF_WHITE, 70, 226, 130, 10, "FREQ SHAPE"}}, {{BVG_STRING, OFF_WHITE, 325, 145, 110, 10, "OSCILLATOR B"}}, {{BVG_VECT, OFF_WHITE, 340, 160, 10, 10, (char *) &rampWave}}, {{BVG_VECT, OFF_WHITE, 370, 160, 10, 10, (char *) &triWave}}, {{BVG_VECT, OFF_WHITE, 402, 160, 10, 10, (char *) &squareWave}}, {{BVG_STRING, OFF_WHITE, 242, 226, 350, 10, "FREQ FINE SHAPE PULSE LFO KBD"}}, {{BVG_STRING, OFF_WHITE, 877, 145, 80, 10, "AMPLIFIER"}}, {{BVG_STRING, OFF_WHITE, 806, 226, 250, 10, " ATTACK DECAY SUSTAIN RELEASE "}}, {{BVG_STRING, OFF_WHITE, 63, 256, 90, 10, "WHEEL MOD"}}, {{BVG_STRING, OFF_WHITE, 56, 274, 180, 10, "FRQA FRQB PWA PWB FILT"}}, {{BVG_STRING, OFF_WHITE, 24, 340, 150, 10, "MIX DEST"}}, {{BVG_STRING, OFF_WHITE, 238, 340, 120, 10, "GLIDE UNISON"}}, {{BVG_STRING, OFF_WHITE, 552, 256, 90, 10, "PROGRAMMER"}}, {{BVG_STRING, OFF_WHITE, 620, 274, 180, 10, "1 2 3 4 5 6 7 8"}}, {{BVG_STRING, OFF_WHITE, 396, 340, 110, 10, "LOAD SAVE BANK"}}, {{BVG_STRING, OFF_WHITE, 687, 340, 50, 10, "SELECT"}}, {{BVG_STRING, OFF_WHITE, 808, 340, 250, 10, "RELEASE VOLUME TUNE "}}, } }; bvgImage AxxePhatImage = { 800, 400, 0x00000000, 61, { {{BVG_STRING, BVG_WHITE, 60, 56, 40, 8, "NOISE"}}, {{BVG_STRING, BVG_WHITE, 50, 70, 70, 8, "GENERATOR"}}, {{BVG_STRING, BVG_WHITE, 143, 45, 34, 8, "WHITE"}}, {{BVG_STRING, BVG_WHITE, 143, 72, 30, 8, "PINK"}}, {{BVG_STRING, BVG_WHITE, 178, 56, 140, 8, "VOLTAGE CONTROLLED"}}, {{BVG_STRING, BVG_WHITE, 206, 70, 70, 8, "OSCILLATOR"}}, {{BVG_VECT|2, OFF_WHITE, 300, 40, 17, 10, (char *) &sawWave}}, {{BVG_VECT|2, OFF_WHITE, 300, 77, 17, 10, (char *) &squareWave}}, {{BVG_STRING, BVG_WHITE, 347, 42, 26, 8, "LOW"}}, {{BVG_STRING, BVG_WHITE, 326, 56, 75, 8, "FREQUENCY"}}, {{BVG_STRING, BVG_WHITE, 327, 70, 75, 8, "OSCILLATOR"}}, {{BVG_VECT|2, OFF_WHITE, 400, 40, 19, 14, (char *) &sineWave}}, {{BVG_VECT|2, OFF_WHITE, 400, 77, 17, 10, (char *) &squareWave}}, {{BVG_STRING, BVG_WHITE, 424, 56, 40, 8, "AUDIO"}}, {{BVG_STRING, BVG_WHITE, 424, 70, 40, 8, "MIXER"}}, {{BVG_STRING, BVG_WHITE, 476, 56, 140, 8, "VOLTAGE CONTROLLED"}}, {{BVG_STRING, BVG_WHITE, 510, 70, 40, 8, "FILTER"}}, {{BVG_STRING, BVG_WHITE, 615, 42, 50, 8, "VOLTAGE"}}, {{BVG_STRING, BVG_WHITE, 606, 56, 75, 8, "CONTROLLED"}}, {{BVG_STRING, BVG_WHITE, 605, 70, 75, 8, "AMPLIFIER"}}, {{BVG_STRING, BVG_WHITE, 696, 42, 110, 8, "GATE SINGLE"}}, {{BVG_STRING, BVG_WHITE, 696, 70, 110, 8, "AUTO MULTI "}}, {{BVG_STRING, BVG_WHITE, 715, 94, 55, 8, "LFO/TRIG"}}, {{BVG_STRING, BVG_WHITE, 262, 160, 130, 8, "PW PWM FREQ"}}, {{BVG_STRING, BVG_WHITE, 478, 144, 28, 8, "VCF"}}, {{BVG_STRING, BVG_WHITE, 462, 160, 70, 8, "FREQ RES"}}, {{BVG_STRING, BVG_WHITE, 613, 160, 32, 8, "GAIN"}}, {{BVG_STRING, BVG_WHITE, 710, 144, 28, 8, "ENV"}}, {{BVG_STRING, BVG_WHITE, 680, 160, 100, 8, "A D S R"}}, {{BVG_STRING, BVG_WHITE, 100, 160, 65, 8, "TRANSPOSE"}}, {{BVG_STRING, BVG_WHITE, 122, 190, 18, 8, "+1"}}, {{BVG_STRING, BVG_WHITE, 122, 280, 18, 8, "-1"}}, {{BVG_VECT, OFF_WHITE, 28, 190, 8, 10, (char *) &flat}}, {{BVG_VECT, OFF_WHITE, 50, 190, 10, 10, (char *) &sineWave}}, {{BVG_VECT, OFF_WHITE, 73, 190, 8, 10, (char *) &sharp}}, {{BVG_STRING, BVG_WHITE, 22, 245, 90, 8, "PITCH CONTROL"}}, {{BVG_STRING, BVG_WHITE, 90, 315, 30, 8, "GLIDE"}}, {{BVG_STRING, BVG_WHITE, 148, 315, 125, 8, "LFO LFO S/H ADSR"}}, {{BVG_VECT, OFF_WHITE, 148, 328, 16, 10, (char *) &sineWave}}, {{BVG_VECT, OFF_WHITE, 173, 328, 16, 10, (char *) &squareWave}}, {{BVG_VECT, OFF_WHITE, 222, 328, 16, 10, (char *) &env}}, {{BVG_STRING, BVG_WHITE, 286, 315, 60, 8, "LFO ADSR"}}, {{BVG_VECT, OFF_WHITE, 286, 328, 16, 10, (char *) &sineWave}}, {{BVG_VECT, OFF_WHITE, 313, 328, 16, 10, (char *) &env}}, {{BVG_STRING, BVG_WHITE, 375, 315, 100, 8, "NOISE VCO VCO"}}, {{BVG_VECT, OFF_WHITE, 411, 328, 16, 10, (char *) &sawWave}}, {{BVG_VECT, OFF_WHITE, 434, 328, 16, 10, (char *) &squareWave}}, {{BVG_STRING, BVG_WHITE, 525, 315, 100, 8, "KBD LFO ADSR"}}, {{BVG_VECT, OFF_WHITE, 555, 328, 16, 10, (char *) &sineWave}}, {{BVG_VECT, OFF_WHITE, 584, 328, 17, 10, (char *) &env}}, {{BVG_STRING, BVG_WHITE, 636, 315, 32, 8, "ADSR"}}, {{BVG_VECT, OFF_WHITE, 639, 328, 17, 10, (char *) &env}}, {{BVG_STRING, BVG_WHITE, 50, 362, 32, 8, "MIDI"}}, {{BVG_STRING, BVG_WHITE, 20, 384, 32, 8, "DOWN"}}, {{BVG_STRING, BVG_WHITE, 83, 384, 16, 8, "UP"}}, {{BVG_STRING, BVG_WHITE, 130, 384, 32, 8, "LOAD"}}, {{BVG_STRING, BVG_WHITE, 176, 384, 250, 8, "1 2 3 4 5 6 7 8 "}}, {{BVG_STRING, BVG_WHITE, 405, 384, 250, 8, "1 2 3 4 5 6 7 8 "}}, {{BVG_STRING, BVG_WHITE, 627, 384, 32, 8, "SAVE"}}, {{BVG_STRING|3, BVG_WHITE, 670, 364, 55, 18, "ARP"}}, {{BVG_STRING|3, 0x00ff6900, 723, 364, 70, 18, "AXXE"}}, } }; bvgImage AxxeImage = { 800, 400, 0x00000000, 61, { {{BVG_STRING, BVG_WHITE, 60, 100, 40, 8, "NOISE"}}, {{BVG_STRING, BVG_WHITE, 50, 112, 70, 8, "GENERATOR"}}, {{BVG_STRING, BVG_WHITE, 143, 90, 34, 8, "WHITE"}}, {{BVG_STRING, BVG_WHITE, 143, 116, 30, 8, "PINK"}}, {{BVG_STRING, BVG_WHITE, 178, 100, 140, 8, "VOLTAGE CONTROLLED"}}, {{BVG_STRING, BVG_WHITE, 206, 112, 70, 8, "OSCILLATOR"}}, {{BVG_VECT|2, OFF_WHITE, 300, 84, 17, 10, (char *) &sawWave}}, {{BVG_VECT|2, OFF_WHITE, 300, 117, 17, 10, (char *) &squareWave}}, {{BVG_STRING, BVG_WHITE, 347, 89, 26, 8, "LOW"}}, {{BVG_STRING, BVG_WHITE, 326, 100, 75, 8, "FREQUENCY"}}, {{BVG_STRING, BVG_WHITE, 327, 112, 75, 8, "OSCILLATOR"}}, {{BVG_VECT|2, OFF_WHITE, 400, 84, 19, 14, (char *) &sineWave}}, {{BVG_VECT|2, OFF_WHITE, 400, 117, 17, 10, (char *) &squareWave}}, {{BVG_STRING, BVG_WHITE, 424, 100, 40, 8, "AUDIO"}}, {{BVG_STRING, BVG_WHITE, 424, 112, 40, 8, "MIXER"}}, {{BVG_STRING, BVG_WHITE, 476, 100, 140, 8, "VOLTAGE CONTROLLED"}}, {{BVG_STRING, BVG_WHITE, 510, 112, 40, 8, "FILTER"}}, {{BVG_STRING, BVG_WHITE, 615, 89, 50, 8, "VOLTAGE"}}, {{BVG_STRING, BVG_WHITE, 606, 100, 75, 8, "CONTROLLED"}}, {{BVG_STRING, BVG_WHITE, 605, 112, 75, 8, "AMPLIFIER"}}, {{BVG_STRING, BVG_WHITE, 696, 89, 110, 8, "GATE SINGLE"}}, {{BVG_STRING, BVG_WHITE, 696, 116, 110, 8, "AUTO MULTI "}}, {{BVG_STRING, BVG_WHITE, 715, 133, 55, 8, "LFO/TRIG"}}, {{BVG_STRING, BVG_WHITE, 262, 190, 130, 8, "PW PWM FREQ"}}, {{BVG_STRING, BVG_WHITE, 478, 175, 28, 8, "VCF"}}, {{BVG_STRING, BVG_WHITE, 462, 190, 70, 8, "FREQ RES"}}, {{BVG_STRING, BVG_WHITE, 613, 190, 32, 8, "GAIN"}}, {{BVG_STRING, BVG_WHITE, 710, 175, 28, 8, "ENV"}}, {{BVG_STRING, BVG_WHITE, 680, 190, 100, 8, "A D S R"}}, {{BVG_STRING, BVG_WHITE, 100, 190, 65, 8, "TRANSPOSE"}}, {{BVG_STRING, BVG_WHITE, 122, 215, 18, 8, "+1"}}, {{BVG_STRING, BVG_WHITE, 122, 300, 18, 8, "-1"}}, {{BVG_VECT, OFF_WHITE, 28, 215, 8, 10, (char *) &flat}}, {{BVG_VECT, OFF_WHITE, 50, 215, 10, 10, (char *) &sineWave}}, {{BVG_VECT, OFF_WHITE, 73, 215, 8, 10, (char *) &sharp}}, {{BVG_STRING, BVG_WHITE, 22, 270, 90, 8, "PITCH CONTROL"}}, {{BVG_STRING, BVG_WHITE, 90, 322, 30, 8, "GLIDE"}}, {{BVG_STRING, BVG_WHITE, 148, 322, 125, 8, "LFO LFO S/H ADSR"}}, {{BVG_VECT, OFF_WHITE, 148, 334, 16, 10, (char *) &sineWave}}, {{BVG_VECT, OFF_WHITE, 173, 334, 16, 10, (char *) &squareWave}}, {{BVG_VECT, OFF_WHITE, 222, 334, 16, 10, (char *) &env}}, {{BVG_STRING, BVG_WHITE, 286, 322, 60, 8, "LFO ADSR"}}, {{BVG_VECT, OFF_WHITE, 286, 334, 16, 10, (char *) &sineWave}}, {{BVG_VECT, OFF_WHITE, 313, 334, 16, 10, (char *) &env}}, {{BVG_STRING, BVG_WHITE, 375, 322, 100, 8, "NOISE VCO VCO"}}, {{BVG_VECT, OFF_WHITE, 411, 334, 16, 10, (char *) &sawWave}}, {{BVG_VECT, OFF_WHITE, 434, 334, 16, 10, (char *) &squareWave}}, {{BVG_STRING, BVG_WHITE, 525, 322, 100, 8, "KBD LFO ADSR"}}, {{BVG_VECT, OFF_WHITE, 555, 334, 16, 10, (char *) &sineWave}}, {{BVG_VECT, OFF_WHITE, 584, 334, 17, 10, (char *) &env}}, {{BVG_STRING, BVG_WHITE, 636, 322, 32, 8, "ADSR"}}, {{BVG_VECT, OFF_WHITE, 639, 334, 17, 10, (char *) &env}}, {{BVG_STRING, BVG_WHITE, 50, 367, 32, 8, "MIDI"}}, {{BVG_STRING, BVG_WHITE, 20, 386, 32, 8, "DOWN"}}, {{BVG_STRING, BVG_WHITE, 83, 386, 16, 8, "UP"}}, {{BVG_STRING, BVG_WHITE, 130, 386, 32, 8, "LOAD"}}, {{BVG_STRING, BVG_WHITE, 176, 386, 250, 8, "1 2 3 4 5 6 7 8 "}}, {{BVG_STRING, BVG_WHITE, 405, 386, 250, 8, "1 2 3 4 5 6 7 8 "}}, {{BVG_STRING, BVG_WHITE, 627, 386, 32, 8, "SAVE"}}, {{BVG_STRING|3, BVG_WHITE, 670, 367, 55, 18, "ARP"}}, {{BVG_STRING|3, 0x00ff6900, 723, 367, 70, 18, "AXXE"}}, } }; bvgImage MemoryMoogImage = { 800, 180, 0x00000000, 62, { {{BVG_STRING, OFF_WHITE, 25, 14, 40, 6, "GLOBAL"}}, {{BVG_STRING, OFF_WHITE, 12, 47, 30, 6, "AUTO"}}, {{BVG_STRING, OFF_WHITE, 42, 47, 30, 6, "TUNE"}}, {{BVG_STRING, OFF_WHITE, 14, 73, 80, 6, "MONO HOLD MULT"}}, {{BVG_STRING, OFF_WHITE, 18, 101, 60, 6, "GLIDE ON"}}, {{BVG_STRING, OFF_WHITE, 20, 131, 50, 6, "OCTAVE"}}, {{BVG_STRING, OFF_WHITE, 16, 159, 65, 6, "PITCH MOD"}}, {{BVG_STRING, OFF_WHITE, 95, 14, 60, 6, "PROGRAMMER"}}, {{BVG_STRING, OFF_WHITE, 95, 32, 60, 6, "DOWN UP"}}, {{BVG_STRING, OFF_WHITE, 80, 88, 105, 6, "1 2 3 "}}, {{BVG_STRING, OFF_WHITE, 80, 112, 105, 6, "4 5 6 "}}, {{BVG_STRING, OFF_WHITE, 80, 136, 105, 6, "7 8 9 "}}, {{BVG_STRING, OFF_WHITE, 80, 160, 105, 6, "L 0 S "}}, {{BVG_STRING, OFF_WHITE, 166, 14, 50, 6, "PRESSURE"}}, {{BVG_STRING, OFF_WHITE, 166, 25, 50, 6, "AMOUNT 1"}}, {{BVG_STRING, OFF_WHITE, 166, 70, 50, 6, "PITCH FILT"}}, {{BVG_STRING, OFF_WHITE, 166, 95, 45, 6, "VOLUME"}}, {{BVG_STRING, OFF_WHITE, 166, 113, 50, 6, "AMOUNT 2"}}, {{BVG_STRING, OFF_WHITE, 166, 160, 50, 6, "MOD OSC2"}}, {{BVG_STRING, OFF_WHITE, 270, 14, 60, 6, "MODIFIERS"}}, {{BVG_STRING, OFF_WHITE, 227, 47, 28, 6, "FREQ"}}, {{BVG_VECT, OFF_WHITE, 262, 47, 10, 6, (char *) &triWave}}, {{BVG_VECT, OFF_WHITE, 281, 47, 10, 6, (char *) &rampWave}}, {{BVG_VECT, OFF_WHITE, 300, 47, 10, 6, (char *) &sawWave}}, {{BVG_VECT, OFF_WHITE, 320, 47, 10, 6, (char *) &squareWave}}, {{BVG_STRING, OFF_WHITE, 338, 47, 22, 6, "S/H"}}, {{BVG_STRING, OFF_WHITE, 220, 83, 180, 6, "FM1 FM2 FM3 PW1 PW2 PW3 FILT"}}, {{BVG_STRING, OFF_WHITE, 228, 122, 170, 6, "OSC3 ENV CONTOUR INVERT"}}, {{BVG_STRING, OFF_WHITE, 240, 160, 130, 6, "FM1 FM2 PW1 PW2 FILT"}}, {{BVG_STRING, OFF_WHITE, 445, 14, 80, 6, "OSCILLATORS"}}, {{BVG_STRING, OFF_WHITE, 372, 47, 156, 6, "16 8 4 2 SYNC PW"}}, {{BVG_VECT, OFF_WHITE, 513, 47, 10, 6, (char *) &squareWave}}, {{BVG_VECT, OFF_WHITE, 534, 47, 10, 6, (char *) &sawWave}}, {{BVG_VECT, OFF_WHITE, 555, 47, 10, 6, (char *) &triWave}}, {{BVG_STRING, OFF_WHITE, 372, 83, 156, 6, "16 8 4 2 SYNC PW"}}, {{BVG_VECT, OFF_WHITE, 513, 83, 10, 6, (char *) &squareWave}}, {{BVG_VECT, OFF_WHITE, 534, 83, 10, 6, (char *) &sawWave}}, {{BVG_VECT, OFF_WHITE, 555, 83, 10, 6, (char *) &triWave}}, {{BVG_STRING, OFF_WHITE, 372, 122, 156, 6, "16 8 4 2 SYNC PW"}}, {{BVG_VECT, OFF_WHITE, 513, 122, 10, 6, (char *) &squareWave}}, {{BVG_VECT, OFF_WHITE, 534, 122, 10, 6, (char *) &sawWave}}, {{BVG_VECT, OFF_WHITE, 555, 122, 10, 6, (char *) &triWave}}, {{BVG_STRING, OFF_WHITE, 385, 160, 25, 6, "LFO"}}, {{BVG_STRING, OFF_WHITE, 428, 160, 25, 6, "KBD"}}, {{BVG_STRING, OFF_WHITE, 575, 14, 30, 6, "MIXER"}}, {{BVG_STRING, OFF_WHITE, 575, 47, 30, 6, "OSC-1"}}, {{BVG_STRING, OFF_WHITE, 575, 83, 30, 6, "OSC-2"}}, {{BVG_STRING, OFF_WHITE, 575, 122, 30, 6, "OSC-3"}}, {{BVG_STRING, OFF_WHITE, 575, 160, 30, 6, "NOISE"}}, {{BVG_STRING, OFF_WHITE, 675, 14, 36, 6, "FILTER"}}, {{BVG_STRING, OFF_WHITE, 623, 45, 36, 6, "1/3 2/3"}}, {{BVG_STRING, OFF_WHITE, 629, 52, 20, 6, "KBD"}}, {{BVG_STRING, OFF_WHITE, 656, 47, 120, 6, "CUTOFF RES ENV"}}, {{BVG_STRING, OFF_WHITE, 620, 83, 180, 6, "ATTACK DECAY SUSTAIN RELEASE"}}, {{BVG_STRING, OFF_WHITE, 621, 120, 160, 6, "ZERO COND KBD REL"}}, {{BVG_STRING, OFF_WHITE, 620, 132, 180, 6, "ATTACK DECAY SUSTAIN RELEASE"}}, {{BVG_STRING, OFF_WHITE, 763, 14, 36, 6, "VOLUME"}}, {{BVG_STRING, OFF_WHITE, 763, 47, 36, 6, "MASTER"}}, {{BVG_STRING, OFF_WHITE, 763, 56, 36, 6, " PROG "}}, {{BVG_STRING, OFF_WHITE, 763, 89, 36, 6, "CHORUS"}}, {{BVG_STRING, OFF_WHITE, 763, 121, 36, 6, " GAIN "}}, {{BVG_STRING, OFF_WHITE, 764, 132, 32, 6, "DEPTH"}}, } }; bvgImage Sonic6Image = { 900, 800, 0x00000000, 102, { {{BVG_VECT, BVG_BLACK, 92, 65, 27, 60, (char *) &pot}}, {{BVG_STRING, BVG_WHITE, 98, 58, 22, 10, "LFO"}}, {{BVG_STRING, BVG_BLACK, 88, 125, 50, 10, "MIX X/Y"}}, {{BVG_VECT, BVG_BLACK, 275, 65, 27, 60, (char *) &pot}}, {{BVG_STRING, BVG_WHITE, 265, 58, 66, 10, "OSCILLATOR"}}, {{BVG_STRING, BVG_BLACK, 268, 125, 50, 10, "MIX A/B"}}, {{BVG_STRING, BVG_WHITE, 48, 167, 150, 10, "LFO X LFO Y"}}, {{BVG_VECT, BVG_BLACK, 28, 206, 8, 10, (char *) &triWave}}, {{BVG_VECT, BVG_BLACK, 35, 192, 10, 10, (char *) &rampWave}}, {{BVG_VECT, BVG_BLACK, 54, 192, 10, 10, (char *) &sawWave}}, {{BVG_VECT, BVG_BLACK, 62, 206, 10, 10, (char *) &squareWave}}, {{BVG_VECT, BVG_BLACK, 143, 206, 8, 10, (char *) &triWave}}, {{BVG_VECT, BVG_BLACK, 150, 192, 10, 10, (char *) &rampWave}}, {{BVG_VECT, BVG_BLACK, 169, 192, 10, 10, (char *) &sawWave}}, {{BVG_VECT, BVG_BLACK, 175, 206, 10, 10, (char *) &biRampWave}}, {{BVG_STRING, BVG_BLACK, 50, 295, 36, 10, "MASTER"}}, {{BVG_STRING, BVG_BLACK, 50, 313, 36, 10, "MOD "}}, {{BVG_STRING, BVG_BLACK, 50, 331, 36, 10, "ADSR "}}, {{BVG_STRING, BVG_BLACK, 139, 295, 36, 10, "MASTER"}}, {{BVG_STRING, BVG_BLACK, 139, 313, 36, 10, " MOD"}}, {{BVG_STRING, BVG_BLACK, 139, 331, 36, 10, " ADSR"}}, {{BVG_STRING, BVG_BLACK, 77, 342, 80, 10, "RATE RATE"}}, {{BVG_STRING, BVG_BLACK, 99, 532, 22, 10, "LFO"}}, {{BVG_STRING, BVG_BLACK, 92, 550, 36, 10, "MASTER"}}, {{BVG_STRING, BVG_WHITE, 215, 167, 75, 10, "OSCILLATOR A"}}, {{BVG_VECT, BVG_BLACK, 205, 204, 27, 60, (char *) &pot}}, {{BVG_VECT, BVG_BLACK, 205, 285, 27, 60, (char *) &pot}}, {{BVG_STRING, BVG_BLACK, 204, 260, 100, 10, "FREQUENCY 16 8 4 "}}, {{BVG_STRING, BVG_BLACK, 205, 342, 35, 10, "WIDTH"}}, {{BVG_VECT, BVG_BLACK, 248, 342, 8, 10, (char *) &triWave}}, {{BVG_VECT, BVG_BLACK, 258, 342, 8, 10, (char *) &rampWave}}, {{BVG_VECT, BVG_BLACK, 268, 342, 8, 10, (char *) &pWave}}, {{BVG_STRING, BVG_WHITE, 210, 378, 85, 10, "PITCH CONTROL"}}, {{BVG_VECT, BVG_BLACK, 205, 410, 27, 60, (char *) &pot}}, {{BVG_VECT, BVG_BLACK, 254, 410, 27, 60, (char *) &pot}}, {{BVG_STRING, BVG_BLACK, 210, 471, 90, 10, "X/Y ADSR"}}, {{BVG_STRING, BVG_BLACK, 220, 546, 70, 10, " LOW OFF HIGH"}}, {{BVG_STRING, BVG_WHITE, 310, 167, 75, 10, "OSCILLATOR B"}}, {{BVG_VECT, BVG_BLACK, 348, 204, 27, 60, (char *) &pot}}, {{BVG_VECT, BVG_BLACK, 348, 285, 27, 60, (char *) &pot}}, {{BVG_STRING, BVG_BLACK, 296, 260, 100, 10, " 16 8 4 FREQUENCY"}}, {{BVG_STRING, BVG_BLACK, 348, 342, 35, 10, "WIDTH"}}, {{BVG_VECT, BVG_BLACK, 300, 342, 8, 10, (char *) &triWave}}, {{BVG_VECT, BVG_BLACK, 310, 342, 8, 10, (char *) &rampWave}}, {{BVG_VECT, BVG_BLACK, 320, 342, 8, 10, (char *) &pWave}}, {{BVG_STRING, BVG_WHITE, 302, 378, 85, 10, "PITCH CONTROL"}}, {{BVG_VECT, BVG_BLACK, 298, 410, 27, 60, (char *) &pot}}, {{BVG_VECT, BVG_BLACK, 348, 410, 27, 60, (char *) &pot}}, {{BVG_VECT, BVG_BLACK, 323, 489, 27, 60, (char *) &pot}}, {{BVG_STRING, BVG_BLACK, 298, 471, 96, 10, "OSC-A X/Y"}}, {{BVG_STRING, BVG_BLACK, 326, 546, 24, 10, "PWM"}}, {{BVG_STRING, BVG_WHITE, 410, 167, 50, 10, "RINGMOD"}}, {{BVG_STRING, BVG_BLACK, 395, 205, 80, 10, "OSCA EXT"}}, {{BVG_STRING, BVG_BLACK, 395, 290, 80, 10, "X/Y OSCB"}}, {{BVG_STRING, BVG_WHITE, 412, 378, 35, 10, "NOISE"}}, {{BVG_STRING, BVG_BLACK, 420, 448, 25, 10, "PINK"}}, {{BVG_STRING, BVG_BLACK, 420, 525, 25, 10, "WHITE"}}, {{BVG_STRING, BVG_WHITE, 490, 167, 35, 10, "MIXER"}}, {{BVG_VECT, BVG_BLACK, 490, 203, 27, 60, (char *) &pot}}, {{BVG_VECT, BVG_BLACK, 490, 291, 27, 60, (char *) &pot}}, {{BVG_VECT, BVG_BLACK, 490, 380, 27, 60, (char *) &pot}}, {{BVG_VECT, BVG_BLACK, 490, 470, 27, 60, (char *) &pot}}, {{BVG_STRING, BVG_BLACK, 490, 270, 45, 10, "MIX A/B"}}, {{BVG_STRING, BVG_BLACK, 485, 360, 50, 10, "RINGMOD"}}, {{BVG_STRING, BVG_BLACK, 485, 450, 50, 10, "EXTERNAL"}}, {{BVG_STRING, BVG_BLACK, 490, 540, 35, 10, "NOISE"}}, {{BVG_VECT, BVG_BLACK, 559, 67, 27, 58, (char *) &pot}}, {{BVG_VECT, BVG_BLACK, 606, 67, 27, 58, (char *) &pot}}, {{BVG_VECT, BVG_BLACK, 654, 67, 27, 58, (char *) &pot}}, {{BVG_VECT, BVG_BLACK, 700, 67, 27, 58, (char *) &pot}}, {{BVG_STRING, BVG_WHITE, 620, 58, 55, 10, "ENVELOPE"}}, {{BVG_STRING, BVG_BLACK, 560, 125, 210, 10, "ATTACK DECAY SUSTAIN RELEASE"}}, {{BVG_VECT, BVG_BLACK, 758, 67, 27, 58, (char *) &pot}}, {{BVG_VECT, BVG_BLACK, 799, 67, 27, 58, (char *) &pot}}, {{BVG_VECT, BVG_BLACK, 839, 67, 27, 58, (char *) &pot}}, {{BVG_STRING, BVG_WHITE, 765, 58, 120, 10, "DIRECT OUTPUT MIXER"}}, {{BVG_STRING, BVG_BLACK, 757, 125, 140, 10, "OSC-A OSC-B RINGMOD"}}, {{BVG_STRING, BVG_WHITE, 578, 167, 38, 10, "BYPASS"}}, {{BVG_STRING, BVG_WHITE, 568, 228, 70, 10, "ARTICULATOR"}}, {{BVG_STRING, BVG_WHITE, 575, 300, 50, 10, "ENVELOPE"}}, {{BVG_STRING, BVG_BLACK, 575, 318, 50, 10, "ASR ADSD"}}, {{BVG_STRING, BVG_BLACK, 565, 340, 80, 10, "AR ADSR"}}, {{BVG_STRING, BVG_BLACK, 575, 426, 50, 10, "VELOCITY"}}, {{BVG_STRING, BVG_WHITE, 560, 460, 90, 10, "TRIGGER INPUTS"}}, {{BVG_STRING, BVG_BLACK, 558, 550, 90, 10, "KBD LFO-X LFO-Y"}}, {{BVG_STRING, BVG_WHITE, 678, 167, 38, 10, "FILTER"}}, {{BVG_STRING, BVG_BLACK, 658, 426, 90, 10, "FREQ RESONANCE"}}, {{BVG_VECT, BVG_BLACK, 652, 488, 27, 58, (char *) &pot}}, {{BVG_VECT, BVG_BLACK, 706, 488, 27, 58, (char *) &pot}}, {{BVG_STRING, BVG_WHITE, 652, 460, 110, 10, "PITCH CONTROL INPUTS"}}, {{BVG_STRING, BVG_BLACK, 652, 550, 100, 10, "ADSR KBD X/Y"}}, {{BVG_STRING, BVG_WHITE, 765, 283, 110, 10, "1 2 3 4 "}}, {{BVG_STRING, BVG_WHITE, 765, 350, 110, 10, "5 6 7 8 "}}, {{BVG_STRING, BVG_WHITE, 760, 416, 130, 10, "LOAD SAVE MEM MIDI"}}, {{BVG_STRING, BVG_WHITE, 760, 475, 60, 10, "BANK FIND"}}, {{BVG_STRING, BVG_WHITE, 835, 378, 8, 10, "U"}}, {{BVG_STRING, BVG_WHITE, 835, 450, 8, 10, "D"}}, {{BVG_STRING|2, BVG_BLACK, 779, 500, 70, 23, "bristol"}}, {{BVG_STRING, BVG_WHITE, 781, 532, 70, 14, "SONIC VX"}}, {{BVG_STRING, BVG_WHITE, 776, 554, 80, 10, "SYNTHESIZER"}}, {{BVG_STRING, OFF_WHITE, 56, 767, 130, 10, "TUNE X Y"}}, {{BVG_STRING, OFF_WHITE, 779, 767, 32, 10, "REVERB"}}, } }; bvgImage PolyImage = { 1500, 400, 0x00000000, 50, { {{BVG_STRING, POLY_WHITE, 15, 15, 130, 14, "OUTPUT PHONES"}}, {{BVG_STRING, POLY_WHITE, 140, 15, 80, 14, "IN OUT"}}, {{BVG_STRING, POLY_WHITE, 160, 25, 20, 14, "CV"}}, {{BVG_STRING, POLY_WHITE, 218, 15, 90, 14, "IN OUT"}}, {{BVG_STRING, POLY_WHITE, 240, 25, 30, 14, "TRIG"}}, {{BVG_STRING, POLY_WHITE, 315, 15, 30, 14, "VCO"}}, {{BVG_STRING, POLY_WHITE, 355, 15, 30, 14, "VCF"}}, {{BVG_STRING, POLY_WHITE, 405, 12, 150, 14, "IN THRU OUT"}}, {{BVG_STRING, POLY_WHITE, 455, 28, 35, 14, "MIDI"}}, {{BVG_STRING, POLY_WHITE, 40, 355, 80, 16, "BEND MG"}}, {{BVG_STRING, POLY_WHITE, 25, 148, 150, 16, "VOLUME TUNE"}}, {{BVG_STRING, POLY_WHITE, 30, 255, 140, 16, "GLIDE BEND"}}, {{BVG_STRING, POLY_WHITE, 312, 52, 35, 16, "VCO"}}, {{BVG_STRING, POLY_WHITE, 175, 148, 270, 16, "OCTAVE WAVE PW/PWM FREQ"}}, {{BVG_STRING, POLY_WHITE, 190, 65, 30, 16, "1 2"}}, {{BVG_STRING, POLY_WHITE, 176, 80, 60, 16, "0 3"}}, {{BVG_VECT, POLY_WHITE, 235, 80, 10, 16, (char *) &triWave}}, {{BVG_VECT, POLY_WHITE, 250, 65, 10, 16, (char *) &sawWave}}, {{BVG_VECT, POLY_WHITE, 268, 65, 10, 16, (char *) &squareWave}}, {{BVG_VECT, POLY_WHITE, 285, 80, 10, 16, (char *) &pulseWave}}, {{BVG_STRING, POLY_WHITE, 445, 80, 35, 16, "OFF"}}, {{BVG_STRING, POLY_WHITE, 445, 110, 38, 16, "SUB1"}}, {{BVG_STRING, POLY_WHITE, 445, 140, 38, 16, "SUB2"}}, {{BVG_STRING, POLY_WHITE, 175, 255, 280, 16, "NOISE FREQ DELAY LEVEL"}}, {{BVG_STRING, POLY_WHITE, 445, 190, 35, 16, "VCO"}}, {{BVG_STRING, POLY_WHITE, 445, 220, 35, 16, "VCF"}}, {{BVG_STRING, POLY_WHITE, 445, 250, 35, 16, "VCA"}}, {{BVG_STRING, POLY_WHITE, 340, 284, 28, 16, "MG"}}, {{BVG_STRING, POLY_WHITE, 590, 52, 35, 16, "VCF"}}, {{BVG_STRING, POLY_WHITE, 490, 148, 250, 16, "FREQ RES ENV KBD"}}, {{BVG_STRING, POLY_WHITE, 550, 255, 190, 16, "HOLD MONO POLY"}}, {{BVG_STRING, POLY_WHITE, 620, 284, 50, 16, "MODE"}}, {{BVG_STRING, POLY_WHITE, 815, 52, 90, 16, "ENVELOPE"}}, {{BVG_STRING, POLY_WHITE, 738, 148, 280, 16, "ATTACK DECAY SUSTAIN RELEASE"}}, {{BVG_STRING, POLY_WHITE, 738, 255, 280, 16, "ATTACK DECAY SUSTAIN RELEASE"}}, {{BVG_STRING, POLY_WHITE, 1035, 52, 45, 16, "VCA"}}, {{BVG_STRING, POLY_WHITE, 1028, 86, 35, 16, "ENV"}}, {{BVG_STRING, POLY_WHITE, 1028, 116, 38, 16, "GATE"}}, {{BVG_STRING, POLY_WHITE, 1072, 148, 40, 16, "GAIN"}}, {{BVG_STRING, POLY_WHITE, 1013, 180, 40, 16, "1 2"}}, {{BVG_STRING, POLY_WHITE, 1000, 200, 65, 16, "0 3"}}, {{BVG_STRING, POLY_WHITE, 1008, 255, 130, 16, "MODE INTENSITY"}}, {{BVG_STRING, POLY_WHITE, 1025, 284, 80, 16, "EFFECTS"}}, {{BVG_STRING, POLY_WHITE, 1255, 52, 120, 16, "MEMORY"}}, {{BVG_STRING, POLY_WHITE, 1133, 148, 320, 16, "L 1 2 3 4 5 6 7 8"}}, {{BVG_STRING, POLY_WHITE, 1133, 255, 320, 16, "S 1 2 3 4 5 6 7 8"}}, {{BVG_STRING, POLY_WHITE, 1448, 52, 40, 16, "MIDI"}}, {{BVG_STRING, POLY_WHITE, 1448, 148, 40, 16, " U "}}, {{BVG_STRING, POLY_WHITE, 1448, 255, 40, 16, " D "}}, {{BVG_STRING, POLY_WHITE, 1435, 16, 60, 14, "POWER"}}, } }; bvgImage MiniPhatImage = { 680, 400, 0x00000000, 78, { {{BVG_STRING|2, OFF_WHITER, 5, 370, 100, 13, "CONTROLLERS"}}, {{BVG_STRING, OFF_WHITE, 36, 80, 25, 11, "TUNE"}}, {{BVG_STRING, OFF_WHITE, 44, 94, 7, 10, "O"}}, {{BVG_STRING, OFF_WHITE, 30, 157, 45, 10, "-1 1"}}, {{BVG_STRING, OFF_WHITE, 14, 195, 30, 11, "GLIDE"}}, {{BVG_STRING, OFF_WHITE, 58, 195, 24, 11, "MOD"}}, {{BVG_STRING, OFF_WHITE, 48, 284, 20, 10, "OSC"}}, {{BVG_STRING, OFF_WHITE, 72, 284, 20, 10, "NSE"}}, {{BVG_STRING, OFF_WHITE, 17, 310, 42, 10, "RELEASE"}}, {{BVG_STRING, OFF_WHITE, 27, 332, 34, 10, "MULTI"}}, {{BVG_STRING, OFF_WHITE, 86, 127, 24, 11, "MOD"}}, {{BVG_STRING, OFF_WHITE, 88, 268, 24, 11, "LFO"}}, {{BVG_STRING|2, OFF_WHITER, 120, 370, 140, 13, "OSCILLATOR BANK"}}, {{BVG_STRING, OFF_WHITE, 115, 23, 175, 11, "RANGE OSCILLATOR-1 WAVEFORM"}}, {{BVG_STRING, OFF_WHITE, 145, 123, 90, 11, "OSCILLATOR-2"}}, {{BVG_STRING, OFF_WHITE, 145, 238, 90, 11, "OSCILLATOR-3"}}, {{BVG_STRING|2, OFF_WHITER, 325, 370, 50, 13, "MIXER"}}, {{BVG_STRING, OFF_WHITE, 270, 23, 38, 11, "VOLUME"}}, {{BVG_STRING, OFF_WHITE, 365, 85, 60, 11, "EXTERNAL"}}, {{BVG_STRING, OFF_WHITE, 370, 194, 40, 11, "NOISE"}}, {{BVG_STRING, OFF_WHITE, 413, 266, 24, 9, "PINK"}}, {{BVG_STRING, OFF_WHITE, 340, 90, 12, 8, "ON"}}, {{BVG_STRING, OFF_WHITE, 340, 148, 12, 8, "ON"}}, {{BVG_STRING, OFF_WHITE, 340, 206, 12, 8, "ON"}}, {{BVG_STRING, OFF_WHITE, 340, 262, 12, 8, "ON"}}, {{BVG_STRING, OFF_WHITE, 340, 318, 12, 8, "ON"}}, {{BVG_STRING|2, OFF_WHITER, 470, 370, 100, 13, "MODIFIERS"}}, {{BVG_STRING, OFF_WHITER, 500, 6, 55, 12, "FILTER"}}, {{BVG_STRING, OFF_WHITE, 442, 23, 190, 11, "FREQUENCY EMPHASIS CONTOUR"}}, {{BVG_STRING, OFF_WHITE, 422, 46, 24, 11, "MOD"}}, {{BVG_STRING, OFF_WHITE, 422, 146, 24, 11, "KBD"}}, {{BVG_STRING, OFF_WHITE, 455, 138, 170, 9, "ATTACK DECAY SUSTAIN"}}, {{BVG_STRING, OFF_WHITE, 470, 240, 130, 11, "LOUDNESS CONTOUR"}}, {{BVG_STRING, OFF_WHITE, 455, 254, 170, 9, "ATTACK DECAY SUSTAIN"}}, {{BVG_STRING|2, OFF_WHITER, 620, 370, 55, 13, "OUTPUT"}}, {{BVG_STRING, OFF_WHITE, 620, 34, 38, 9, "VOLUME"}}, {{BVG_STRING, OFF_WHITE, 654, 22, 12, 9, "ON"}}, {{BVG_STRING, OFF_WHITE, 630, 345, 25, 9, "MEM"}}, {{BVG_LINE|2, OFF_WHITE, 95, 6, 95, 90}}, {{BVG_LINE|2, OFF_WHITE, 95, 175, 95, 255}}, {{BVG_LINE|2, OFF_WHITE, 95, 340, 95, 390}}, {{BVG_LINE|2, OFF_WHITE, 258, 6, 258, 390}}, {{BVG_LINE|2, OFF_WHITE, 435, 6, 435, 35}}, {{BVG_LINE|2, OFF_WHITE, 435, 86, 435, 110}}, {{BVG_LINE|2, OFF_WHITE, 435, 190, 435, 390}}, {{BVG_LINE|2, OFF_WHITE, 436, 232, 599, 232}}, {{BVG_LINE|2, OFF_WHITE, 600, 6, 600, 390}}, {{BVG_LINE, OFF_WHITE, 310, 75, 320, 75}}, {{BVG_LINE, OFF_WHITE, 310, 190, 320, 190}}, {{BVG_LINE, OFF_WHITE, 310, 303, 320, 303}}, {{BVG_LINE, OFF_WHITE, 345, 131, 360, 131}}, {{BVG_LINE, OFF_WHITE, 345, 248, 360, 248}}, {{BVG_VECT, BVG_WHITE, 29, 104, 34, 53, (char *) &pot}}, {{BVG_IMAGE, BVG_WHITE, 10, 218, 100, 100, (char *) &subMiniImage}}, {{BVG_IMAGE, BVG_WHITE, 52, 218, 100, 100, (char *) &subMiniImage}}, {{BVG_IMAGE, BVG_GREEN, 208, 46, 100, 100, (char *) &subMiniImage4}}, {{BVG_IMAGE, BVG_GREEN, 208, 161, 100, 100, (char *) &subMiniImage4}}, {{BVG_IMAGE, BVG_GREEN, 208, 276, 100, 100, (char *) &subMiniImage4}}, {{BVG_IMAGE, BVG_GREEN, 105, 46, 100, 100, (char *) &subMiniImage3}}, {{BVG_IMAGE, BVG_GREEN, 105, 163, 100, 100, (char *) &subMiniImage3}}, {{BVG_IMAGE, BVG_GREEN, 105, 276, 100, 100, (char *) &subMiniImage3}}, {{BVG_IMAGE, BVG_WHITE, 156, 149, 100, 100, (char *) &subMiniImage2}}, {{BVG_IMAGE, BVG_WHITE, 156, 260, 100, 100, (char *) &subMiniImage2}}, //{{BVG_VECT, BVG_WHITE, 156, 260, 46, 70, (char *) &pot}}, {{BVG_IMAGE, BVG_GREEN, 268, 46, 100, 100, (char *) &subMiniImage}}, {{BVG_IMAGE, BVG_GREEN, 268, 161, 100, 100, (char *) &subMiniImage}}, {{BVG_IMAGE, BVG_GREEN, 268, 276, 100, 100, (char *) &subMiniImage}}, {{BVG_IMAGE, BVG_GREEN, 370, 105, 100, 100, (char *) &subMiniImage}}, {{BVG_IMAGE, BVG_GREEN, 370, 218, 100, 100, (char *) &subMiniImage}}, {{BVG_IMAGE, BVG_GREEN, 455, 46, 100, 100, (char *) &subMiniImage}}, {{BVG_IMAGE, BVG_GREEN, 509, 46, 100, 100, (char *) &subMiniImage}}, {{BVG_IMAGE, BVG_GREEN, 559, 46, 100, 100, (char *) &subMiniImage}}, {{BVG_IMAGE, BVG_GREEN, 455, 162, 100, 100, (char *) &subMiniImage}}, {{BVG_IMAGE, BVG_GREEN, 509, 162, 100, 100, (char *) &subMiniImage}}, {{BVG_IMAGE, BVG_GREEN, 559, 162, 100, 100, (char *) &subMiniImage}}, {{BVG_IMAGE, BVG_GREEN, 455, 276, 100, 100, (char *) &subMiniImage}}, {{BVG_IMAGE, BVG_GREEN, 509, 276, 100, 100, (char *) &subMiniImage}}, {{BVG_IMAGE, BVG_GREEN, 559, 276, 100, 100, (char *) &subMiniImage}}, {{BVG_IMAGE, BVG_GREEN, 612, 47, 142, 142, (char *) &subMiniImage}}, } }; bvgImage MiniImage = { 680, 400, 0x00000000, 80, { {{BVG_STRING|2, OFF_WHITER, 5, 370, 100, 13, "CONTROLLERS"}}, {{BVG_STRING, OFF_WHITE, 36, 80, 25, 11, "TUNE"}}, {{BVG_STRING, OFF_WHITE, 44, 94, 7, 10, "O"}}, {{BVG_STRING, OFF_WHITE, 30, 157, 45, 10, "-1 1"}}, {{BVG_STRING, OFF_WHITE, 14, 195, 30, 11, "GLIDE"}}, {{BVG_STRING, OFF_WHITE, 58, 195, 24, 11, "MOD"}}, {{BVG_STRING, OFF_WHITE, 48, 284, 20, 10, "OSC"}}, {{BVG_STRING, OFF_WHITE, 72, 284, 20, 10, "NSE"}}, {{BVG_STRING, OFF_WHITE, 17, 310, 42, 10, "RELEASE"}}, {{BVG_STRING, OFF_WHITE, 27, 332, 34, 10, "MULTI"}}, {{BVG_STRING, OFF_WHITE, 86, 127, 24, 11, "MOD"}}, {{BVG_STRING, OFF_WHITE, 88, 268, 24, 11, "LFO"}}, {{BVG_STRING|2, OFF_WHITER, 120, 370, 140, 13, "OSCILLATOR BANK"}}, {{BVG_STRING, OFF_WHITE, 115, 23, 175, 11, "RANGE OSCILLATOR-1 WAVEFORM"}}, {{BVG_STRING, OFF_WHITE, 145, 123, 90, 11, "OSCILLATOR-2"}}, {{BVG_STRING, OFF_WHITE, 145, 238, 90, 11, "OSCILLATOR-3"}}, {{BVG_STRING|2, OFF_WHITER, 325, 370, 50, 13, "MIXER"}}, {{BVG_STRING, OFF_WHITE, 270, 23, 38, 11, "VOLUME"}}, {{BVG_STRING, OFF_WHITE, 365, 85, 60, 11, "EXTERNAL"}}, {{BVG_STRING, OFF_WHITE, 370, 194, 40, 11, "NOISE"}}, {{BVG_STRING, OFF_WHITE, 413, 266, 24, 9, "PINK"}}, {{BVG_STRING, OFF_WHITE, 340, 90, 12, 8, "ON"}}, {{BVG_STRING, OFF_WHITE, 340, 148, 12, 8, "ON"}}, {{BVG_STRING, OFF_WHITE, 340, 206, 12, 8, "ON"}}, {{BVG_STRING, OFF_WHITE, 340, 262, 12, 8, "ON"}}, {{BVG_STRING, OFF_WHITE, 340, 318, 12, 8, "ON"}}, {{BVG_STRING|2, OFF_WHITER, 470, 370, 100, 13, "MODIFIERS"}}, {{BVG_STRING, OFF_WHITER, 500, 6, 55, 12, "FILTER"}}, {{BVG_STRING, OFF_WHITE, 442, 23, 190, 11, "FREQUENCY EMPHASIS CONTOUR"}}, {{BVG_STRING, OFF_WHITE, 422, 46, 24, 11, "MOD"}}, {{BVG_STRING, OFF_WHITE, 422, 146, 24, 11, "KBD"}}, {{BVG_STRING, OFF_WHITE, 455, 138, 170, 9, "ATTACK DECAY SUSTAIN"}}, {{BVG_STRING, OFF_WHITE, 470, 240, 130, 11, "LOUDNESS CONTOUR"}}, {{BVG_STRING, OFF_WHITE, 455, 254, 170, 9, "ATTACK DECAY SUSTAIN"}}, {{BVG_STRING|2, OFF_WHITER, 620, 370, 55, 13, "OUTPUT"}}, {{BVG_STRING, OFF_WHITE, 620, 34, 38, 9, "VOLUME"}}, {{BVG_STRING, OFF_WHITE, 654, 22, 12, 9, "ON"}}, {{BVG_STRING, OFF_WHITE, 653, 140, 28, 11, "A440"}}, {{BVG_STRING, OFF_WHITE, 605, 175, 28, 11, "MIDI"}}, {{BVG_STRING, OFF_WHITE, 630, 345, 25, 9, "MEM"}}, {{BVG_LINE|2, OFF_WHITE, 95, 6, 95, 90}}, {{BVG_LINE|2, OFF_WHITE, 95, 175, 95, 255}}, {{BVG_LINE|2, OFF_WHITE, 95, 340, 95, 390}}, {{BVG_LINE|2, OFF_WHITE, 258, 6, 258, 390}}, {{BVG_LINE|2, OFF_WHITE, 435, 6, 435, 35}}, {{BVG_LINE|2, OFF_WHITE, 435, 86, 435, 110}}, {{BVG_LINE|2, OFF_WHITE, 435, 190, 435, 390}}, {{BVG_LINE|2, OFF_WHITE, 436, 232, 599, 232}}, {{BVG_LINE|2, OFF_WHITE, 600, 6, 600, 390}}, {{BVG_LINE, OFF_WHITE, 310, 75, 320, 75}}, {{BVG_LINE, OFF_WHITE, 310, 190, 320, 190}}, {{BVG_LINE, OFF_WHITE, 310, 303, 320, 303}}, {{BVG_LINE, OFF_WHITE, 345, 131, 360, 131}}, {{BVG_LINE, OFF_WHITE, 345, 248, 360, 248}}, {{BVG_VECT, BVG_WHITE, 29, 104, 34, 53, (char *) &pot}}, {{BVG_IMAGE, BVG_WHITE, 10, 218, 100, 100, (char *) &subMiniImage}}, {{BVG_IMAGE, BVG_WHITE, 52, 218, 100, 100, (char *) &subMiniImage}}, {{BVG_IMAGE, BVG_GREEN, 208, 46, 100, 100, (char *) &subMiniImage4}}, {{BVG_IMAGE, BVG_GREEN, 208, 161, 100, 100, (char *) &subMiniImage4}}, {{BVG_IMAGE, BVG_GREEN, 208, 276, 100, 100, (char *) &subMiniImage4}}, {{BVG_IMAGE, BVG_GREEN, 105, 46, 100, 100, (char *) &subMiniImage3}}, {{BVG_IMAGE, BVG_GREEN, 105, 163, 100, 100, (char *) &subMiniImage3}}, {{BVG_IMAGE, BVG_GREEN, 105, 276, 100, 100, (char *) &subMiniImage3}}, {{BVG_IMAGE, BVG_WHITE, 156, 149, 100, 100, (char *) &subMiniImage2}}, {{BVG_IMAGE, BVG_WHITE, 156, 260, 100, 100, (char *) &subMiniImage2}}, //{{BVG_VECT, BVG_WHITE, 156, 260, 46, 70, (char *) &pot}}, {{BVG_IMAGE, BVG_GREEN, 268, 46, 100, 100, (char *) &subMiniImage}}, {{BVG_IMAGE, BVG_GREEN, 268, 161, 100, 100, (char *) &subMiniImage}}, {{BVG_IMAGE, BVG_GREEN, 268, 276, 100, 100, (char *) &subMiniImage}}, {{BVG_IMAGE, BVG_GREEN, 370, 105, 100, 100, (char *) &subMiniImage}}, {{BVG_IMAGE, BVG_GREEN, 370, 218, 100, 100, (char *) &subMiniImage}}, {{BVG_IMAGE, BVG_GREEN, 455, 46, 100, 100, (char *) &subMiniImage}}, {{BVG_IMAGE, BVG_GREEN, 509, 46, 100, 100, (char *) &subMiniImage}}, {{BVG_IMAGE, BVG_GREEN, 559, 46, 100, 100, (char *) &subMiniImage}}, {{BVG_IMAGE, BVG_GREEN, 455, 162, 100, 100, (char *) &subMiniImage}}, {{BVG_IMAGE, BVG_GREEN, 509, 162, 100, 100, (char *) &subMiniImage}}, {{BVG_IMAGE, BVG_GREEN, 559, 162, 100, 100, (char *) &subMiniImage}}, {{BVG_IMAGE, BVG_GREEN, 455, 276, 100, 100, (char *) &subMiniImage}}, {{BVG_IMAGE, BVG_GREEN, 509, 276, 100, 100, (char *) &subMiniImage}}, {{BVG_IMAGE, BVG_GREEN, 559, 276, 100, 100, (char *) &subMiniImage}}, {{BVG_IMAGE, BVG_GREEN, 612, 47, 142, 142, (char *) &subMiniImage}}, } }; bvgImage JunoPhatImage = { 788, 244, 0x00000000, 48, { {{BVG_STRING, BVG_BLACK, 3, 19, 30, 10, "power"}}, {{BVG_STRING, BVG_BLACK, 61, 19, 25, 10, "tune"}}, {{BVG_STRING, BVG_BLACK, 92, 19, 25, 10, "hold"}}, {{BVG_STRING, OFF_WHITE, 137, 19, 70, 10, "arpeggio"}}, {{BVG_STRING, OFF_WHITE, 225, 19, 25, 10, "lfo"}}, {{BVG_STRING, OFF_WHITE, 325, 19, 28, 10, "dco"}}, {{BVG_STRING, OFF_WHITE, 420, 19, 23, 10, "hpf"}}, {{BVG_STRING, OFF_WHITE, 482, 19, 22, 10, "VCF"}}, {{BVG_STRING, OFF_WHITE, 555, 19, 22, 10, "VCA"}}, {{BVG_STRING, OFF_WHITE, 605, 19, 25, 10, "ENV"}}, {{BVG_STRING, OFF_WHITE, 648, 19, 55, 10, "chorus"}}, {{BVG_STRING, OFF_WHITE, 718, 19, 55, 10, "memory"}}, {{BVG_STRING, OFF_WHITE, 26, 50, 45, 8, "DCO VCF"}}, {{BVG_STRING, OFF_WHITE, 62, 105, 28, 8, "glide"}}, {{BVG_STRING, OFF_WHITE, 65, 150, 18, 8, "LFO"}}, {{BVG_STRING, OFF_WHITE, 87, 50, 25, 8, "Trans"}}, {{BVG_STRING, OFF_WHITE, 128, 50, 113, 8, "ON MODE RANGE RATE"}}, {{BVG_STRING, OFF_WHITE, 146, 80, 10, 8, "UP"}}, {{BVG_STRING, OFF_WHITE, 140, 160, 30, 8, "DOWN"}}, {{BVG_STRING, OFF_WHITE, 180, 100, 5, 8, "3"}}, {{BVG_STRING, OFF_WHITE, 180, 117, 5, 8, "2"}}, {{BVG_STRING, OFF_WHITE, 180, 134, 5, 8, "1"}}, {{BVG_STRING, OFF_WHITE, 210, 50, 50, 8, "Rate Delay"}}, {{BVG_STRING, OFF_WHITE, 245, 93, 15, 8, "MAN"}}, {{BVG_STRING, OFF_WHITE, 242, 145, 20, 8, "AUTO"}}, {{BVG_STRING, OFF_WHITE, 262, 50, 42, 8, "lfo pwm"}}, {{BVG_STRING, OFF_WHITE, 308, 100, 18, 8, "ENV"}}, {{BVG_STRING, OFF_WHITE, 308, 117, 18, 8, "LFO"}}, {{BVG_STRING, OFF_WHITE, 308, 134, 18, 8, "MAN"}}, {{BVG_STRING, OFF_WHITE, 378, 50, 50, 8, "sub noise"}}, {{BVG_STRING, OFF_WHITE, 420, 50, 24, 8, "freq"}}, {{BVG_STRING, OFF_WHITE, 445, 50, 45, 8, "freq res"}}, {{BVG_STRING, OFF_WHITE, 497, 50, 60, 8, "ENV LFO KBD"}}, {{BVG_STRING, OFF_WHITE, 561, 50, 25, 8, "LEVEL"}}, {{BVG_STRING, OFF_WHITE, 546, 82, 18, 8, "ENV"}}, {{BVG_STRING, OFF_WHITE, 545, 162, 21, 8, "GATE"}}, {{BVG_STRING, OFF_WHITE, 590, 50, 67, 8, "A D S R"}}, {{BVG_STRING, OFF_WHITE, 651, 50, 55, 8, "Off I II"}}, {{BVG_STRING, OFF_WHITE, 721, 190, 49, 8, "D MEM U"}}, {{BVG_VECT, OFF_WHITE, 74, 55, 6, 8, (char *) &sharp}}, {{BVG_VECT, OFF_WHITE, 64, 55, 6, 8, (char *) &flat}}, {{BVG_VECT, OFF_WHITE, 332, 82, 10, 8, (char *) &pulseWave}}, {{BVG_VECT, OFF_WHITE, 347, 82, 10, 8, (char *) &rampWave}}, {{BVG_VECT, OFF_WHITE, 362, 82, 10, 8, (char *) &squareWave}}, {{BVG_VECT, OFF_WHITE, 482, 90, 12, 8, (char *) &env}}, {{BVG_VECT, OFF_WHITE, 482, 145, 12, 8, (char *) &invenv}}, {{BVG_VECT, OFF_WHITE, 545, 96, 15, 8, (char *) &env}}, {{BVG_VECT, OFF_WHITE, 545, 147, 15, 8, (char *) &gate}}, } }; bvgImage JunoImage = { 788, 244, 0x00000000, 50, { {{BVG_STRING, BVG_BLACK, 3, 19, 30, 10, "power"}}, {{BVG_STRING, BVG_BLACK, 61, 19, 25, 10, "tune"}}, {{BVG_STRING, BVG_BLACK, 92, 19, 25, 10, "hold"}}, {{BVG_STRING, OFF_WHITE, 137, 19, 70, 10, "arpeggio"}}, {{BVG_STRING, OFF_WHITE, 225, 19, 25, 10, "lfo"}}, {{BVG_STRING, OFF_WHITE, 325, 19, 28, 10, "dco"}}, {{BVG_STRING, OFF_WHITE, 420, 19, 23, 10, "hpf"}}, {{BVG_STRING, OFF_WHITE, 482, 19, 22, 10, "VCF"}}, {{BVG_STRING, OFF_WHITE, 555, 19, 22, 10, "VCA"}}, {{BVG_STRING, OFF_WHITE, 605, 19, 25, 10, "ENV"}}, {{BVG_STRING, OFF_WHITE, 648, 19, 55, 10, "chorus"}}, {{BVG_STRING, OFF_WHITE, 718, 19, 55, 10, "memory"}}, {{BVG_STRING, OFF_WHITE, 26, 50, 45, 8, "DCO VCF"}}, {{BVG_STRING, OFF_WHITE, 62, 105, 28, 8, "glide"}}, {{BVG_STRING, OFF_WHITE, 65, 150, 18, 8, "LFO"}}, {{BVG_STRING, OFF_WHITE, 87, 50, 25, 8, "Trans"}}, {{BVG_STRING, OFF_WHITE, 128, 50, 113, 8, "ON MODE RANGE RATE"}}, {{BVG_STRING, OFF_WHITE, 146, 80, 10, 8, "UP"}}, {{BVG_STRING, OFF_WHITE, 140, 160, 30, 8, "DOWN"}}, {{BVG_STRING, OFF_WHITE, 180, 100, 5, 8, "3"}}, {{BVG_STRING, OFF_WHITE, 180, 117, 5, 8, "2"}}, {{BVG_STRING, OFF_WHITE, 180, 134, 5, 8, "1"}}, {{BVG_STRING, OFF_WHITE, 210, 50, 50, 8, "Rate Delay"}}, {{BVG_STRING, OFF_WHITE, 245, 93, 15, 8, "MAN"}}, {{BVG_STRING, OFF_WHITE, 242, 145, 20, 8, "AUTO"}}, {{BVG_STRING, OFF_WHITE, 262, 50, 42, 8, "lfo pwm"}}, {{BVG_STRING, OFF_WHITE, 308, 100, 18, 8, "ENV"}}, {{BVG_STRING, OFF_WHITE, 308, 117, 18, 8, "LFO"}}, {{BVG_STRING, OFF_WHITE, 308, 134, 18, 8, "MAN"}}, {{BVG_STRING, OFF_WHITE, 378, 50, 50, 8, "sub noise"}}, {{BVG_STRING, OFF_WHITE, 420, 50, 24, 8, "freq"}}, {{BVG_STRING, OFF_WHITE, 445, 50, 45, 8, "freq res"}}, {{BVG_STRING, OFF_WHITE, 497, 50, 60, 8, "ENV LFO KBD"}}, {{BVG_STRING, OFF_WHITE, 561, 50, 25, 8, "LEVEL"}}, {{BVG_STRING, OFF_WHITE, 546, 82, 18, 8, "ENV"}}, {{BVG_STRING, OFF_WHITE, 545, 162, 21, 8, "GATE"}}, {{BVG_STRING, OFF_WHITE, 590, 50, 67, 8, "A D S R"}}, {{BVG_STRING, OFF_WHITE, 651, 50, 55, 8, "Off I II"}}, {{BVG_STRING, OFF_WHITE, 707, 80, 90, 8, "MIDI MEMORY"}}, {{BVG_STRING, OFF_WHITE, 710, 93, 70, 8, "U D L S"}}, {{BVG_STRING, OFF_WHITE, 721, 190, 49, 8, "D MEM U"}}, {{BVG_VECT, OFF_WHITE, 74, 55, 6, 8, (char *) &sharp}}, {{BVG_VECT, OFF_WHITE, 64, 55, 6, 8, (char *) &flat}}, {{BVG_VECT, OFF_WHITE, 332, 82, 10, 8, (char *) &pulseWave}}, {{BVG_VECT, OFF_WHITE, 347, 82, 10, 8, (char *) &rampWave}}, {{BVG_VECT, OFF_WHITE, 362, 82, 10, 8, (char *) &squareWave}}, {{BVG_VECT, OFF_WHITE, 482, 90, 12, 8, (char *) &env}}, {{BVG_VECT, OFF_WHITE, 482, 145, 12, 8, (char *) &invenv}}, {{BVG_VECT, OFF_WHITE, 545, 96, 15, 8, (char *) &env}}, {{BVG_VECT, OFF_WHITE, 545, 147, 15, 8, (char *) &gate}}, /* {{BVG_LINE, BVG_BLUE, 20, 100, 10, 10}}, {{BVG_SQUARE, BVG_GREEN, 500, 40, 590, 200}}, {{BVG_LINE, BVG_BLUE, 20, 100, 10, 10}}, {{BVG_SQUARE, BVG_WHITE, 10, 20, 100, 20}}, {{BVG_IMAGE, BVG_WHITE, 10, 10, 100, 100, (char *) &myImage}}, {{BVG_VECT|0, BVG_RED, 100, 10, 30, 50, (char *) &boxTest}}, */ } }; iMap imageMap[64] = { {"/juno.xpm", &JunoImage}, {"/junophat.xpm", &JunoPhatImage}, {"/mini.xpm", &MiniImage}, {"/miniphat.xpm", &MiniPhatImage}, {"/memMoog.xpm", &MemoryMoogImage}, //{"/poly.xpm", &PolyImage}, {"/poly6.xpm", &PolyImage}, {"/sonic6.xpm", &Sonic6Image}, {"/sonic6phat.xpm", &Sonic6Image}, {"/axxe.xpm", &AxxeImage}, {"/axxephat.xpm", &AxxePhatImage}, {"/prophet.xpm", &ProphetImage}, {"/pro1.xpm", &Prophet1Image}, {"/prophet52.xpm", &Prophet52Image}, {"/BME700.xpm", &BME700Image}, {"/BME700mods.xpm", &BME700ModImage}, //{"/obxlogo.xpm", &obxLogoImage}, {"/obx.xpm", &obxImage}, {"/obxmod.xpm", &obxModImage}, {"/arp2600.xpm", &arpImage}, {"/odyssey.xpm", &odysseyImage}, {"/odyssey2.xpm", &odysseyImage}, {"/odysseymem.xpm", &odysseyMemImage}, {"", NULL}, }; bristol-0.60.11/brighton/brightonMixer.c0000644000175000017500000013422211746476475015110 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include #include "brighton.h" #include "brightonMini.h" #include "brightonKeys.h" #include "brightonMixer.h" #include "brightonMixerMemory.h" static int mixInit(); static int mixConfigure(); static int mixCallback(brightonWindow *, int, int, float); extern guimain global; extern int functionOp(guiSynth *, int, int, int, float); extern void mixerMemory(guiSynth *, int, int, int, float *); extern int loadMixerMemory(guiSynth *, char *, int); extern int setMixerMemory(mixerMem *, int, int, float *, char *); static void mixSendMsg(guiSynth *, int, int, int, int, int); /* brightonMixerMemory.c */ extern void *initMixerMemory(int count); /* * The last parameter, device count, was used to define a memory structure. * This is used by the GUI parameter changes to store the parameter values. From * here we should be able to save the structure. * * Personally I think we should define a memory structure that is overlayed * onto the array of floats that defines the actual memory space. To allow for * extensability then bussing should come first, then tracks listed from '1'. * The function section which includes master volume is not saved. */ /* * This structure is for device definition. The structure is defined in * include/brighton.h, further definitions in brighton/brightonDevtable.h and * include/brightoninternals.h * * typedef int (*brightonCallback)(int, float); * typedef struct BrightonLocations { * int device; 0=rotary, 1=scale, etc. * float relx, rely; relative position with regards to 1000 by 1000 window * float relw, relh; relative height. * int from, to; * brightonCallback callback; specific to this dev * char *image; bitmap. If zero take a device default. * int flags; * } brightonLocations; * * This example is for a mixBristol type synth interface. */ #define CD1 37 #define R1 46 #define R2 (R1 + CD1) #define R3 (R2 + CD1) #define R4 (R3 + CD1) #define R5 (R4 + CD1) #define R6 (R5 + CD1) #define R7 (R6 + CD1) #define R8 (R7 + CD1) #define R9 (R8 + CD1) #define R10 (R9 + CD1) #define R11 (R10 + CD1) #define R12 (R11 + CD1) #define R13 (R12 + CD1) #define R14 (R13 + CD1) #define R15 (R14 + CD1) #define R16 (R15 + CD1) #define R17 (R16 + CD1) #define R18 (R17 + CD1) #define RSL 741 #define RTX (RSL + 50) #define D1 180 #define C0 120 #define C1 275 #define C2 100 #define C3 600 #define C4 350 #define C5 75 #define C6 400 #define C7 725 #define C8 30 #define C9 275 #define C10 525 #define C11 760 #define C12 770 #define S1 450 #define S2 40 #define SB3 225 #define SB4 11 #define SB5 20 #define SB6 200 #define SB7 9 #define BH 10 #define BH1 9 #define BB1 2 #define BB2 (BB1 + BH) #define BB3 (BB2 + BH) #define BB4 (BB3 + BH) #define BBR1 685 #define BBR2 (BBR1 + BH) #define BBR3 (BBR2 + BH) #define BBR4 (BBR3 + BH) #define BBR5 (BBR4 + BH) /* * This should be organised such that continuous controllers are located first, * then buttons? The benefits of such an organisation is that the continuous * controllers are likely to be extended, and the button groups tend to be * exclusive, so whilst we have 16 IO selectors, for example, these are only * represented by one parameter, the channel number. */ static brightonLocations locations[MEM_COUNT] = { /* * Input channel select buttons */ {"", 2, C8, BB1, SB3, SB4, 0, 1.01, 0, "bitmaps/buttons/pressoffS.xpm", "bitmaps/buttons/pressonS.xpm", BRIGHTON_NOSHADOW}, {"", 2, C9, BB1, SB3, SB4, 0, 1.01, 0, "bitmaps/buttons/pressoffS.xpm", "bitmaps/buttons/pressonS.xpm", BRIGHTON_NOSHADOW}, {"", 2, C10, BB1, SB3, SB4, 0, 1.01, 0, "bitmaps/buttons/pressoffS.xpm", "bitmaps/buttons/pressonS.xpm", BRIGHTON_NOSHADOW}, {"", 2, C11, BB1, SB3, SB4, 0, 1.01, 0, "bitmaps/buttons/pressoffS.xpm", "bitmaps/buttons/pressonS.xpm", BRIGHTON_NOSHADOW}, {"", 2, C8, BB2, SB3, SB4, 0, 1.01, 0, "bitmaps/buttons/pressoffS.xpm", "bitmaps/buttons/pressonS.xpm", BRIGHTON_NOSHADOW}, {"", 2, C9, BB2, SB3, SB4, 0, 1.01, 0, "bitmaps/buttons/pressoffS.xpm", "bitmaps/buttons/pressonS.xpm", BRIGHTON_NOSHADOW}, {"", 2, C10, BB2, SB3, SB4, 0, 1.01, 0, "bitmaps/buttons/pressoffS.xpm", "bitmaps/buttons/pressonS.xpm", BRIGHTON_NOSHADOW}, {"", 2, C11, BB2, SB3, SB4, 0, 1.01, 0, "bitmaps/buttons/pressoffS.xpm", "bitmaps/buttons/pressonS.xpm", BRIGHTON_NOSHADOW}, {"", 2, C8, BB3, SB3, SB4, 0, 1.01, 0, "bitmaps/buttons/pressoffS.xpm", "bitmaps/buttons/pressonS.xpm", BRIGHTON_NOSHADOW}, {"", 2, C9, BB3, SB3, SB4, 0, 1.01, 0, "bitmaps/buttons/pressoffS.xpm", "bitmaps/buttons/pressonS.xpm", BRIGHTON_NOSHADOW}, {"", 2, C10, BB3, SB3, SB4, 0, 1.01, 0, "bitmaps/buttons/pressoffS.xpm", "bitmaps/buttons/pressonS.xpm", BRIGHTON_NOSHADOW}, {"", 2, C11, BB3, SB3, SB4, 0, 1.01, 0, "bitmaps/buttons/pressoffS.xpm", "bitmaps/buttons/pressonS.xpm", BRIGHTON_NOSHADOW}, {"", 2, C8, BB4, SB3, SB4, 0, 1.01, 0, "bitmaps/buttons/pressoffS.xpm", "bitmaps/buttons/pressonS.xpm", BRIGHTON_NOSHADOW}, {"", 2, C9, BB4, SB3, SB4, 0, 1.01, 0, "bitmaps/buttons/pressoffS.xpm", "bitmaps/buttons/pressonS.xpm", BRIGHTON_NOSHADOW}, {"", 2, C10, BB4, SB3, SB4, 0, 1.01, 0, "bitmaps/buttons/pressoffS.xpm", "bitmaps/buttons/pressonS.xpm", BRIGHTON_NOSHADOW}, {"", 2, C11, BB4, SB3, SB4, 0, 1.01, 0, "bitmaps/buttons/pressoffS.xpm", "bitmaps/buttons/pressonS.xpm", BRIGHTON_NOSHADOW}, /* * presend select */ {"", 2, C12, R2, SB3, SB7, 0, 1.01, 0, "bitmaps/buttons/pressoffSy.xpm", "bitmaps/buttons/pressonSy.xpm", BRIGHTON_NOSHADOW}, {"", 2, C12, R2 + 10, SB3, SB7, 0, 1.01, 0, "bitmaps/buttons/pressoffSy.xpm", "bitmaps/buttons/pressonSy.xpm", BRIGHTON_NOSHADOW}, {"", 2, C12, R2 + 19, SB3, SB7, 0, 1.01, 0, "bitmaps/buttons/pressoffSy.xpm", "bitmaps/buttons/pressonSy.xpm", BRIGHTON_NOSHADOW}, {"", 2, C12, R2 + 29, SB3, SB7, 0, 1.01, 0, "bitmaps/buttons/pressoffSy.xpm", "bitmaps/buttons/pressonSy.xpm", BRIGHTON_NOSHADOW}, /* * Dynamics select {"", 2, C12, R3, SB3, SB7, 0, 1.01, 0, "bitmaps/buttons/pressoffSg.xpm", "bitmaps/buttons/pressonSg.xpm", BRIGHTON_NOSHADOW}, */ {"", 2, C12, R5 + 0, SB3, SB7, 0, 1.01, 0, "bitmaps/buttons/pressoffSg.xpm", "bitmaps/buttons/pressonSg.xpm", BRIGHTON_NOSHADOW}, {"", 2, C12, R5 + 10, SB3, SB7, 0, 1.01, 0, "bitmaps/buttons/pressoffSg.xpm", "bitmaps/buttons/pressonSg.xpm", BRIGHTON_NOSHADOW}, {"", 2, C12, R5 + 20, SB3, SB7, 0, 1.01, 0, "bitmaps/buttons/pressoffSg.xpm", "bitmaps/buttons/pressonSg.xpm", BRIGHTON_NOSHADOW}, /* * Filter select */ {"", 2, C12, R10 + 1, SB3, SB7, 0, 1.01, 0, "bitmaps/buttons/pressoffSg.xpm", "bitmaps/buttons/pressonSg.xpm", BRIGHTON_NOSHADOW}, {"", 2, C12, R10 + 11, SB3, SB7, 0, 1.01, 0, "bitmaps/buttons/pressoffSg.xpm", "bitmaps/buttons/pressonSg.xpm", BRIGHTON_NOSHADOW}, {"", 2, C12, R10 + 21, SB3, SB7, 0, 1.01, 0, "bitmaps/buttons/pressoffSg.xpm", "bitmaps/buttons/pressonSg.xpm", BRIGHTON_NOSHADOW}, {"", 2, C12, R10 + 31, SB3, SB7, 0, 1.01, 0, "bitmaps/buttons/pressoffSg.xpm", "bitmaps/buttons/pressonSg.xpm", BRIGHTON_NOSHADOW}, /* * postsend select */ {"", 2, C12, R13 + 0, SB3, SB7, 0, 1.01, 0, "bitmaps/buttons/pressoffSy.xpm", "bitmaps/buttons/pressonSy.xpm", BRIGHTON_NOSHADOW}, {"", 2, C12, R13 + 9, SB3, SB7, 0, 1.01, 0, "bitmaps/buttons/pressoffSy.xpm", "bitmaps/buttons/pressonSy.xpm", BRIGHTON_NOSHADOW}, {"", 2, C12, R13 + 19, SB3, SB7, 0, 1.01, 0, "bitmaps/buttons/pressoffSy.xpm", "bitmaps/buttons/pressonSy.xpm", BRIGHTON_NOSHADOW}, {"", 2, C12, R13 + 29, SB3, SB7, 0, 1.01, 0, "bitmaps/buttons/pressoffSy.xpm", "bitmaps/buttons/pressonSy.xpm", BRIGHTON_NOSHADOW}, /* * Effects select: reverb, echo, chorus, flanger, tremelo, vibrato, delay */ {"", 2, C12, R14 + 6, SB3, SB7, 0, 1.01, 0, "bitmaps/buttons/pressoffSg.xpm", "bitmaps/buttons/pressonSg.xpm", BRIGHTON_NOSHADOW}, {"", 2, C12, R14 + 16, SB3, SB7, 0, 1.01, 0, "bitmaps/buttons/pressoffSg.xpm", "bitmaps/buttons/pressonSg.xpm", BRIGHTON_NOSHADOW}, {"", 2, C12, R14 + 26, SB3, SB7, 0, 1.01, 0, "bitmaps/buttons/pressoffSg.xpm", "bitmaps/buttons/pressonSg.xpm", BRIGHTON_NOSHADOW}, {"", 2, C12, R14 + 35, SB3, SB7, 0, 1.01, 0, "bitmaps/buttons/pressoffSg.xpm", "bitmaps/buttons/pressonSg.xpm", BRIGHTON_NOSHADOW}, {"", 2, C12, R14 + 45, SB3, SB7, 0, 1.01, 0, "bitmaps/buttons/pressoffSg.xpm", "bitmaps/buttons/pressonSg.xpm", BRIGHTON_NOSHADOW}, {"", 2, C12, R14 + 55, SB3, SB7, 0, 1.01, 0, "bitmaps/buttons/pressoffSg.xpm", "bitmaps/buttons/pressonSg.xpm", BRIGHTON_NOSHADOW}, {"", 2, C12, R14 + 65, SB3, SB7, 0, 1.01, 0, "bitmaps/buttons/pressoffSg.xpm", "bitmaps/buttons/pressonSg.xpm", BRIGHTON_NOSHADOW}, {"", 0, C1, R1, S1, S2, 0, 1, 0, "bitmaps/knobs/knobred.xpm", 0, 0}, {"", 0, C0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knobyellow.xpm", 0, 0}, {"", 0, C0, R3, S1, S2, 0, 1, 0, "bitmaps/knobs/knob.xpm", 0, 0}, {"", 0, C0, R4, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", 0, 0}, {"", 0, C0, R5, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", 0, 0}, {"", 0, C0, R6, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", 0, 0}, {"", 0, C0, R7, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", 0, 0}, {"", 0, C0, R8, S1, S2, 0, 1, 0, "bitmaps/knobs/knobgreen.xpm", 0, 0}, {"", 0, C0, R9, S1, S2, 0, 1, 0, "bitmaps/knobs/knobgreen.xpm", 0, 0}, {"", 0, C0, R10, S1, S2, 0, 1, 0, "bitmaps/knobs/knob.xpm", 0, 0}, {"", 0, C0, R11, S1, S2, 0, 1, 0, "bitmaps/knobs/knobgreen.xpm", 0, 0}, {"", 0, C0, R12, S1, S2, 0, 1, 0, "bitmaps/knobs/knobgreen.xpm", 0, 0}, {"", 0, C0, R13, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", 0, 0}, {"", 0, C0, R14, S1, S2, 0, 1, 0, "bitmaps/knobs/knoborange.xpm", 0, 0}, {"", 0, C0, R15, S1, S2, 0, 1, 0, "bitmaps/knobs/knoborange.xpm", 0, 0}, {"", 0, C0, R16, S1, S2, 0, 1, 0, "bitmaps/knobs/knoborange.xpm", 0, 0}, {"", 0, C1, R17, S1, S2, 0, 1, 0, "bitmaps/knobs/knobyellow.xpm", 0, BRIGHTON_NOTCH}, /* * Mute/Solo/Boost */ {"", 2, C5, R18, SB3, SB4, 0, 1.01, 0, "bitmaps/buttons/pressoffS.xpm", "bitmaps/buttons/pressonS.xpm", BRIGHTON_NOSHADOW}, {"", 2, C6, R18, SB3, SB4, 0, 1.01, 0, "bitmaps/buttons/pressoffS.xpm", "bitmaps/buttons/pressonS.xpm", BRIGHTON_NOSHADOW}, {"", 2, C7, R18, SB3, SB4, 0, 1.01, 0, "bitmaps/buttons/pressoffS.xpm", "bitmaps/buttons/pressonS.xpm", BRIGHTON_NOSHADOW}, /* * Output channel select buttons */ {"", 2, C8, BBR1, SB3, SB4, 0, 1.01, 0, "bitmaps/buttons/pressoffSg.xpm", "bitmaps/buttons/pressonSg.xpm", BRIGHTON_NOSHADOW}, {"", 2, C9, BBR1, SB3, SB4, 0, 1.01, 0, "bitmaps/buttons/pressoffSg.xpm", "bitmaps/buttons/pressonSg.xpm", BRIGHTON_NOSHADOW}, {"", 2, C10, BBR1, SB3, SB4, 0, 1.01, 0, "bitmaps/buttons/pressoffSg.xpm", "bitmaps/buttons/pressonSg.xpm", BRIGHTON_NOSHADOW}, {"", 2, C11, BBR1, SB3, SB4, 0, 1.01, 0, "bitmaps/buttons/pressoffSg.xpm", "bitmaps/buttons/pressonSg.xpm", BRIGHTON_NOSHADOW}, {"", 2, C8, BBR2, SB3, SB4, 0, 1.01, 0, "bitmaps/buttons/pressoffSg.xpm", "bitmaps/buttons/pressonSg.xpm", BRIGHTON_NOSHADOW}, {"", 2, C9, BBR2, SB3, SB4, 0, 1.01, 0, "bitmaps/buttons/pressoffSg.xpm", "bitmaps/buttons/pressonSg.xpm", BRIGHTON_NOSHADOW}, {"", 2, C10, BBR2, SB3, SB4, 0, 1.01, 0, "bitmaps/buttons/pressoffSg.xpm", "bitmaps/buttons/pressonSg.xpm", BRIGHTON_NOSHADOW}, {"", 2, C11, BBR2, SB3, SB4, 0, 1.01, 0, "bitmaps/buttons/pressoffSg.xpm", "bitmaps/buttons/pressonSg.xpm", BRIGHTON_NOSHADOW}, {"", 2, C8, BBR3, SB3, SB4, 0, 1.01, 0, "bitmaps/buttons/pressoffSg.xpm", "bitmaps/buttons/pressonSg.xpm", BRIGHTON_NOSHADOW}, {"", 2, C9, BBR3, SB3, SB4, 0, 1.01, 0, "bitmaps/buttons/pressoffSg.xpm", "bitmaps/buttons/pressonSg.xpm", BRIGHTON_NOSHADOW}, {"", 2, C10, BBR3, SB3, SB4, 0, 1.01, 0, "bitmaps/buttons/pressoffSg.xpm", "bitmaps/buttons/pressonSg.xpm", BRIGHTON_NOSHADOW}, {"", 2, C11, BBR3, SB3, SB4, 0, 1.01, 0, "bitmaps/buttons/pressoffSg.xpm", "bitmaps/buttons/pressonSg.xpm", BRIGHTON_NOSHADOW}, {"", 2, C8, BBR4, SB3, SB4, 0, 1.01, 0, "bitmaps/buttons/pressoffSg.xpm", "bitmaps/buttons/pressonSg.xpm", BRIGHTON_NOSHADOW}, {"", 2, C9, BBR4, SB3, SB4, 0, 1.01, 0, "bitmaps/buttons/pressoffSg.xpm", "bitmaps/buttons/pressonSg.xpm", BRIGHTON_NOSHADOW}, {"", 2, C10, BBR4, SB3, SB4, 0, 1.01, 0, "bitmaps/buttons/pressoffSg.xpm", "bitmaps/buttons/pressonSg.xpm", BRIGHTON_NOSHADOW}, {"", 2, C11, BBR4, SB3, SB4, 0, 1.01, 0, "bitmaps/buttons/pressoffSg.xpm", "bitmaps/buttons/pressonSg.xpm", BRIGHTON_NOSHADOW}, /* * Bus select buttons */ {"", 2, C8, BBR5, SB3, SB4, 0, 1.01, 0, "bitmaps/buttons/pressoffSb.xpm", "bitmaps/buttons/pressonSb.xpm", BRIGHTON_NOSHADOW}, {"", 2, C9, BBR5, SB3, SB4, 0, 1.01, 0, "bitmaps/buttons/pressoffSb.xpm", "bitmaps/buttons/pressonSb.xpm", BRIGHTON_NOSHADOW}, {"", 2, C10, BBR5, SB3, SB4, 0, 1.01, 0, "bitmaps/buttons/pressoffSb.xpm", "bitmaps/buttons/pressonSb.xpm", BRIGHTON_NOSHADOW}, {"", 2, C11, BBR5, SB3, SB4, 0, 1.01, 0, "bitmaps/buttons/pressoffSb.xpm", "bitmaps/buttons/pressonSb.xpm", BRIGHTON_NOSHADOW}, {"", 1, C4 - 25, RSL, 360, 226, 0, 1, 0, "bitmaps/knobs/sliderblack2.xpm", 0, 0}, /* Finally the display. This is the 80th location (0..79). */ {"", 3, 0, 977, 1000, 13, 0, 1, 0, "bitmaps/digits/display2.xpm", 0, 0} }; #define BS1 80 #define BS2 70 #define BRD1 100 #define BRD2 72 #define BR1 11 #define BR2 (BR1 + BRD2) #define BR3 (BR2 + BRD2) #define BR4 (BR3 + BRD2) #define BR5 (BR4 + BRD2) #define BR6 (BR5 + BRD2) #define BR7 (BR6 + BRD2) #define BR8 (BR7 + BRD2) #define BR9 (BR8 + BRD2) #define BR10 (BR9 + BRD2) #define BCD1 100 #define BCD2 125 #define BC1 35 #define BC2 200 #define BC3 350 #define BC4 550 #define BC5 700 #define BC6 850 #define BC7 (BC1 + BCD2) #define BC8 (BC7 + BCD2) #define BC9 (BC8 + BCD2) #define BC10 (BC9 + BCD2) #define BC11 (BC10 + BCD2) #define BC12 (BC11 + BCD2) #define BC13 (BC12 + BCD2) #define FRS1 125 #define FBC0 5 #define FBC1 (115) #define FBC2 (FBC1 + FRS1) #define FBC3 (FBC2 + FRS1) #define FBC4 (FBC3 + FRS1) #define FBC5 (FBC4 + FRS1) #define FBC6 (FBC5 + FRS1) #define FBC7 860 #define FBW1 35 #define FBW2 32 #define FBH1 13 #define FBS1 70 /* * One effect - FX select, some params, output channels selection. */ #define FXBUS(off) \ {"", 0, FBC1, off, FBS1, FBS1, 0, 1, 0, \ "bitmaps/knobs/knobgreen.xpm", 0, 0}, \ {"", 0, FBC2, off, FBS1, FBS1, 0, 1, 0, \ "bitmaps/knobs/knoborange.xpm", 0, 0}, \ {"", 0, FBC3, off, FBS1, FBS1, 0, 1, 0, \ "bitmaps/knobs/knoborange.xpm", 0, 0}, \ {"", 0, FBC4, off, FBS1, FBS1, 0, 1, 0, \ "bitmaps/knobs/knoborange.xpm", 0, 0}, \ {"", 0, FBC5, off, FBS1, FBS1, 0, 1, 0, \ "bitmaps/knobs/knobyellow.xpm", 0, BRIGHTON_NOTCH}, \ {"", 0, FBC6, off, FBS1, FBS1, 0, 1, 0, \ "bitmaps/knobs/knobred.xpm", 0, 0}, \ {"", 2, FBC0, off + 0, FBW1, FBH1, 0, 1.01, 0, \ "bitmaps/buttons/pressoffSy.xpm", "bitmaps/buttons/pressonSy.xpm", BRIGHTON_NOSHADOW}, \ {"", 2, FBC0, off + 13, FBW1, FBH1, 0, 1.01, 0, \ "bitmaps/buttons/pressoffSy.xpm", "bitmaps/buttons/pressonSy.xpm", BRIGHTON_NOSHADOW}, \ {"", 2, FBC0, off + 26, FBW1, FBH1, 0, 1.01, 0, \ "bitmaps/buttons/pressoffSy.xpm", "bitmaps/buttons/pressonSy.xpm", BRIGHTON_NOSHADOW}, \ {"", 2, FBC0, off + 39, FBW1, FBH1, 0, 1.01, 0, \ "bitmaps/buttons/pressoffSy.xpm", "bitmaps/buttons/pressonSy.xpm", BRIGHTON_NOSHADOW}, \ {"", 2, FBC0 + FBW1 + 5, off + 0, FBW1, FBH1, 0, 1.01, 0, \ "bitmaps/buttons/pressoffSy.xpm", "bitmaps/buttons/pressonSy.xpm", BRIGHTON_NOSHADOW}, \ {"", 2, FBC0 + FBW1 + 5, off + 13, FBW1, FBH1, 0, 1.01, 0, \ "bitmaps/buttons/pressoffSy.xpm", "bitmaps/buttons/pressonSy.xpm", BRIGHTON_NOSHADOW}, \ {"", 2, FBC0 + FBW1 + 5, off + 26, FBW1, FBH1, 0, 1.01, 0, \ "bitmaps/buttons/pressoffSy.xpm", "bitmaps/buttons/pressonSy.xpm", BRIGHTON_NOSHADOW}, \ {"", 2, FBC0 + FBW1 + 5, off + 39, FBW1, FBH1, 0, 1.01, 0, \ "bitmaps/buttons/pressoffSy.xpm", "bitmaps/buttons/pressonSy.xpm", BRIGHTON_NOSHADOW}, \ \ {"", 2, FBC7 + FBW1 * 0 + 3, off + 0, FBW2, FBH1, 0, 1.01, 0, \ "bitmaps/buttons/pressoffSg.xpm", "bitmaps/buttons/pressonSg.xpm", BRIGHTON_NOSHADOW}, \ {"", 2, FBC7 + FBW1 * 1 + 1, off + 0, FBW2, FBH1, 0, 1.01, 0, \ "bitmaps/buttons/pressoffSg.xpm", "bitmaps/buttons/pressonSg.xpm", BRIGHTON_NOSHADOW}, \ {"", 2, FBC7 + FBW1 * 2, off + 0, FBW2, FBH1, 0, 1.01, 0, \ "bitmaps/buttons/pressoffSg.xpm", "bitmaps/buttons/pressonSg.xpm", BRIGHTON_NOSHADOW}, \ {"", 2, FBC7 + FBW1 * 3, off + 0, FBW2, FBH1, 0, 1.01, 0, \ "bitmaps/buttons/pressoffSg.xpm", "bitmaps/buttons/pressonSg.xpm", BRIGHTON_NOSHADOW}, \ {"", 2, FBC7 + FBW1 * 0 + 3, off + 13, FBW2, FBH1, 0, 1.01, 0, \ "bitmaps/buttons/pressoffSg.xpm", "bitmaps/buttons/pressonSg.xpm", BRIGHTON_NOSHADOW}, \ {"", 2, FBC7 + FBW1 * 1 + 1, off + 13, FBW2, FBH1, 0, 1.01, 0, \ "bitmaps/buttons/pressoffSg.xpm", "bitmaps/buttons/pressonSg.xpm", BRIGHTON_NOSHADOW}, \ {"", 2, FBC7 + FBW1 * 2, off + 13, FBW2, FBH1, 0, 1.01, 0, \ "bitmaps/buttons/pressoffSg.xpm", "bitmaps/buttons/pressonSg.xpm", BRIGHTON_NOSHADOW}, \ {"", 2, FBC7 + FBW1 * 3, off + 13, FBW2, FBH1, 0, 1.01, 0, \ "bitmaps/buttons/pressoffSg.xpm", "bitmaps/buttons/pressonSg.xpm", BRIGHTON_NOSHADOW}, \ {"", 2, FBC7 + FBW1 * 0 + 3, off + 26, FBW2, FBH1, 0, 1.01, 0, \ "bitmaps/buttons/pressoffSg.xpm", "bitmaps/buttons/pressonSg.xpm", BRIGHTON_NOSHADOW}, \ {"", 2, FBC7 + FBW1 * 1 + 1, off + 26, FBW2, FBH1, 0, 1.01, 0, \ "bitmaps/buttons/pressoffSg.xpm", "bitmaps/buttons/pressonSg.xpm", BRIGHTON_NOSHADOW}, \ {"", 2, FBC7 + FBW1 * 2, off + 26, FBW2, FBH1, 0, 1.01, 0, \ "bitmaps/buttons/pressoffSg.xpm", "bitmaps/buttons/pressonSg.xpm", BRIGHTON_NOSHADOW}, \ {"", 2, FBC7 + FBW1 * 3, off + 26, FBW2, FBH1, 0, 1.01, 0, \ "bitmaps/buttons/pressoffSg.xpm", "bitmaps/buttons/pressonSg.xpm", BRIGHTON_NOSHADOW}, \ {"", 2, FBC7 + FBW1 * 0 + 3, off + 39, FBW2, FBH1, 0, 1.01, 0, \ "bitmaps/buttons/pressoffSg.xpm", "bitmaps/buttons/pressonSg.xpm", BRIGHTON_NOSHADOW}, \ {"", 2, FBC7 + FBW1 * 1 + 1, off + 39, FBW2, FBH1, 0, 1.01, 0, \ "bitmaps/buttons/pressoffSg.xpm", "bitmaps/buttons/pressonSg.xpm", BRIGHTON_NOSHADOW}, \ {"", 2, FBC7 + FBW1 * 2, off + 39, FBW2, FBH1, 0, 1.01, 0, \ "bitmaps/buttons/pressoffSg.xpm", "bitmaps/buttons/pressonSg.xpm", BRIGHTON_NOSHADOW}, \ {"", 2, FBC7 + FBW1 * 3, off + 39, FBW2, FBH1, 0, 1.01, 0, \ "bitmaps/buttons/pressoffSg.xpm", "bitmaps/buttons/pressonSg.xpm", BRIGHTON_NOSHADOW} /*16 = 30 */ /* FX Bus definitions: */ static brightonLocations busses[BUS_COUNT] = { /* Bus groups */ FXBUS(BR1), FXBUS(BR2), FXBUS(BR3), FXBUS(BR4), FXBUS(BR5), FXBUS(BR6), FXBUS(BR7), FXBUS(BR8), /* 40 * 8 = 320 */ #define BSL 299 {"", 0, BC1 + 40, BR9, BS1, BS2, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, BRIGHTON_NOTCH}, {"", 1, BC1, BR10, 55, BSL, 0, 1, 0, "bitmaps/knobs/sliderblack2.xpm", 0, 0}, {"", 1, BC7, BR10, 55, BSL, 0, 1, 0, "bitmaps/knobs/sliderblack2.xpm", 0, 0}, {"", 0, BC8 + 40, BR9, BS1, BS2, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, BRIGHTON_NOTCH}, {"", 1, BC8, BR10, 55, BSL, 0, 1, 0, "bitmaps/knobs/sliderblack2.xpm", 0, 0}, {"", 1, BC9, BR10, 55, BSL, 0, 1, 0, "bitmaps/knobs/sliderblack2.xpm", 0, 0}, {"", 0, BC10 + 40, BR9, BS1, BS2, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, BRIGHTON_NOTCH}, {"", 1, BC10, BR10, 55, BSL, 0, 1, 0, "bitmaps/knobs/sliderblack2.xpm", 0, 0}, {"", 1, BC11, BR10, 55, BSL, 0, 1, 0, "bitmaps/knobs/sliderblack2.xpm", 0, 0}, {"", 0, BC12 + 40, BR9, BS1, BS2, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, BRIGHTON_NOTCH}, {"", 1, BC12, BR10, 55, BSL, 0, 1, 0, "bitmaps/knobs/sliderblack2.xpm", 0, 0}, {"", 1, BC13, BR10, 55, BSL, 0, 1, 0, "bitmaps/knobs/sliderblack2.xpm", 0, 0}, /* total = 12 + 320 = 332 */ }; #define MC1 150 #define MC2 200 #define MC3 650 #define MS1 240 /* Don't think we pack this? static brightonLocations master[MASTER_COUNT] = { {"", 0, MC2, BR8, 600, 600, 0, 1, 0, 0, 0, 0}, {"", 1, MC1 + 50, BR10, 130, BSL, 0, 1, 0, "bitmaps/knobs/sliderblack2.xpm", 0, 0}, {"", 1, MC3, BR10, 130, BSL, 0, 1, 0, "bitmaps/knobs/sliderblack2.xpm", 0, 0}, {"", 0, MC1, BR1, MS1, MS1, 0, 1, 0, "bitmaps/knobs/knob.xpm", 0, 0}, {"", 0, MC1, BR2, MS1, MS1, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", 0, 0}, {"", 0, MC1, BR3, MS1, MS1, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", 0, 0}, {"", 0, MC1, BR4, MS1, MS1, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", 0, 0}, {"", 0, MC1, BR5, MS1, MS1, 0, 1, 0, "bitmaps/knobs/knobgreen.xpm", 0, 0}, {"", 0, MC1, BR6, MS1, MS1, 0, 1, 0, "bitmaps/knobs/knobgreen.xpm", 0, 0}, {"", 0, MC1, BR7, MS1, MS1, 0, 1, 0, "bitmaps/knobs/knobgreen.xpm", 0, 0}, {"", 0, MC3, BR1, MS1, MS1, 0, 1, 0, "bitmaps/knobs/knob.xpm", 0, 0}, {"", 0, MC3, BR2, MS1, MS1, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", 0, 0}, {"", 0, MC3, BR3, MS1, MS1, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", 0, 0}, {"", 0, MC3, BR4, MS1, MS1, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", 0, 0}, {"", 0, MC3, BR5, MS1, MS1, 0, 1, 0, "bitmaps/knobs/knobgreen.xpm", 0, 0}, {"", 0, MC3, BR6, MS1, MS1, 0, 1, 0, "bitmaps/knobs/knobgreen.xpm", 0, 0}, {"", 0, MC3, BR7, MS1, MS1, 0, 1, 0, "bitmaps/knobs/knobgreen.xpm", 0, 0}, }; */ #define FD1 8 #define FD2 67 #define FD3 120 #define FPS1 83 #define FPS2 650 #define FPS3 875 #define FR1 25 #define FR2 (FR1 + FPS1 * 5) #define FR3 (FR2 + FPS1 - FD1) #define FR4 (FR3 + FPS1 - FD1) #define FR5 (FR4 + FPS1 - FD1) #define FR6 (FR5 + FPS1 - FD1) #define FR7 (FR6 + FPS1 - FD1) #define FR8 (FR7 + FPS1 + FD1) #define FR10 (FR10 + 120) #define FC1 10 #define FC2 (FC1 + FC1 + FD2) #define FC3 (FC2 + FD2) #define FC4 (FC3 + FD2) #define FC5 (FC4 + FD2) #define FC6 (FC5 + FD2) #define FC7 (FC6 + FD2) #define FC8 (FC7 + FD2) #define FC9 (FC8 + FD2) #define FC10 (FC9 + FD2) #define FC11 (FC10 + FD2) #define FC12 (FC11 + FD2) #define FC13 (FC12 + FD2) #define FC14 (FC13 + FD2) #define FC15 (FC14 + FD2 - 5) #define DISPLAY1 (FUNCTION_COUNT - 6) #define DISPLAY2 (FUNCTION_COUNT - 5) #define DISPLAY3 (FUNCTION_COUNT - 4) #define DISPLAY4 (FUNCTION_COUNT - 3) #define DISPLAY5 (FUNCTION_COUNT - 2) #define DISPLAY6 (FUNCTION_COUNT - 1) #define FBBW 47 #define FBBH 70 /* * Display and memory select buttons. * Should memory selection be panel operation */ static brightonLocations functions[FUNCTION_COUNT] = { /* Master gain */ {"", 0, 750, 75, 250, 250, 0, 1, 0, 0, 0, 0}, /* Page left and right */ {"", 2, FC1, FR2 - 5, FBBW, FBBH, 0, 1.01, 0, "bitmaps/buttons/touchnlb.xpm", "bitmaps/buttons/touchnlb.xpm", BRIGHTON_NOSHADOW}, {"", 2, FC15, FR2 - 5, FBBW, FBBH, 0, 1.01, 0, "bitmaps/buttons/touchnrb.xpm", "bitmaps/buttons/touchnrb.xpm", BRIGHTON_NOSHADOW}, /* left functions */ {"", 2, FC1, FR3, FBBW, FBBH, 0, 1.01, 0, "bitmaps/buttons/touchnrb.xpm", "bitmaps/buttons/touchnrb.xpm", BRIGHTON_NOSHADOW}, {"", 2, FC1, FR4, FBBW, FBBH, 0, 1.01, 0, "bitmaps/buttons/touchnrb.xpm", "bitmaps/buttons/touchnrb.xpm", BRIGHTON_NOSHADOW}, {"", 2, FC1, FR5, FBBW, FBBH, 0, 1.01, 0, "bitmaps/buttons/touchnrb.xpm", "bitmaps/buttons/touchnrb.xpm", BRIGHTON_NOSHADOW}, {"", 2, FC1, FR6, FBBW, FBBH, 0, 1.01, 0, "bitmaps/buttons/touchnrb.xpm", "bitmaps/buttons/touchnrb.xpm", BRIGHTON_NOSHADOW}, {"", 2, FC1, FR7, FBBW, FBBH, 0, 1.01, 0, "bitmaps/buttons/touchnrb.xpm", "bitmaps/buttons/touchnrb.xpm", BRIGHTON_NOSHADOW}, /* right functions */ {"", 2, FC15, FR3, FBBW, FBBH, 0, 1.01, 0, "bitmaps/buttons/touchnlb.xpm", "bitmaps/buttons/touchnlb.xpm", BRIGHTON_NOSHADOW}, {"", 2, FC15, FR4, FBBW, FBBH, 0, 1.01, 0, "bitmaps/buttons/touchnlb.xpm", "bitmaps/buttons/touchnlb.xpm", BRIGHTON_NOSHADOW}, {"", 2, FC15, FR5, FBBW, FBBH, 0, 1.01, 0, "bitmaps/buttons/touchnlb.xpm", "bitmaps/buttons/touchnlb.xpm", BRIGHTON_NOSHADOW}, {"", 2, FC15, FR6, FBBW, FBBH, 0, 1.01, 0, "bitmaps/buttons/touchnlb.xpm", "bitmaps/buttons/touchnlb.xpm", BRIGHTON_NOSHADOW}, {"", 2, FC15, FR7, FBBW, FBBH, 0, 1.01, 0, "bitmaps/buttons/touchnlb.xpm", "bitmaps/buttons/touchnlb.xpm", BRIGHTON_NOSHADOW}, /* * Some more buttons for base, 0-9, up/down, etc. * * First the load function */ {"", 2, FC1, FR8, 40, 75, 0, 1.01, 0, "bitmaps/buttons/pressoffo.xpm", "bitmaps/buttons/pressono.xpm", BRIGHTON_CHECKBUTTON}, /* 0 to nine */ {"", 2, FC3, FR8, 40, 75, 0, 1.01, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, FC4, FR8, 40, 75, 0, 1.01, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, FC5, FR8, 40, 75, 0, 1.01, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, FC6, FR8, 40, 75, 0, 1.01, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, FC7, FR8, 40, 75, 0, 1.01, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, FC8, FR8, 40, 75, 0, 1.01, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, FC9, FR8, 40, 75, 0, 1.01, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, FC10, FR8, 40, 75, 0, 1.01, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, FC11, FR8, 40, 75, 0, 1.01, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, FC12, FR8, 40, 75, 0, 1.01, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, /* Memory load/save */ {"", 2, FC14, FR8, 40, 75, 0, 1.01, 0, "bitmaps/buttons/pressoffo.xpm", "bitmaps/buttons/pressono.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, FC15, FR8, 40, 75, 0, 1.01, 0, "bitmaps/buttons/pressoffo.xpm", "bitmaps/buttons/pressono.xpm", BRIGHTON_CHECKBUTTON}, /* {"", 3, FC1, FR1, FPS2, FPS1 * 5 - 25, 0, 1, 0, */ {"", 6, FC1 + 25, FR1 + 20, FPS2 - 14, FPS1 * 4 - 26, 0, 1, 0, "bitmaps/images/vu.xpm", "bitmaps/images/vumask.xpm", 0}, {"", 3, FC2 - FD1 * 2, FR2, FPS3, FPS1 - 10, 0, 1, 0, 0, "bitmaps/images/alphadisplay3.xpm", 0}, {"", 3, FC2 - FD1 * 2, FR3, FPS3, FPS1 - 1, 0, 1, 0, 0, "bitmaps/images/alphadisplay4.xpm", 0}, {"", 3, FC2 - FD1 * 2, FR4, FPS3, FPS1, 0, 1, 0, 0, "bitmaps/images/alphadisplay5.xpm", 0}, {"", 3, FC2 - FD1 * 2, FR5, FPS3, FPS1, 0, 1, 0, 0, 0, 0}, {"", 3, FC2 - FD1 * 2, FR6, FPS3, FPS1, 0, 1, 0, 0, 0, 0}, {"", 3, FC2 - FD1 * 2, FR7, FPS3, FPS1, 0, 1, 0, 0, 0, 0}, /* "bitmaps/images/alphadisplay2.xpm", 0}, */ }; /* * Width is a function of track count. With 16 tracks this is about 965, which * is equivalent to 16 + 5.5 tracks - this is used to scale to different widths. */ #define WIDTH (965 * (CHAN_COUNT + 5.5) / 21.5) #define PS1 ((int) (4 * 965 / WIDTH)) #define PV1 4 #define PWB ((int) (20 * 965 / WIDTH)) #define PW1 ((int) (((1000 - PWB * 2) / (CHAN_COUNT + 5.5)) - PS1)) #define PW2 ((int) (PW1 + PS1)) #define PBH 760 #define M1CHAN(offset) \ {\ "Mix",\ "bitmaps/blueprints/m1chan.xpm",\ "bitmaps/textures/metal5.xpm",\ 0,\ 0,\ 0,\ mixCallback,\ PWB + PS1 + PW2 * offset, PV1, PW1, 1000 - PV1 * 2,\ PARAM_COUNT,\ locations\ } /* * This is a set of globals for the main window rendering. Again taken from * include/brighton.h */ brightonApp mixApp = { "mixer", 0, /* no blueprint on wood background. */ "bitmaps/textures/metal6.xpm", BRIGHTON_STRETCH, mixInit, mixConfigure, /* 3 callbacks, unused? */ 0, destroySynth, {1, 0, 2, 1, 5, 520, 0, 0}, WIDTH, 720, 0, 0, CHAN_COUNT + 4, /* panel count == CHAN_COUNT + 4 */ { { "Border Left", 0, "bitmaps/textures/wood2.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 0, 0, PWB, 1000, 0, 0 }, { "Border Right", 0, "bitmaps/textures/wood2.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 1000 - PWB, 0, PWB, 1000, 0, 0 }, { "Function Panel", "bitmaps/blueprints/display5.xpm", "bitmaps/textures/metal5.xpm", 0, /* flags */ 0, 0, mixCallback, PWB + PS1 + PW2 * CHAN_COUNT, PV1, /*PS1, */ 1000 - PWB - PS1 * 2 - PWB - PW2 * CHAN_COUNT, 1000 - PBH - PV1, FUNCTION_COUNT, functions }, { "Bussing", "bitmaps/blueprints/m1bus.xpm", "bitmaps/textures/metal5.xpm", 0, /* flags */ 0, 0, mixCallback, PWB + PS1 + PW2 * CHAN_COUNT, 1000 - PBH + PV1, /*PS1, */ 1000 - PWB - PS1 * 2 - PWB - PW2 * CHAN_COUNT, PBH - PV1 * 2,/*1000 - PS1 * 2, */ BUS_COUNT, busses }, M1CHAN(0), M1CHAN(1), M1CHAN(2), M1CHAN(3), M1CHAN(4), M1CHAN(5), M1CHAN(6), M1CHAN(7), M1CHAN(8), M1CHAN(9), M1CHAN(10), M1CHAN(11), M1CHAN(12), M1CHAN(13), M1CHAN(14), M1CHAN(15), M1CHAN(16), M1CHAN(17), M1CHAN(18), M1CHAN(19), M1CHAN(20), M1CHAN(21), M1CHAN(22), M1CHAN(23), M1CHAN(24), M1CHAN(25), M1CHAN(26), M1CHAN(27), M1CHAN(28), M1CHAN(29), M1CHAN(30), M1CHAN(31), M1CHAN(32), M1CHAN(33), M1CHAN(34), M1CHAN(35), M1CHAN(36), M1CHAN(37), M1CHAN(38), M1CHAN(39), M1CHAN(40), M1CHAN(41), M1CHAN(42), M1CHAN(43), M1CHAN(44), M1CHAN(45), M1CHAN(46), M1CHAN(47), M1CHAN(48), M1CHAN(49), M1CHAN(50), M1CHAN(51), M1CHAN(52), M1CHAN(53), M1CHAN(54), M1CHAN(55), M1CHAN(56), M1CHAN(57), M1CHAN(58), M1CHAN(59), } }; /*static dispatcher dispatch[DEVICE_COUNT]; static void mixMemory(guiSynth *synth, int fd, int chan, int c, int o, int v) { printf("mixMemory()\n"); switch (c) { default: case 0: synth->location = synth->location * 10 + o; if (synth->location >= 1000) synth->location = o; displayPanelText(synth, "PRG", synth->location, DISPLAY_PANEL, DISPLAY_DEV); break; case 1: loadMemory(synth, "mix", 0, synth->location, synth->mem.active, FIRST_DEV, 0); displayPanelText(synth, "PRG", synth->bank + synth->location, DISPLAY_PANEL, DISPLAY_DEV); break; case 2: saveMemory(synth, "mix", 0, synth->location, FIRST_DEV); displayPanelText(synth, "PRG", synth->bank + synth->location, DISPLAY_PANEL, DISPLAY_DEV); break; } } static void mixMidi(guiSynth *synth, int fd, int chan, int c, int o, int v) { if ((synth->flags & OPERATIONAL) == 0) return; if (c == 1) { if (--synth->midichannel < 0) synth->midichannel = 0; } else { if (++synth->midichannel >= 16) synth->midichannel = 15; } bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_MIDICHANNEL|synth->midichannel); displayPanelText(synth, "MIDI", synth->midichannel + 1, DISPLAY_PANEL, DISPLAY_DEV); } */ /* * Having these located here implies only one instance of the mixer. Not sure * if that is reasonable, but if we implement multiple then this can be buried * in a dispatch structure instead. I have not specified implementation of * multiple mixers as this is realtime from the audio device. Multiple mixers * would be in separate engines? * * Oops, should change since it is very non-conducive to memory selections. * This is non-trivial, since the GUI does not support radio buttons, and the * memory subsystem should not know about them. Consequently they have to be * handled here, and it can create issues where the GUI, the mixer and its * memory subsystem are not in agreament. MARK */ int currentInSelect[MAX_CHAN_COUNT] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; int currentDynSelect[MAX_CHAN_COUNT] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; int currentFiltSelect[MAX_CHAN_COUNT] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; int currentFXSelect[MAX_CHAN_COUNT] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; int currentBusSelect[MAX_CHAN_COUNT] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; int currentBusFXSelect[MAX_CHAN_COUNT] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; /* * May pull all this track/bus/function logic into a separate file, along with * mixCallback() as access point. From a logical perspective the GUI should * feed into the memory structures and to the engine. The memory save should * push the memory structures out to storage, and the load routines should * just feed into the GUI. This makes the memory rather bespoke, but there are * a few issues that have to be taken care of for the mixer memories that will * probably require such coding. * * Currently busOp is called from mixCallback. */ int busOp(guiSynth *synth, int panel, int track, int operator, float value) { int param = operator % 30; if ((synth->flags & OPERATIONAL) == 0) return(-1); /* printf("busOp(%x, %i, %i, %i, (%i) %f)\n", */ /* synth, panel, track, operator, param, value); */ /* * For now just try and get the first 16 devices to operate as radio * buttons. */ if ((param < 14) && (param > 5)) { /* * See if we need to clear last value. Logic is: * last value = -1 -> send request for this track. * last value = other -> clear other bitmap, request this track. * last value = this -> clear this bitmap, clear track request. */ if (currentBusFXSelect[track] == -1) { currentBusFXSelect[track] = operator; } else if (currentBusFXSelect[track] == operator) { currentBusFXSelect[track] = -1; } else { brightonEvent event; /* * We now have to alter the bitmap for the previous element. * This is a call to libbrighton.... * guiSynth has brightonApp *resources: * brightonResources[] resources = panel. * resources.callback() * * However, it is wrong that we need to know about all the brighton * internals, so need to add a routine to libbrighton to allow me * to set a value, and have the display reflect that change. */ event.type = BRIGHTON_FLOAT; event.value = 0.0; brightonParamChange(synth->win, panel, currentBusFXSelect[track], &event); currentBusFXSelect[track] = operator; } return(0); } return(0); } #define DYN_START (CHAN_COUNT + 4) #define DYN_END (DYN_START + 3) #define FILT_START (DYN_START + 3) #define FILT_END (FILT_START + 4) #define FX_START (FILT_START + 8) #define FX_END (FX_START + 7) #define BUS_START (FX_START + 43) #define BUS_END (BUS_START + 4) /* * May pull all this track/bus/function logic into a separate file, along with * mixCallback() as access point. This takes calls from the bussing section and * the mixing channels and covers all parameters. It does not receive calls * from the control panel which includes the master volume, and I think I will * keep it that way, ie, master volume is a manual configuration? * * This will put the configured option into its associated structure and send * the value through to the engine, and the code will be bespoke for the mixer. * Memory load and save will also be bespoke, they will save the values to a * disk file and refill them from the file for loading, sending engine updates * for changes. * * trackOp is called from the generic mixcallback. */ static void trackOp(guiSynth *synth, int panel, int track, int operator, float value) { if ((synth->flags & OPERATIONAL) == 0) return; /* printf("trackOp(%x, %i, %i, %i, %f)\n", */ /* synth, panel, track, operator, value); */ /* * For now just try and get the first 16 devices to operate as radio * buttons. */ if (operator < CHAN_COUNT) { /* * See if we need to clear last value. Logic is: * last value = -1 -> send request for this track. * last value = other -> clear other bitmap, request this track. * last value = this -> clear this bitmap, clear track request. */ if (currentInSelect[track] == -1) { currentInSelect[track] = operator; } else if (currentInSelect[track] == operator) { currentInSelect[track] = -1; } else { brightonEvent event; /* * We now have to alter the bitmap for the previous element. * This is a call to libbrighton.... * guiSynth has brightonApp *resources: * brightonResources[] resources = panel. * resources.callback() * * However, it is wrong that we need to know about all the brighton * internals, so need to add a routine to libbrighton to allow me * to set a value, and have the display reflect that change. */ event.type = BRIGHTON_FLOAT; event.value = 0.0; brightonParamChange(synth->win, panel, currentInSelect[track], &event); currentInSelect[track] = operator; } return; } /* * Dynamics radio buttons */ if ((operator < DYN_END) && (operator >= DYN_START)) { if (currentDynSelect[track] == -1) { currentDynSelect[track] = operator; } else if (currentDynSelect[track] == operator) { currentDynSelect[track] = -1; } else { brightonEvent event; /* * We now have to alter the bitmap for the previous element. * This is a call to libbrighton.... * guiSynth has brightonApp *resources: * brightonResources[] resources = panel. * resources.callback() * * However, it is wrong that we need to know about all the brighton * internals, so need to add a routine to libbrighton to allow me * to set a value, and have the display reflect that change. */ event.type = BRIGHTON_FLOAT; event.value = 0.0; brightonParamChange(synth->win, panel, currentDynSelect[track], &event); currentDynSelect[track] = operator; } return; } /* * Filter select radio buttons */ if ((operator < FILT_END) && (operator >= FILT_START)) { if (currentFiltSelect[track] == -1) { currentFiltSelect[track] = operator; } else if (currentFiltSelect[track] == operator) { currentFiltSelect[track] = -1; } else { brightonEvent event; /* * We now have to alter the bitmap for the previous element. * This is a call to libbrighton.... * guiSynth has brightonApp *resources: * brightonResources[] resources = panel. * resources.callback() * * However, it is wrong that we need to know about all the brighton * internals, so need to add a routine to libbrighton to allow me * to set a value, and have the display reflect that change. */ event.type = BRIGHTON_FLOAT; event.value = 0.0; brightonParamChange(synth->win, panel, currentFiltSelect[track], &event); currentFiltSelect[track] = operator; } return; } /* * FX radio buttons */ if ((operator < FX_END) && (operator >= FX_START)) { if (currentFXSelect[track] == -1) { currentFXSelect[track] = operator; } else if (currentFXSelect[track] == operator) { currentFXSelect[track] = -1; } else { brightonEvent event; /* * We now have to alter the bitmap for the previous element. * This is a call to libbrighton.... * guiSynth has brightonApp *resources: * brightonResources[] resources = panel. * resources.callback() * * However, it is wrong that we need to know about all the brighton * internals, so need to add a routine to libbrighton to allow me * to set a value, and have the display reflect that change. */ event.type = BRIGHTON_FLOAT; event.value = 0.0; brightonParamChange(synth->win, panel, currentFXSelect[track], &event); currentFXSelect[track] = operator; } return; } /* * Bus select radio buttons */ if ((operator < BUS_END) && (operator >= BUS_START)) { if (currentBusSelect[track] == -1) { currentBusSelect[track] = operator; } else if (currentBusSelect[track] == operator) { currentBusSelect[track] = -1; } else { brightonEvent event; /* * We now have to alter the bitmap for the previous element. * This is a call to libbrighton.... * guiSynth has brightonApp *resources: * brightonResources[] resources = panel. * resources.callback() * * However, it is wrong that we need to know about all the brighton * internals, so need to add a routine to libbrighton to allow me * to set a value, and have the display reflect that change. */ event.type = BRIGHTON_FLOAT; event.value = 0.0; brightonParamChange(synth->win, panel, currentBusSelect[track], &event); currentBusSelect[track] = operator; } return; } } /* * For the sake of ease of use, links have been placed here to be called * by any of the devices created. They would be better in some other file, * perhaps with this as a dispatch. * * Param refers to the device index in the locations table given below. * The memory structure is going to be large. To cater for future extensions * each memory component (track, bus, etc) is going to have extra memory * allocated. New parameters will occupy the extra space allowing for * compatability of memories over releases. */ static int mixCallback(brightonWindow * win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); int sendvalue; if (synth == 0) return(0); /* printf("1: mixCallback(%i, %i, %f): %x\n", panel, index, value, synth); */ if (mixApp.resources[panel].devlocn[index].to == 1) sendvalue = value * C_RANGE_MIN_1; else sendvalue = value; switch (panel) { case FUNCTION_PANEL: functionOp(synth, panel, index, index - 1, value); break; case BUS_PANEL: if (index < 240) { int chan, op; chan = index / 30; op = index % 30; busOp(synth, panel, chan, index, value); mixerMemory(synth, MM_GET, BUS_PANEL, index, &value); mixSendMsg(synth, global.controlfd, synth->sid, 64 + chan, op, sendvalue); } else { /* WTF is VBUS_PANEL? not an op... */ mixerMemory(synth, MM_GET, VBUS_PANEL, index - 240, &value); mixSendMsg(synth, global.controlfd, synth->sid, 80, index - 240, sendvalue); } /* index += panel * PARAM_COUNT; */ /* * Corrected to: */ index += FUNCTION_COUNT; break; default: /* * Here I want to call a track function, it will be given the * track number, parameter and value, and will set that value in * an internal memory space. For radio buttons it may also need * to send requests to the GUI to alter the display. */ trackOp(synth, panel, panel - 4, index, value); setMixerMemory((mixerMem *) synth->mem.param, panel, index, &value, NULL); mixSendMsg(synth, global.controlfd, synth->sid, panel - 4, index, sendvalue); break; } if ((synth->flags & OPERATIONAL) == 0) return(0); /* printf("2: mixCallback(%i, %f): %x\n", index, value, synth); */ /* * Parameters are now handled through brightonMixerMemory.c if (debug) printf("p1 %x %i %i\n", synth->dispatch[index].routine, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator); synth->dispatch[index].routine(synth, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #ifdef DEBUG printf("dispatch[%x,%i](%i, %i, %i, %i, %i)\n", synth, index, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #endif */ return(0); } static void mixSendMsg(guiSynth *synth, int fd, int chan, int c, int o, int v) { /*printf("mixSendMsg(%i, %i, %i, %i, %f\n", fd, chan, c, o, v); */ /* int value; */ /* */ /* value = v < 1.0? v * 16383: v; */ bristolMidiSendMsg(fd, chan, c, o, v); } /* * Any location initialisation required to run the callbacks. For bristol, this * will connect to the engine, and give it some base parameters. * May need to generate some application specific menus. * Will also then make specific requests to some of the devices to alter their * rendering. * * For the mixer it is also reasonable to build the application structures, * rather than have them defined in advance? */ static int mixInit(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); /* dispatcher *dispatch; */ /* brightonEvent event; char bitmap[128]; event.type = BRIGHTON_MEM; event.m = OP2XPM; brightonParamChange(synth->win, ALGOS_PANEL, ALGOS_COUNT - 1, &event); */ if (synth == 0) { synth = findSynth(global.synths, 0); if (synth == 0) { printf("cannot init\n"); return(0); } } synth->win = win; printf("Initialise the mix link to bristol: %p\n", synth->win); /* Alloc device_count. This is wrong, should be 'abs max'. */ synth->mem.param = (float *) initMixerMemory(16); synth->mem.count = DEVICE_COUNT; synth->mem.active = ACTIVE_DEVS; /* synth->dispatch = (dispatcher *) */ /* brightonmalloc(DEVICE_COUNT * sizeof(dispatcher)); */ /* dispatch = synth->dispatch; */ /* * We really want to have three connection mechanisms. These should be * 1. Unix named sockets. * 2. UDP sockets. * 3. MIDI pipe. */ if (!global.libtest) if ((synth->sid = initConnection(&global, synth)) < 0) return(-1); /* for (i = 0; i < DEVICE_COUNT; i++) */ /* synth->dispatch[i].routine = (synthRoutine) mixSendMsg; */ return(0); } /* * This will be called to make any routine specific parameters available. */ static int mixConfigure(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); brightonEvent event; if (synth == 0) { printf("problems going operational\n"); return(-1); } if (synth->flags & OPERATIONAL) return(0); printf("going operational %p %p\n", synth, synth->win); synth->flags |= OPERATIONAL; synth->keypanel = -1; synth->keypanel2 = -1; functionOp(synth, FUNCTION_PANEL, 1, 1, 0.0); displayPanelText(synth, "TRK", 1, 4, PARAM_COUNT - 1); displayPanelText(synth, "TRK", 2, 5, PARAM_COUNT - 1); displayPanelText(synth, "TRK", 3, 6, PARAM_COUNT - 1); displayPanelText(synth, "TRK", 4, 7, PARAM_COUNT - 1); displayPanelText(synth, "TRK", 5, 8, PARAM_COUNT - 1); displayPanelText(synth, "TRK", 6, 9, PARAM_COUNT - 1); displayPanelText(synth, "TRK", 7, 10, PARAM_COUNT - 1); displayPanelText(synth, "TRK", 8, 11, PARAM_COUNT - 1); if (CHAN_COUNT > 7) { displayPanelText(synth, "TRK", 9, 12, PARAM_COUNT - 1); displayPanelText(synth, "TRK", 10, 13, PARAM_COUNT - 1); displayPanelText(synth, "TRK", 11, 14, PARAM_COUNT - 1); displayPanelText(synth, "TRK", 12, 15, PARAM_COUNT - 1); displayPanelText(synth, "TRK", 13, 16, PARAM_COUNT - 1); displayPanelText(synth, "TRK", 14, 17, PARAM_COUNT - 1); displayPanelText(synth, "TRK", 15, 18, PARAM_COUNT - 1); displayPanelText(synth, "TRK", 16, 19, PARAM_COUNT - 1); } loadMixerMemory(synth, "default", 0); event.type = BRIGHTON_FLOAT; event.value = 0.5; brightonParamChange(synth->win, 2, 0, &event); return(0); } bristol-0.60.11/brighton/brightonProphet52.c0000644000175000017500000006520011746476475015613 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include #include "brighton.h" #include "brightonMini.h" #include "brightonKeys.h" #include "brightoninternals.h" static int initmem; static int prophet52Init(); static int prophet52Configure(); static int prophet52Callback(brightonWindow *, int, int, float); /*static int keyCallback(brightonWindow *, int, int, float); */ /*static int modCallback(brightonWindow *, int, int, float); */ static int midiCallback(brightonWindow *, int, int, float); extern guimain global; #include "brightonKeys.h" #define LAST_DEV 51 #define DEV_OFFSET 2 #define FIRST_DEV 0 #define DEVICE_COUNT (69 + FIRST_DEV) #define ACTIVE_DEVS (51 + FIRST_DEV) #define DISPLAY_DEV (DEVICE_COUNT - 1 + FIRST_DEV) #define RADIOSET_1 (LAST_DEV + 1) #define KEY_PANEL 1 #define R1 140 #define RB1 160 #define R2 425 #define RB2 445 #define R3 710 #define RB3 730 #define C1 17 #define C2 66 #define CB1 60 #define CB2 88 #define C3 116 #define C4 143 #define C5 172 #define C6 217 #define CB6 258 #define CB7 287 #define C7 320 #define CB8 370 #define C9 262 #define CB9 310 #define CB10 340 #define CB11 370 #define C10 410 #define CB12 460 #define CB13 490 #define C11 418 #define C12 466 #define C13 513 #define C14 565 #define C15 613 #define C16 658 #define C17 705 #define C18 761 #define C19 810 #define C20 860 #define C21 910 #define C22 877 #define C23 964 #define S1 120 #define B1 14 #define B2 80 /* * This structure is for device definition. The structure is defined in * include/brighton.h, further definitions in brighton/brightonDevtable.h and * include/brightoninternals.h * * typedef int (*brightonCallback)(int, float); * typedef struct BrightonLocations { * int device; 0=rotary, 1=scale, etc. * float relx, rely; relative position with regards to 1000 by 1000 window * float relw, relh; relative height. * int from, to; * brightonCallback callback; specific to this dev * char *image; bitmap. If zero take a device default. * int flags; * } brightonLocations; * * This example is for a prophet52Bristol type synth interface. */ static brightonLocations locations[DEVICE_COUNT] = { /* poly mod */ {"PolyMod-Filt", 0, C1, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"PolyMod-OscB", 0, C2, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"PolyMod2Freq-A", 2, C3, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"PolyMod2PW-A", 2, C4, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"PolyMod2Filt", 2, C5, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* lfo */ {"LFO-Freq", 0, C2, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"LFO-Ramp", 2, C3, RB2, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"LFO-Tri", 2, C4, RB2, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"LFO-Square", 2, C5, RB2, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* wheel mod */ {"Wheel-Mix", 0, C1, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"Whell-FreqA", 2, CB1, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"Whell-FreqB", 2, CB2, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"Wheel-PW-A", 2, C3, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"Wheel-PW-B", 2, C4, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"Wheel-Filt", 2, C5, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* osc a */ {"OscA-Transpose", 0, C6, R1, S1, S1, 0, 5, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"OscA-Ramp", 2, CB6, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"OscA-Pulse", 2, CB7, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"OscA-PW", 0, C7, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"OscA-Sync", 2, CB8, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* osc b */ {"OscB-Transpose", 0, C6, R2, S1, S1, 0, 5, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"OscB-Tunine", 0, C9, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, BRIGHTON_NOTCH}, {"OscB-Ramp", 2, CB9, RB2, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"OscB-Tri", 2, CB10, RB2, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"OscB-Pulse", 2, CB11, RB2, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"OscB-PW", 0, C10, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"OscB-LFO", 2, CB12, RB2, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"OscB-KBD", 2, CB13, RB2, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* glide, etc */ {"Glide", 0, C6, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"Unison", 2, CB7, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* mixer */ {"Mix-OscA", 0, C11, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"Mix-OscB", 0, C12, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"Mix-Noise", 0, C13, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, /* filter + env */ {"VCF-Cutoff", 0, C14, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"VCF-Resonance", 0, C15, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"VCF-Envelope", 0, C16, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"VCF-KBD", 2, C17 + 6, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"VCF-Attack", 0, C14, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"VCF-Decay", 0, C15, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"VCF-Sustain", 0, C16, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"VCF-Release", 0, C17, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, /* main env */ {"VCA-Attack", 0, C18, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"VCA-Decay", 0, C19, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"VCA-Sustain", 0, C20, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"VCA-Release", 0, C21, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, /* tune + vol */ {"MasterTuning", 0, C18, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob3.xpm", 0, BRIGHTON_NOTCH}, {"MasterVolume", 0, C23, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob3.xpm", 0, 0}, /* Chorus */ {"Chorus-Speed", 0, C18, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"Chorus-Depth", 0, C19, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"Chorus-Phase", 0, C20, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, {"Chorus-Gain", 0, C21, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0}, /* opts */ {"Release", 2, C23 + 7, RB2, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, {"A-440", 2, C19 + 7, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, {"Tune", 2, C23 + 7, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, /* memories */ {"", 2, C14 + 10, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C14 + 30, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C14 + 50, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C14 + 70, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C14 + 90, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C14 + 110, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C14 + 130, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C14 + 150, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON}, /* L/S */ {"", 2, CB8 - 10, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, CB8 + 20, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffo.xpm", "bitmaps/buttons/pressono.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, CB8 + 50, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, /* Midi, perhaps eventually file import/export buttons */ {"", 2, C20 + 10, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, C21 + 10, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, /* */ {"", 4, 840, 1025, 140, 130, 0, 1, 0, "bitmaps/images/prophet55.xpm", 0, 0}, /* Display */ {"", 3, CB8 + 75, RB3, 120, B2, 0, 1, 0, 0, "bitmaps/images/alphadisplay3.xpm", 0} }; /* */ /* * This is a set of globals for the main window rendering. Again taken from * include/brighton.h */ brightonApp prophet52App = { "prophet52", 0, /* no blueprint on wood background. */ "bitmaps/textures/wood7.xpm", /* was wood2.xpm */ 0, /* BRIGHTON_STRETCH, //flags */ prophet52Init, prophet52Configure, /* 3 callbacks, unused? */ midiCallback, destroySynth, {5, 100, 2, 2, 5, 520, 0, 0}, 753, 310, 0, 0, 6, /* one panel only */ { { "Prophet", "bitmaps/blueprints/prophet52.xpm", "bitmaps/textures/metal4.xpm", 0, /*BRIGHTON_STRETCH, // flags */ 0, 0, prophet52Callback, 15, 25, 970, 540, DEVICE_COUNT, locations }, { "Keyboard", 0, "bitmaps/newkeys/kbg.xpm", /* flags */ 0x020|BRIGHTON_STRETCH, 0, 0, keyCallback, 110, 660, 900, 320, KEY_COUNT, keysprofile }, { "Mods", "bitmaps/blueprints/prophetmod.xpm", "bitmaps/textures/metal4.xpm", /* flags */ BRIGHTON_REVERSE, 0, 0, modCallback, 15, 660, 95, 320, 2, mods }, { "Prophet", 0, "bitmaps/textures/wood7.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 0, 0, 15, 1000, 0, 0 }, { "Prophet", 0, "bitmaps/textures/wood7.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /*flags */ 0, 0, 0, 985, 0, 15, 1000, 0, 0 }, { "Prophet", 0, "bitmaps/textures/wood4.xpm", 0, /*BRIGHTON_STRETCH|BRIGHTON_VERTICAL, //flags */ 0, 0, 0, 15, 980, 970, 20, 0, 0 } } }; /*static dispatcher dispatch[DEVICE_COUNT]; */ static int midiCallback(brightonWindow *win, int controller, int value, float n) { guiSynth *synth = findSynth(global.synths, win); printf("midi callback: %x, %i\n", controller, value); switch(controller) { case MIDI_PROGRAM: printf("midi program: %x, %i\n", controller, value); synth->location = value; loadMemory(synth, "prophet52", 0, synth->bank + synth->location, synth->mem.active, FIRST_DEV, 0); break; case MIDI_BANK_SELECT: printf("midi banksel: %x, %i\n", controller, value); synth->bank = value; break; } return(0); } static int prophet52MidiSendMsg(void *synth, int fd, int chan, int c, int o, int v) { bristolMidiSendMsg(fd, chan, c, o, v); return(0); } static void multiTune(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; /* * Configures all the tune settings to zero (ie, 0.5). Do the Osc-A first, * since it is not visible, and then request the GUI to configure Osc-B. */ bristolMidiSendMsg(fd, synth->sid, 0, 2, 8191); event.type = BRIGHTON_FLOAT; event.value = 0.5; brightonParamChange(synth->win, synth->panel, FIRST_DEV + 45, &event); brightonParamChange(synth->win, synth->panel, FIRST_DEV + 21, &event); } static void midiRelease(guiSynth *synth, int fd, int chan, int c, int o, int v) { if (!global.libtest) { bristolMidiSendMsg(fd, synth->sid, 127, 0, BRISTOL_ALL_NOTES_OFF); } } static void prophet52Memory(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; /* printf("prophet52Memory(%i)\n", c); */ if (synth->flags & MEM_LOADING) return; if ((synth->flags & OPERATIONAL) == 0) return; if (synth->dispatch[RADIOSET_1].other2) { synth->dispatch[RADIOSET_1].other2 = 0; return; } switch (c) { default: case 0: /* * We want to make these into memory buttons. To do so we need to * know what the last active button was, and deactivate its * display, then send any message which represents the most * recently configured value. Since this is a memory button we do * not have much issue with the message, but we are concerned with * the display. */ if (synth->dispatch[RADIOSET_1].other1 != -1) { synth->dispatch[RADIOSET_1].other2 = 1; if (synth->dispatch[RADIOSET_1].other1 != o) event.value = 0; else event.value = 1; brightonParamChange(synth->win, synth->panel, synth->dispatch[RADIOSET_1].other1 + LAST_DEV + 2, &event); } synth->dispatch[RADIOSET_1].other1 = o; if (synth->flags & BANK_SELECT) { if ((synth->bank * 10 + o * 10) >= 1000) { synth->location = o; synth->flags &= ~BANK_SELECT; if (loadMemory(synth, "prophet52", 0, synth->bank + synth->location, synth->mem.active, FIRST_DEV, BRISTOL_STAT) < 0) displayText(synth, "FRE", synth->bank + synth->location, DISPLAY_DEV); else displayText(synth, "PRG", synth->bank + synth->location, DISPLAY_DEV); } else { synth->bank = synth->bank * 10 + o * 10; displayText(synth, "BANK", synth->bank + synth->location, DISPLAY_DEV); } } else { if (synth->bank < 10) synth->bank = 10; synth->location = o; if (loadMemory(synth, "prophet52", 0, synth->bank + synth->location, synth->mem.active, FIRST_DEV, BRISTOL_STAT) < 0) displayText(synth, "FRE", synth->bank + synth->location, DISPLAY_DEV); else displayText(synth, "PRG", synth->bank + synth->location, DISPLAY_DEV); } break; case 1: if (synth->bank < 10) synth->bank = 10; if (synth->location == 0) synth->location = 1; if (loadMemory(synth, "prophet52", 0, synth->bank + synth->location, synth->mem.active, FIRST_DEV, 0) < 0) displayText(synth, "FRE", synth->bank + synth->location, DISPLAY_DEV); else displayText(synth, "PRG", synth->bank + synth->location, DISPLAY_DEV); synth->flags &= ~BANK_SELECT; break; case 2: if (synth->bank < 10) synth->bank = 10; if (synth->location == 0) synth->location = 1; saveMemory(synth, "prophet52", 0, synth->bank + synth->location, FIRST_DEV); displayText(synth, "PRG", synth->bank + synth->location, DISPLAY_DEV); synth->flags &= ~BANK_SELECT; break; case 3: if (synth->flags & BANK_SELECT) { synth->flags &= ~BANK_SELECT; if (loadMemory(synth, "prophet52", 0, synth->bank + synth->location, synth->mem.active, FIRST_DEV, BRISTOL_STAT) < 0) displayText(synth, "FRE", synth->bank + synth->location, DISPLAY_DEV); else displayText(synth, "PRG", synth->bank + synth->location, DISPLAY_DEV); } else { synth->bank = 0; displayText(synth, "BANK", synth->bank, DISPLAY_DEV); synth->flags |= BANK_SELECT; } break; } /* printf(" prophet52Memory(B: %i L %i: %i)\n", */ /* synth->bank, synth->location, o); */ } static int prophet52Midi(guiSynth *synth, int fd, int chan, int c, int o, int v) { int newchan; if ((synth->flags & OPERATIONAL) == 0) return(0); if (c == 1) { if ((newchan = synth->midichannel - 1) < 0) { synth->midichannel = 0; return(0); } } else { if ((newchan = synth->midichannel + 1) >= 16) { synth->midichannel = 15; return(0); } } if (global.libtest == 0) { bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_MIDICHANNEL|newchan); } displayText(synth, "MIDI", newchan + 1, DISPLAY_DEV); synth->midichannel = newchan; /* printf("P: going to display: %x, %x\n", synth, synth->win); */ /* displayText(synth, "MIDI", synth->midichannel + 1, DISPLAY_DEV); */ return(0); } /* * For the sake of ease of use, links have been placed here to be called * by any of the devices created. They would be better in some other file, * perhaps with this as a dispatch. * * Param refers to the device index in the locations table given below. */ static int prophet52Callback(brightonWindow * win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); int sendvalue; /* printf("prophet52Callback(%i, %f): %x\n", index, value, synth); */ if (synth == 0) return(0); if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0)) return(0); if (prophet52App.resources[0].devlocn[index].to == 1.0) sendvalue = value * (CONTROLLER_RANGE - 1); else sendvalue = value; synth->mem.param[index] = value; if ((!global.libtest) || (index >= ACTIVE_DEVS)) synth->dispatch[index].routine(synth, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #ifdef DEBUG else printf("dispatch[%p,%i](%i, %i, %i, %i, %i)\n", synth, index, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #endif return(0); } static void keyTracking(guiSynth *synth, int fd, int chan, int c, int o, int v) { bristolMidiSendMsg(fd, synth->sid, 4, 3, v / 2); } /* * Any location initialisation required to run the callbacks. For bristol, this * will connect to the engine, and give it some base parameters. * May need to generate some application specific menus. * Will also then make specific requests to some of the devices to alter their * rendering. */ static int prophet52Init(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); dispatcher *dispatch; int i; if (synth == 0) { synth = findSynth(global.synths, (int) 0); if (synth == 0) { printf("cannot init\n"); return(0); } } synth->win = win; if ((initmem = synth->location) == 0) initmem = 11; printf("Initialise the prophet52 link to bristol: %p\n", synth->win); synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float)); synth->mem.count = DEVICE_COUNT; synth->mem.active = ACTIVE_DEVS; synth->dispatch = (dispatcher *) brightonmalloc(DEVICE_COUNT * sizeof(dispatcher)); dispatch = synth->dispatch; /* * We really want to have three connection mechanisms. These should be * 1. Unix named sockets. * 2. UDP sockets. * 3. MIDI pipe. */ if (!global.libtest) { if ((synth->sid = initConnection(&global, synth)) < 0) return(-1); } for (i = 0; i < DEVICE_COUNT; i++) { synth->dispatch[i].routine = prophet52MidiSendMsg; } dispatch[FIRST_DEV].controller = 126; dispatch[FIRST_DEV].operator = 6; dispatch[FIRST_DEV + 1].controller = 126; dispatch[FIRST_DEV + 1].operator = 7; dispatch[FIRST_DEV + 2].controller = 126; dispatch[FIRST_DEV + 2].operator = 8; dispatch[FIRST_DEV + 3].controller = 126; dispatch[FIRST_DEV + 3].operator = 9; dispatch[FIRST_DEV + 4].controller = 126; dispatch[FIRST_DEV + 4].operator = 10; dispatch[FIRST_DEV + 5].controller = 2; dispatch[FIRST_DEV + 5].operator = 0; dispatch[FIRST_DEV + 6].controller = 126; dispatch[FIRST_DEV + 6].operator = 24; dispatch[FIRST_DEV + 7].controller = 126; dispatch[FIRST_DEV + 7].operator = 25; dispatch[FIRST_DEV + 8].controller = 126; dispatch[FIRST_DEV + 8].operator = 26; dispatch[FIRST_DEV + 9].controller = 126; dispatch[FIRST_DEV + 9].operator = 11; dispatch[FIRST_DEV + 10].controller = 126; dispatch[FIRST_DEV + 10].operator = 12; dispatch[FIRST_DEV + 11].controller = 126; dispatch[FIRST_DEV + 11].operator = 13; dispatch[FIRST_DEV + 12].controller = 126; dispatch[FIRST_DEV + 12].operator = 14; dispatch[FIRST_DEV + 13].controller = 126; dispatch[FIRST_DEV + 13].operator = 15; dispatch[FIRST_DEV + 14].controller = 126; dispatch[FIRST_DEV + 14].operator = 16; dispatch[FIRST_DEV + 15].controller = 0; dispatch[FIRST_DEV + 15].operator = 1; dispatch[FIRST_DEV + 16].controller = 0; dispatch[FIRST_DEV + 16].operator = 4; dispatch[FIRST_DEV + 17].controller = 0; dispatch[FIRST_DEV + 17].operator = 6; dispatch[FIRST_DEV + 18].controller = 0; dispatch[FIRST_DEV + 18].operator = 0; dispatch[FIRST_DEV + 19].controller = 0; dispatch[FIRST_DEV + 19].operator = 7; dispatch[FIRST_DEV + 20].controller = 1; dispatch[FIRST_DEV + 20].operator = 1; dispatch[FIRST_DEV + 21].controller = 1; dispatch[FIRST_DEV + 21].operator = 2; dispatch[FIRST_DEV + 22].controller = 1; dispatch[FIRST_DEV + 22].operator = 4; dispatch[FIRST_DEV + 23].controller = 1; dispatch[FIRST_DEV + 23].operator = 5; dispatch[FIRST_DEV + 24].controller = 1; dispatch[FIRST_DEV + 24].operator = 6; dispatch[FIRST_DEV + 25].controller = 1; dispatch[FIRST_DEV + 25].operator = 0; dispatch[FIRST_DEV + 26].controller = 126; dispatch[FIRST_DEV + 26].operator = 18; dispatch[FIRST_DEV + 27].controller = 126; dispatch[FIRST_DEV + 27].operator = 19; dispatch[FIRST_DEV + 28].controller = 126; dispatch[FIRST_DEV + 28].operator = 0; dispatch[FIRST_DEV + 29].controller = 126; dispatch[FIRST_DEV + 29].operator = 1; dispatch[FIRST_DEV + 30].controller = 126; dispatch[FIRST_DEV + 30].operator = 20; dispatch[FIRST_DEV + 31].controller = 126; dispatch[FIRST_DEV + 31].operator = 21; dispatch[FIRST_DEV + 32].controller = 126; dispatch[FIRST_DEV + 32].operator = 22; dispatch[FIRST_DEV + 33].controller = 4; dispatch[FIRST_DEV + 33].operator = 0; dispatch[FIRST_DEV + 34].controller = 4; dispatch[FIRST_DEV + 34].operator = 1; dispatch[FIRST_DEV + 35].controller = 126; dispatch[FIRST_DEV + 35].operator = 23; dispatch[FIRST_DEV + 36].controller = 4; dispatch[FIRST_DEV + 36].operator = 3; dispatch[FIRST_DEV + 36].routine = (synthRoutine) keyTracking; dispatch[FIRST_DEV + 37].controller = 3; dispatch[FIRST_DEV + 37].operator = 0; dispatch[FIRST_DEV + 38].controller = 3; dispatch[FIRST_DEV + 38].operator = 1; dispatch[FIRST_DEV + 39].controller = 3; dispatch[FIRST_DEV + 39].operator = 2; dispatch[FIRST_DEV + 40].controller = 3; dispatch[FIRST_DEV + 40].operator = 3; dispatch[FIRST_DEV + 41].controller = 5; dispatch[FIRST_DEV + 41].operator = 0; dispatch[FIRST_DEV + 42].controller = 5; dispatch[FIRST_DEV + 42].operator = 1; dispatch[FIRST_DEV + 43].controller = 5; dispatch[FIRST_DEV + 43].operator = 2; dispatch[FIRST_DEV + 44].controller = 5; dispatch[FIRST_DEV + 44].operator = 3; dispatch[FIRST_DEV + 45].controller = 126; dispatch[FIRST_DEV + 45].operator = 2; dispatch[FIRST_DEV + 46].controller = 5; dispatch[FIRST_DEV + 46].operator = 4; dispatch[FIRST_DEV + 47].controller = 126; dispatch[FIRST_DEV + 47].operator = 32; dispatch[FIRST_DEV + 48].controller = 126; dispatch[FIRST_DEV + 48].operator = 31; dispatch[FIRST_DEV + 49].controller = 126; dispatch[FIRST_DEV + 49].operator = 30; dispatch[FIRST_DEV + 50].controller = 126; dispatch[FIRST_DEV + 50].operator = 33; dispatch[DEV_OFFSET + 49].controller = 1; dispatch[DEV_OFFSET + 49].operator = 1; dispatch[DEV_OFFSET + 49].routine = (synthRoutine) midiRelease; dispatch[DEV_OFFSET + 50].controller = 126; dispatch[DEV_OFFSET + 50].operator = 3; dispatch[DEV_OFFSET + 51].controller = 1; dispatch[DEV_OFFSET + 51].operator = 1; dispatch[DEV_OFFSET + 51].routine = (synthRoutine) multiTune; dispatch[DEV_OFFSET + 52].operator = 1; dispatch[DEV_OFFSET + 53].operator = 2; dispatch[DEV_OFFSET + 54].operator = 3; dispatch[DEV_OFFSET + 55].operator = 4; dispatch[DEV_OFFSET + 56].operator = 5; dispatch[DEV_OFFSET + 57].operator = 6; dispatch[DEV_OFFSET + 58].operator = 7; dispatch[DEV_OFFSET + 59].operator = 8; dispatch[DEV_OFFSET + 60].controller = 1; dispatch[DEV_OFFSET + 61].controller = 2; dispatch[DEV_OFFSET + 62].controller = 3; dispatch[DEV_OFFSET + 52].routine = dispatch[DEV_OFFSET + 53].routine = dispatch[DEV_OFFSET + 54].routine = dispatch[DEV_OFFSET + 55].routine = dispatch[DEV_OFFSET + 56].routine = dispatch[DEV_OFFSET + 57].routine = dispatch[DEV_OFFSET + 58].routine = dispatch[DEV_OFFSET + 59].routine = dispatch[DEV_OFFSET + 60].routine = dispatch[DEV_OFFSET + 61].routine = dispatch[DEV_OFFSET + 62].routine = (synthRoutine) prophet52Memory; dispatch[DEV_OFFSET + 63].routine = dispatch[DEV_OFFSET + 64].routine = (synthRoutine) prophet52Midi; dispatch[DEV_OFFSET + 63].controller = 1; dispatch[DEV_OFFSET + 64].controller = 2; dispatch[RADIOSET_1].other1 = -1; /* Tune osc-1 */ bristolMidiSendMsg(global.controlfd, synth->sid, 0, 2, 8192); /* Gain on filter contour */ bristolMidiSendMsg(global.controlfd, synth->sid, 3, 4, CONTROLLER_RANGE - 1); bristolMidiSendMsg(global.controlfd, synth->sid, 4, 4, 4); return(0); } /* * This will be called to make any routine specific parameters available. */ static int prophet52Configure(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); brightonEvent event; if (synth == 0) { printf("problems going operational\n"); return(-1); } if (synth->flags & OPERATIONAL) return(0); printf("going operational\n"); synth->flags |= OPERATIONAL; synth->keypanel = 1; synth->keypanel2 = -1; synth->transpose = 36; if (synth->location == 0) { synth->bank = 10; synth->location = 1; } loadMemory(synth, "prophet52", 0, initmem, synth->mem.active, FIRST_DEV, 0); brightonPut(win, "bitmaps/blueprints/prophet52shade.xpm", 0, 0, win->width, win->height); /* * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only * occurs on first paint, so we suppress the first paint, and then request * an expose here. */ event.type = BRIGHTON_EXPOSE; event.intvalue = 1; brightonParamChange(synth->win, KEY_PANEL, -1, &event); configureGlobals(synth); return(0); } bristol-0.60.11/brighton/brightonOBX.c0000644000175000017500000010453411746476475014457 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include #include "brighton.h" #include "brightonMini.h" static int initmem; static int obxInit(); static int obxConfigure(); static int obxCallback(brightonWindow *, int, int, float); /*static int keyCallback(void *, int, int, float); */ static int obxModCallback(brightonWindow *, int, int, float); static int obxMidiCallback(brightonWindow *, int, int, float); extern guimain global; #include "brightonKeys.h" #include "brightoninternals.h" #define FIRST_DEV 0 #define DEVICE_COUNT 65 #define ACTIVE_DEVS 43 #define OBX_DEVS 46 /* Have to account for the manual options. */ #define MEM_START (OBX_DEVS - 1) #define RADIOSET_1 MEM_START #define RADIOSET_2 (MEM_START + 1) #define RADIOSET_3 (MEM_START + 2) #define DISPLAY_DEV (DEVICE_COUNT - 1) #define KEY_PANEL 1 /* * This structure is for device definition. The structure is defined in * include/brighton.h, further definitions in brighton/brightonDevtable.h and * include/brightoninternals.h * * typedef int (*brightonCallback)(int, float); * typedef struct BrightonLocations { * int device; 0=rotary, 1=scale, etc. * float relx, rely; relative position with regards to 1000 by 1000 window * float relw, relh; relative height. * int from, to; * brightonCallback callback; specific to this dev * char *image; bitmap. If zero take a device default. * int flags; * } brightonLocations; * * This example is for a obxBristol type synth interface. */ #define S1 110 #define S2 17 #define S3 70 #define BO 10 #define B2 6 #define R1 200 #define R2 430 #define R3 600 #define R3b 600 #define R4 780 #define C1 50 #define C2 66 #define C3 100 #define C4 175 #define C5 242 #define C6 300 #define C7 354 #define C8 415 #define C9 475 #define C10 535 #define C11 590 #define C12 650 #define C13 710 #define C11b 750 #define C12b 800 #define C13b 850 #define C14 775 #define C15 825 #define C16 875 #define C17 925 /* memories */ #define MD 23 #define C20 (C8 + MD + MD/2) #define C21 (C20 + MD) #define C22 (C21 + MD) #define C23 (C22 + MD) #define C24 (C23 + MD) #define C25 (C24 + MD) #define C26 (C25 + MD) #define C27 (C26 + MD) #define C28 (C27 + MD + MD/2) #define C29 (C28 + MD) #define C30 (C29 + MD) #define C31 (C30 + MD) #define C32 (C31 + MD) #define C33 (C32 + MD) #define C34 (C33 + MD) #define C35 (C34 + MD) #define C36 (C35 + MD + MD/2) static brightonLocations locations[DEVICE_COUNT] = { /* 0 - control */ {"Glide", 0, C4, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"Unison", 2, C4 + B2, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"Osc2-Detune", 0, C4, R3b, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, /* 3 - mods */ {"LFO-Freq", 0, C5, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"LFO-Sine", 2, C5 + B2, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"LFO-Square", 2, C5 + B2, R3, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"LFO-S/H", 2, C5 + B2, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"LFO-FM-Depth", 0, C6, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"LFO-FM-Osc1", 2, C6 + B2, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"LFO-FM-Osc2", 2, C6 + B2, R3, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"LFO-FM-Filt", 2, C6 + B2, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"LFO-PWM-Depth", 0, C7, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"LFO-PWM-Osc1", 2, C7 + B2, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"LFO-PWM-Osc2", 2, C7 + B2, R3, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* 14 - oscillators: */ {"Osc1-Transpose", 0, C8, R1, S1, S1, 0, 5, 0, "bitmaps/knobs/knob5.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"Osc-PW", 0, C9, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"Osc2-Tune", 0, C10, R1, S1, S1, 0, 47, 0, "bitmaps/knobs/knob5.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"Osc1-Saw", 2, C8 - 8, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"Osc1-PW-CLI!", 2, C8 + 17, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"Osc-CrossMod", 2, C9 - 8, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"Osc-Sync", 2, C9 + 17, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"Osc1-Saw", 2, C10 - 8, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"Osc1-Pulse", 2, C10 + 17, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* 23 - filter */ {"VCF-Cutoff", 0, C11, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"VCF-Resonance", 0, C12, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"VCF-ModLevel", 0, C13, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"MixOsc1", 2, C11 - 8, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"VCF-KBD", 2, C11 + 17, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"MixOsc2-Half", 2, C12 - 8, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"MixOsc2-Full", 2, C12 + 17, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"MixNoise-Half", 2, C13 - 8, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"MixNoise-Full", 2, C13 + 17, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* 32 - envelope */ {"VCF-Attack", 0, C14, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"VCF-Decay", 0, C15, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"VCF-Sustain", 0, C16, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"VCF-Release", 0, C17, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"VCA-Attack", 0, C14, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"VCA-Decay", 0, C15, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"VCA-Sustain", 0, C16, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"VCA-Release", 0, C17, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, /* According to the original, these are not saved. Volume will be, and */ /* reset should be.. */ {"MasterVolume", 0, C2 + BO, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"Reset", 2, C3 + BO, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* Total 42 parameters. */ {"Auto", 2, C1, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, C2 + BO * 3/2, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* {"", 2, C3 + BO, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", */ /* "bitmaps/buttons/presson.xpm", 0}, */ {"", 0, C2 + BO, R3b, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_NOTCH}, /*46 */ /* Programmer */ {"", 2, C8, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, C20, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C21, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C22, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C23, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C24, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C25, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C26, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C27, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C28, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C29, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C30, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C31, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C32, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C33, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C34, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C35, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON}, {"", 2, C36, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, C17 - 10, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, C17 + MD, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, }; #define OBX_MODCOUNT 5 static brightonLocations obxMods[OBX_MODCOUNT] = { {"", 1, 385, 200, 100, 468, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, BRIGHTON_CENTER}, {"", 1, 520, 200, 100, 468, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0, 0}, {"", 2, 180, 800, 130, 140, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 450, 800, 130, 140, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 690, 800, 130, 140, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0} }; /* * This is a set of globals for the main window rendering. Again taken from * include/brighton.h */ brightonApp obxApp = { "obx", 0, /* no blueprint on wood background. */ "bitmaps/textures/metal6.xpm", BRIGHTON_STRETCH, /*flags */ obxInit, obxConfigure, /* 3 callbacks, unused? */ obxMidiCallback, destroySynth, {5, 100, 2, 2, 5, 520, 0, 0}, 770, 350, 0, 0, 6, /* Panel count */ { { "OBX", "bitmaps/blueprints/obx.xpm", "bitmaps/textures/metal6.xpm", BRIGHTON_STRETCH|BRIGHTON_REVERSE, /* flags */ 0, 0, obxCallback, 14, 130, 970, 520, DEVICE_COUNT, locations }, { "Keyboard", 0, "bitmaps/newkeys/kbg.xpm", /* flags */ 0x020|BRIGHTON_STRETCH, 0, 0, keyCallback, 155, 690, 854, 290, KEY_COUNT, keys }, { "Mods", "bitmaps/blueprints/obxmod.xpm", "bitmaps/textures/metal5.xpm", /* flags */ 0, 0, 0, obxModCallback, /* Needs to be obxModCallback */ 17, 690, 136, 290, OBX_MODCOUNT, obxMods }, { "Logo", "bitmaps/blueprints/obxlogo.xpm", 0, BRIGHTON_STRETCH, /*flags */ 0, 0, 0, 15, 0, 970, 130, 0, 0 }, { "Edge", 0, "bitmaps/images/rhodes.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 0, 0, 15, 1000, 0, 0 }, { "Edge", 0, "bitmaps/images/rhodes.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /*flags */ 0, 0, 0, 985, 0, 15, 1000, 0, 0 }, } }; static int obxKeyLoadMemory(guiSynth *synth, char *algo, char *name, int location, int active, int skip, int flags) { brightonEvent event; synth->flags |= MEM_LOADING; loadMemory(synth, "obx", 0, location, synth->mem.active, FIRST_DEV, 0); /* * We now need to force the PW of the two oscillators? */ bristolMidiSendMsg(synth->sid, synth->midichannel, 0, 0, (int) synth->mem.param[15]); bristolMidiSendMsg(synth->sid, synth->midichannel, 1, 0, (int) synth->mem.param[ACTIVE_DEVS-1]); event.value = 0; brightonParamChange(synth->win, 0, ACTIVE_DEVS-1, &event); synth->flags &= ~MEM_LOADING; return(0); } static void obxLoadMemory(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; synth->flags |= MEM_LOADING; loadMemory(synth, "obx", 0, synth->bank * 10 + synth->location, synth->mem.active, FIRST_DEV, 0); /* * We now need to force the PW of the two oscillators? */ bristolMidiSendMsg(fd, chan, 0, 0, (int) synth->mem.param[15]); bristolMidiSendMsg(fd, chan, 1, 0, (int) synth->mem.param[ACTIVE_DEVS-1]); event.value = 0; brightonParamChange(synth->win, 0, ACTIVE_DEVS-1, &event); synth->flags &= ~MEM_LOADING; } static int obxMidiCallback(brightonWindow *win, int controller, int value, float n) { guiSynth *synth = findSynth(global.synths, win); printf("midi callback: %x, %i\n", controller, value); switch(controller) { case MIDI_PROGRAM: printf("midi program: %x, %i\n", controller, value); synth->location = value; /* loadMemory(synth, "obx", 0, synth->bank + synth->location, */ /* synth->mem.active, FIRST_DEV, 0); */ obxLoadMemory(synth, global.controlfd, synth->midichannel, 0, 0, 0); break; case MIDI_BANK_SELECT: printf("midi banksel: %x, %i\n", controller, value); synth->bank = value; break; } return(0); } static int narrow = 0; static int osc2 = 0; static int obxModCallback(brightonWindow *win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); int sendvalue; /* printf("obxModCallback(%x, %i, %i, %f)\n", synth, panel, index, value); */ /* * If this is controller 0 it is the frequency control, otherwise a * generic controller 1. */ switch (index) { case 0: if (narrow != 0) sendvalue = C_RANGE_MIN_1 / 2 + (int) (((value - 0.5) / 3) * C_RANGE_MIN_1); else sendvalue = (int) ((value * C_RANGE_MIN_1)); if (osc2 == 0) bristolMidiSendMsg(global.controlfd, synth->sid, 0, 11, sendvalue); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 11, sendvalue); break; case 1: /* * Not sure why this should work, and it probably doesn't. It is * the 'mod' controller but appears to affect Osc-1 tranpose */ if (narrow != 0) /*sendvalue = (int) ((value * C_RANGE_MIN_1)) >> 3; */ sendvalue = C_RANGE_MIN_1 / 2 + (int) (((value - 0.5) / 3) * C_RANGE_MIN_1); else sendvalue = (int) ((value * C_RANGE_MIN_1)); bristolMidiSendMsg(global.controlfd, synth->midichannel, 2, 0, sendvalue); break; case 2: /* Narrow */ if (value != 0.0) narrow = 4; else narrow = 0; break; case 3: /* Osc2 */ /* * This switch is a bit of a pain, it controls whether Osc-2 is * affected by the pitchbend. This means we have to use another * modulation method for case 0 above since the existing method * is global. This is painful as it means we need another param * on the prophetdco..... * May remap the button for single/multi LFO? bristolMidiSendMsg(global.controlfd, synth->sid, 126, 22, (int) value); */ osc2 = value; break; case 4: /* Transpose */ if (value != 0.0) synth->transpose = 48; else synth->transpose = 36; break; } return(0); } #define KEY_HOLD (FIRST_DEV + 43) static void obxHold(guiSynth *synth) { if ((synth->flags & OPERATIONAL) == 0) return; /*printf("obxHold %x\n", synth); */ if (synth->mem.param[KEY_HOLD]) bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_HOLD|1); else bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_HOLD|0); } static int dreset = 0; static int d1 = 0; static int d2 = 0; /* * If controller #41 has value zero then we configure the release rates, else * we use the shortest release rate. */ static void obxDecay(void *synth, int fd, int chan, int c, int o, int v) { if (c == 41) { if (v == 0) { /* * Set values to their current settings */ dreset = 0; bristolMidiSendMsg(fd, chan, 3, 3, d1); bristolMidiSendMsg(fd, chan, 5, 3, d2); } else { /* * Set values to minimum release time */ dreset = 1; bristolMidiSendMsg(fd, chan, 3, 3, 20); bristolMidiSendMsg(fd, chan, 5, 3, 20); } } else { if (dreset == 0) bristolMidiSendMsg(fd, chan, c, o, v); if (c == 3) d1 = v; else d2 = v; } } static int pwSelect = 0; /* * We need to see if for any given oscillator none of the wave buttons are * selected. If this is the case then select triangle. Else disable tri and * configure the selected values. */ static void obxWaveform(guiSynth *synth, int fd, int chan, int c, int o, int v) { /* * See if this is the PW parameter. */ if (c == 15) { if (synth->flags & MEM_LOADING) return; synth->mem.param[15] = v; if (pwSelect == 0) { bristolMidiSendMsg(fd, chan, 0, 0, v); } else { synth->mem.param[ACTIVE_DEVS - 1] = v; bristolMidiSendMsg(fd, chan, 1, 0, v); } return; } /* * See if we need to set PW selector */ if (o == 6) { /* * If the sqr is being selected, then PW will modify this oscillator, * and if going off then it will cotrol the other */ if (v != 0) pwSelect = c; else pwSelect = 1 - c; } /* * If the value is '1' we can just set the desired wave and disable tri. */ if (v != 0) { bristolMidiSendMsg(fd, chan, c, o, v); bristolMidiSendMsg(fd, chan, c, 5, 0); } else { bristolMidiSendMsg(fd, chan, c, o, v); if (c == 0) { if ((synth->mem.param[17] == 0) && (synth->mem.param[18] == 0)) bristolMidiSendMsg(fd, chan, c, 5, 1); } else { if ((synth->mem.param[21] == 0) && (synth->mem.param[22] == 0)) bristolMidiSendMsg(fd, chan, c, 5, 1); } } } static int obxMidiSendMsg(void *synth, int fd, int chan, int c, int o, int v) { bristolMidiSendMsg(fd, chan, c, o, v); return(0); } static void multiTune(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; if (synth->flags & MEM_LOADING) return; /* * Configures all the tune settings to zero (ie, 0.5). * We have master tune, id 44 and Osc-2 detune, id 2. */ event.type = BRIGHTON_FLOAT; event.value = 0.5; brightonParamChange(synth->win, synth->panel, FIRST_DEV + 2, &event); brightonParamChange(synth->win, synth->panel, FIRST_DEV + 44, &event); } /* * The OB-X does not have a lot of memories, just 8 banks of 8 memories. This * is a bit sparse for the emulater but it keeps the interface easy. Will be * two sets of buttons, one for the bank, one for the index, then load and * save. Load and Save will be intermittent and the banks radio buttons. */ static void obxMemory(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; /*printf("obxMemory(%i, %i, %i, %i)\n", chan, c, o, v); */ switch (c) { case 16: /* Load */ /* synth->flags |= MEM_LOADING; loadMemory(synth, "obx", 0, synth->bank * 10 + synth->location, synth->mem.active, FIRST_DEV, 0); * We now need to force the PW of the two oscillators? bristolMidiSendMsg(fd, chan, 0, 0, (int) synth->mem.param[15]); bristolMidiSendMsg(fd, chan, 1, 0, (int) synth->mem.param[ACTIVE_DEVS-1]); event.value = 0; brightonParamChange(synth->win, 0, ACTIVE_DEVS-1, &event); synth->flags &= ~MEM_LOADING; */ obxLoadMemory(synth, fd, chan, c, o, v); break; case 17: /* Save */ saveMemory(synth, "obx", 0, synth->bank * 10 + synth->location, 0); break; case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: if (synth->dispatch[RADIOSET_1].other2) { synth->dispatch[RADIOSET_1].other2 = 0; return; } if (synth->dispatch[RADIOSET_1].other1 != -1) { synth->dispatch[RADIOSET_1].other2 = 1; if (synth->dispatch[RADIOSET_1].other1 != o) event.value = 0; else event.value = 1; brightonParamChange(synth->win, synth->panel, synth->dispatch[RADIOSET_1].other1, &event); } synth->dispatch[RADIOSET_1].other1 = o; synth->bank = c + 1; break; case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: if (synth->dispatch[RADIOSET_2].other2) { synth->dispatch[RADIOSET_2].other2 = 0; return; } if (synth->dispatch[RADIOSET_2].other1 != -1) { synth->dispatch[RADIOSET_2].other2 = 1; if (synth->dispatch[RADIOSET_2].other1 != o) event.value = 0; else event.value = 1; brightonParamChange(synth->win, synth->panel, synth->dispatch[RADIOSET_2].other1, &event); } synth->dispatch[RADIOSET_2].other1 = o; synth->location = c - 7; break; } /*printf(" obxMemory(B: %i, L: %i, %i, %i)\n", */ /*synth->bank, synth->location, synth->bank * 8 + synth->location, o); */ } static void obxMidi(guiSynth *synth, int fd, int chan, int c, int o, int v) { int newchan; if ((synth->flags & OPERATIONAL) == 0) return; if (c == 1) { if ((newchan = synth->midichannel - 1) < 0) { synth->midichannel = 0; return; } } else { if ((newchan = synth->midichannel + 1) >= 16) { synth->midichannel = 15; return; } } if (global.libtest == 0) { bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_MIDICHANNEL|newchan); } synth->midichannel = newchan; } /* * For the sake of ease of use, links have been placed here to be called * by any of the devices created. They would be better in some other file, * perhaps with this as a dispatch. * * Param refers to the device index in the locations table given below. */ static int obxCallback(brightonWindow *win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); int sendvalue; /* printf("obxCallback(%i, %f): %x\n", index, value, synth); */ if (synth == 0) return(0); if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0)) return(0); if (obxApp.resources[0].devlocn[index].to == 1.0) sendvalue = value * C_RANGE_MIN_1; else sendvalue = value; synth->mem.param[index] = value; if ((!global.libtest) || (index >= ACTIVE_DEVS)) synth->dispatch[index].routine(synth, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #ifdef DEBUG else printf("dispatch[%x,%i](%i, %i, %i, %i, %i)\n", synth, index, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #endif return(0); } /* * Any location initialisation required to run the callbacks. For bristol, this * will connect to the engine, and give it some base parameters. * May need to generate some application specific menus. * Will also then make specific requests to some of the devices to alter their * rendering. */ static int obxInit(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); dispatcher *dispatch; int i; if (synth == 0) { synth = findSynth(global.synths, 0); if (synth == 0) { printf("cannot init\n"); return(0); } } if ((initmem = synth->location) == 0) initmem = 11; synth->win = win; printf("Initialise the obx link to bristol: %p\n", synth->win); synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float)); synth->mem.count = DEVICE_COUNT; synth->mem.active = ACTIVE_DEVS; synth->dispatch = (dispatcher *) brightonmalloc(DEVICE_COUNT * sizeof(dispatcher)); dispatch = synth->dispatch; /* * We really want to have three connection mechanisms. These should be * 1. Unix named sockets. * 2. UDP sockets. * 3. MIDI pipe. */ if (!global.libtest) { if ((synth->sid = initConnection(&global, synth)) < 0) return(-1); } for (i = 0; i < DEVICE_COUNT; i++) synth->dispatch[i].routine = obxMidiSendMsg; /* Glide and Unison, done */ dispatch[FIRST_DEV].controller = 126; dispatch[FIRST_DEV].operator = 0; dispatch[FIRST_DEV + 1].controller = 126; dispatch[FIRST_DEV + 1].operator = 1; dispatch[FIRST_DEV + 2].controller = 1; dispatch[FIRST_DEV + 2].operator = 10; /* LFO - operator 2 parameters - Done */ dispatch[FIRST_DEV + 3].controller = 2; dispatch[FIRST_DEV + 3].operator = 0; dispatch[FIRST_DEV + 4].controller = 126; dispatch[FIRST_DEV + 4].operator = 19; dispatch[FIRST_DEV + 5].controller = 126; dispatch[FIRST_DEV + 5].operator = 20; /* S/H - this should be a routing switch. */ dispatch[FIRST_DEV + 6].controller = 126; dispatch[FIRST_DEV + 6].operator = 21; /* Depth Osc/Osc/Filt - routing control/switches */ dispatch[FIRST_DEV + 7].controller = 126; dispatch[FIRST_DEV + 7].operator = 4; dispatch[FIRST_DEV + 8].controller = 126; dispatch[FIRST_DEV + 8].operator = 5; dispatch[FIRST_DEV + 9].controller = 126; dispatch[FIRST_DEV + 9].operator = 6; dispatch[FIRST_DEV + 10].controller = 126; dispatch[FIRST_DEV + 10].operator = 7; /* PWM Osc/Osc - routing control/switches */ dispatch[FIRST_DEV + 11].controller = 126; dispatch[FIRST_DEV + 11].operator = 8; dispatch[FIRST_DEV + 12].controller = 126; dispatch[FIRST_DEV + 12].operator = 9; dispatch[FIRST_DEV + 13].controller = 126; dispatch[FIRST_DEV + 13].operator = 10; /* Osc - Some routing switches. */ dispatch[FIRST_DEV + 14].controller = 0; dispatch[FIRST_DEV + 14].operator = 1; /* PWM - needs to adjust both oscillators, so need a dispatcher. */ dispatch[FIRST_DEV + 15].controller = 15; dispatch[FIRST_DEV + 15].operator = 1; dispatch[FIRST_DEV + 16].controller = 1; dispatch[FIRST_DEV + 16].operator = 9; /* Saw/Square. May need dispatch for tri when both off */ dispatch[FIRST_DEV + 17].controller = 0; dispatch[FIRST_DEV + 17].operator = 4; dispatch[FIRST_DEV + 18].controller = 0; dispatch[FIRST_DEV + 18].operator = 6; /* Crossmod and sync - routing switches */ dispatch[FIRST_DEV + 19].controller = 126; dispatch[FIRST_DEV + 19].operator = 11; dispatch[FIRST_DEV + 20].controller = 1; dispatch[FIRST_DEV + 20].operator = 7; /* Saw/Square. May need dispatch for tri when both off */ dispatch[FIRST_DEV + 21].controller = 1; dispatch[FIRST_DEV + 21].operator = 4; dispatch[FIRST_DEV + 22].controller = 1; dispatch[FIRST_DEV + 22].operator = 6; /* Osc waveforms need a dispatcher to enable tri with both buttons off. */ dispatch[FIRST_DEV + 15].routine = dispatch[FIRST_DEV + 17].routine = dispatch[FIRST_DEV + 18].routine = dispatch[FIRST_DEV + 21].routine = dispatch[FIRST_DEV + 22].routine = (synthRoutine) obxWaveform; /* Filter - some routing switches */ dispatch[FIRST_DEV + 23].controller = 4; dispatch[FIRST_DEV + 23].operator = 0; dispatch[FIRST_DEV + 24].controller = 4; dispatch[FIRST_DEV + 24].operator = 1; dispatch[FIRST_DEV + 25].controller = 4; dispatch[FIRST_DEV + 25].operator = 2; /* Routing switches. Need to check on KBD tracking though */ dispatch[FIRST_DEV + 26].controller = 126; dispatch[FIRST_DEV + 26].operator = 12; dispatch[FIRST_DEV + 27].controller = 4; dispatch[FIRST_DEV + 27].operator = 3; dispatch[FIRST_DEV + 28].controller = 126; dispatch[FIRST_DEV + 28].operator = 14; dispatch[FIRST_DEV + 29].controller = 126; dispatch[FIRST_DEV + 29].operator = 15; dispatch[FIRST_DEV + 30].controller = 126; dispatch[FIRST_DEV + 30].operator = 16; dispatch[FIRST_DEV + 31].controller = 126; dispatch[FIRST_DEV + 31].operator = 17; /* Envelopes */ dispatch[FIRST_DEV + 32].controller = 3; dispatch[FIRST_DEV + 32].operator = 0; dispatch[FIRST_DEV + 33].controller = 3; dispatch[FIRST_DEV + 33].operator = 1; dispatch[FIRST_DEV + 34].controller = 3; dispatch[FIRST_DEV + 34].operator = 2; dispatch[FIRST_DEV + 35].controller = 3; dispatch[FIRST_DEV + 35].operator = 3; dispatch[FIRST_DEV + 36].controller = 5; dispatch[FIRST_DEV + 36].operator = 0; dispatch[FIRST_DEV + 37].controller = 5; dispatch[FIRST_DEV + 37].operator = 1; dispatch[FIRST_DEV + 38].controller = 5; dispatch[FIRST_DEV + 38].operator = 2; dispatch[FIRST_DEV + 39].controller = 5; dispatch[FIRST_DEV + 39].operator = 3; /* We need a separate dispatcher for the decay, since the reset button */ /* will affect the value. */ dispatch[FIRST_DEV + 35].routine = dispatch[FIRST_DEV + 39].routine = (synthRoutine) obxDecay; /* Master volume - gain of envelope? */ dispatch[FIRST_DEV + 40].controller = 5; dispatch[FIRST_DEV + 40].operator = 4; /* Reset of 'release' DONE */ dispatch[FIRST_DEV + 41].controller = 41; dispatch[FIRST_DEV + 41].operator = 0; dispatch[FIRST_DEV + 41].routine = (synthRoutine) obxDecay; /* Autotune */ dispatch[FIRST_DEV + 42].routine = (synthRoutine) multiTune; /* Hold - DONE (stole from Juno.....) */ dispatch[FIRST_DEV + 43].routine = (synthRoutine) obxHold; /* Master tune - Done. */ dispatch[FIRST_DEV + 44].controller = 126; dispatch[FIRST_DEV + 44].operator = 2; /* Memories. */ dispatch[MEM_START + 0].controller = 16; dispatch[MEM_START + 1].controller = 0; dispatch[MEM_START + 2].controller = 1; dispatch[MEM_START + 3].controller = 2; dispatch[MEM_START + 4].controller = 3; dispatch[MEM_START + 5].controller = 4; dispatch[MEM_START + 6].controller = 5; dispatch[MEM_START + 7].controller = 6; dispatch[MEM_START + 8].controller = 7; dispatch[MEM_START + 9].controller = 8; dispatch[MEM_START + 10].controller = 9; dispatch[MEM_START + 11].controller = 10; dispatch[MEM_START + 12].controller = 11; dispatch[MEM_START + 13].controller = 12; dispatch[MEM_START + 14].controller = 13; dispatch[MEM_START + 15].controller = 14; dispatch[MEM_START + 16].controller = 15; dispatch[MEM_START + 17].controller = 17; dispatch[MEM_START + 0].operator = MEM_START + 0; dispatch[MEM_START + 1].operator = MEM_START + 1; dispatch[MEM_START + 2].operator = MEM_START + 2; dispatch[MEM_START + 3].operator = MEM_START + 3; dispatch[MEM_START + 4].operator = MEM_START + 4; dispatch[MEM_START + 5].operator = MEM_START + 5; dispatch[MEM_START + 6].operator = MEM_START + 6; dispatch[MEM_START + 7].operator = MEM_START + 7; dispatch[MEM_START + 8].operator = MEM_START + 8; dispatch[MEM_START + 9].operator = MEM_START + 9; dispatch[MEM_START + 10].operator = MEM_START + 10; dispatch[MEM_START + 11].operator = MEM_START + 11; dispatch[MEM_START + 12].operator = MEM_START + 12; dispatch[MEM_START + 13].operator = MEM_START + 13; dispatch[MEM_START + 14].operator = MEM_START + 14; dispatch[MEM_START + 15].operator = MEM_START + 15; dispatch[MEM_START + 16].operator = MEM_START + 16; dispatch[MEM_START + 17].operator = MEM_START + 17; dispatch[MEM_START + 0].routine = dispatch[MEM_START + 1].routine = dispatch[MEM_START + 2].routine = dispatch[MEM_START + 3].routine = dispatch[MEM_START + 4].routine = dispatch[MEM_START + 5].routine = dispatch[MEM_START + 6].routine = dispatch[MEM_START + 7].routine = dispatch[MEM_START + 8].routine = dispatch[MEM_START + 9].routine = dispatch[MEM_START + 10].routine = dispatch[MEM_START + 11].routine = dispatch[MEM_START + 12].routine = dispatch[MEM_START + 13].routine = dispatch[MEM_START + 14].routine = dispatch[MEM_START + 15].routine = dispatch[MEM_START + 16].routine = dispatch[MEM_START + 17].routine = (synthRoutine) obxMemory; dispatch[FIRST_DEV + 63].routine = dispatch[FIRST_DEV + 64].routine = (synthRoutine) obxMidi; dispatch[FIRST_DEV + 63].controller = 1; dispatch[FIRST_DEV + 64].controller = 2; dispatch[RADIOSET_1].other1 = -1; dispatch[RADIOSET_2].other1 = -1; /* Tune/Gain osc-1/2 */ bristolMidiSendMsg(global.controlfd, synth->sid, 0, 2, 8192); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 2, 8192); bristolMidiSendMsg(global.controlfd, synth->sid, 0, 3, C_RANGE_MIN_1); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 3, C_RANGE_MIN_1); /* Gain on filter contour */ bristolMidiSendMsg(global.controlfd, synth->sid, 3, 4, C_RANGE_MIN_1); /* Select alt filter and pole remix */ bristolMidiSendMsg(global.controlfd, synth->sid, 4, 4, 4); bristolMidiSendMsg(global.controlfd, synth->sid, 4, 7, 4096); return(0); } /* * This will be called to make any routine specific parameters available. */ static int obxConfigure(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); brightonEvent event; if (synth == 0) { printf("problems going operational\n"); return(-1); } if (synth->flags & OPERATIONAL) return(0); printf("going operational\n"); synth->flags |= OPERATIONAL; synth->keypanel = 1; synth->keypanel2 = -1; synth->transpose = 36; synth->bank = 0; /* Don't load a memory, send a bank, location and load request. */ event.intvalue = 1; brightonParamChange(synth->win, synth->panel, MEM_START + 1, &event); brightonParamChange(synth->win, synth->panel, MEM_START + 9, &event); multiTune(synth, 0,0,0,0,0); /* loadMemory(synth, "obx", 0, 0, synth->mem.active, FIRST_DEV, 0); */ obxLoadMemory(synth, global.controlfd, synth->midichannel, 0, initmem, 0); brightonPut(win, "bitmaps/blueprints/obxshade.xpm", 0, 0, win->width, win->height); /* * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only * occurs on first paint, so we suppress the first paint, and then request * an expose here. */ event.type = BRIGHTON_EXPOSE; event.intvalue = 1; brightonParamChange(synth->win, KEY_PANEL, -1, &event); configureGlobals(synth); synth->loadMemory = (loadRoutine) obxKeyLoadMemory; return(0); } bristol-0.60.11/brighton/brightonControllers.c0000644000175000017500000014351212073600374016311 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include #include #include #include #include "brightoninternals.h" #include "brightonMini.h" #include "brightonKeys.h" #include "brightondev.h" #include "bristolmidi.h" #include "bristolmessages.h" /* * These should also go into the window structure..... */ static int confflag = 0; static brightonDevice *confdev[BRIGHTON_GANG_COUNT]; static float confval[BRIGHTON_GANG_COUNT]; extern guimain global; extern void printBrightonHelp(int); extern void printBrightonReadme(); extern void brightonSetCLIcode(char *); extern void brightonGetCLIcodes(int); //static int width = 0, height = 0; /* * kbdmap now burried in the brightonWindow structure. * * This is an array of MIDI note numbers indexed by ASCII keyboard key number * and works for top row of qwerty only: azerty, qwertz, dvorak keyboards, etc, * will need their own mapping (text configuration) files. * * Oops, in 0.20.4 this became qwerty key to button index in the GUI piano * keyboard starting from zero. */ #define KM_KEY 0 #define KM_CHAN 1 /* * This is for note on/off events, it keeps a map to supress keyrepeat events. * * It does not always work since the events are on/off sequentially so it has * been extended such that window enter/leave call XAutoRepeatOff/On(). * A better solution would be for devices to supply their repeat functionality * and have it set per device. For example buttons probably don't want this * but continuous controllers do. * * This does not need to be in the window structure as we only have a single * computer keyboard. */ static int kbdstate[128] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; char *pheader = "#\n\ # This the the MIDI controller profile, it keeps controller remappings for\n\ # converting one controller ID to another, and then defines which controllers\n\ # are tracked by which GUI devices. It may be edited manually, in which case\n\ # changes are maintained but the GUI can also alter the controller tracking\n\ # by typing , the moving the desired control.\n\ # This file is saved whenever a GUI memory is saved.\n\ #\n\ # The file contains Controller Mapping (one controller to another, for example\n\ # breath controller maps to footpedal, etc), Key Mappings for QWERTY to MIDI\n\ # note events, and Continuous Controller mappings that allow a control surface\n\ # to drive the GUI.\n\ #\n\ # Remap format is \"CM: MidiCC MidiCC\"\n\ # Keyboard map format is \"KM: ASCII MIDI_note [MIDI_chan]\"\n\ # Control format is \"CC: MidiCC panel/index [value]\"\n\ #\n\ # The values are integers from 0 to 16384, the fine resolution controller\n\ # value for the throw of this controller. If in doubt use the value 16383,\n\ # it is only relevant for ganging controllers.\n\ #\n\n"; /* * This will parse for a key from the ASCII keyboard and map it to a MIDI note * allowing the keyboard to then play the synth. */ static void brightonMapKeyboard(brightonWindow *bwin, brightonApp *app, int channel, char *param) { int from, to, chan; from = param[0]; if ((param = index(param, ' ')) == NULL) return; to = atoi(param); if ((param = index(++param, ' ')) == NULL) { /* printf("Keymap %c to %i on def channel 0\n", from, to); */ bwin->kbdmap[from][KM_KEY] = to; bwin->kbdmap[from][KM_CHAN] = 0; return; } chan = atoi(++param); bwin->kbdmap[from][KM_KEY] = to; bwin->kbdmap[from][KM_CHAN] = chan; /* printf("Keymap %c to %i on channel %i\n", from, to, chan); */ } static void brightonMapControl(brightonWindow *bwin, brightonApp *app, int channel, char *param) { int from, to; from = atoi(param); if ((param = index(param, ' ')) == NULL) { if ((param = index(param, 9)) == NULL) { /* printf("failed to get target\n"); */ return; } } to = atoi(param); if ((from < 0) || (from > 127) || (to < 0) || (to > 127)) return; bwin->midimap[from] = to; printf("Mapped %i to %i\n", from, to); } static void brightonSetNRPControl(brightonWindow *bwin, brightonApp *app, int channel, char *param) { int cc, panel, ind, i; char *pp; brightonIResource *p; float value = 0.2; cc = atoi(param); if ((pp = index(param, ' ')) == NULL) { if ((pp = index(param, 9)) == NULL) { /* printf("failed to get panel\n"); */ return; } } panel = atoi(pp); if ((pp = index(param, '/')) == NULL) { /* printf("failed to get index\n"); */ return; } ind = atoi(++pp); if ((index(pp, ' ')) == NULL) { if ((pp = index(pp, 9)) == NULL) { //printf("failed to get value\n"); value = 1.0; } else { printf("got number: %s\n", pp); value = ((float) atoi(pp)) / 16384.0; } } else { pp = index(pp, ' '); value = ((float) atoi(pp)) / 16384.0; } /* * We need some error checking */ if ((cc < 0) || (cc > bwin->nrpcount) || (panel < 0) || (panel >= app->nresources) || (ind < 0) || (ind >= app->resources[panel].ndevices)) return; /* * We now have what looks to be a valid tuple cc/panel/index. Find * the configuration code for that device and plug it into our * dispatcher. */ p = (brightonIResource *) &bwin->app->resources[panel]; for (i = 0; i < bwin->nrpcount; i++) { if (bwin->nrpcontrol[i].device == NULL) { bwin->nrpcontrol[i].device = ((struct brightonDevice *) p->devlocn[ind].dev); bwin->nrpcontrol[i].nrp = cc; break; } } } static void brightonSetControl(brightonWindow *bwin, brightonApp *app, int channel, char *param) { int cc, panel, ind, i; char *pp; brightonIResource *p; float value = 0.2, maxvalue = 0.0; cc = atoi(param); if ((pp = index(param, ' ')) == NULL) { if ((pp = index(param, 9)) == NULL) { /* printf("failed to get panel\n"); */ return; } } panel = atoi(pp); if ((pp = index(param, '/')) == NULL) { /* printf("failed to get index\n"); */ return; } ind = atoi(++pp); if ((pp = index(param, '/')) == NULL) { /* printf("failed to get index\n"); */ return; } ind = atoi(++pp); if ((index(pp, ' ')) == NULL) { if ((pp = index(pp, 9)) == NULL) { printf("failed to get value\n"); value = 1.0; } else { printf("got number: %s\n", pp); value = ((float) atoi(pp)) / 16384.0; } } else { pp = index(pp, ' '); value = ((float) atoi(pp)) / 16384.0; } /*printf("%i %i of max %i %i\n", panel, ind, app->nresources, */ /*app->resources[panel].ndevices); */ /* * We need some error checking */ if ((cc < 0) || (cc > 127) || (panel < 0) || (panel >= app->nresources) || (ind < 0) || (ind >= app->resources[panel].ndevices)) return; /* * We now have what looks to be a valid tuple cc/panel/index. Find * the configuration code for that device and plug it into our * dispatcher. */ p = (brightonIResource *) &bwin->app->resources[panel]; /* * This should not be indexed by the controller rather the device. That * way we can gang controls. Since the only data we have is the cc and * a device, we should limit the number of calls to perhaps 8? */ for (i = 0; i < BRIGHTON_GANG_COUNT; i++) { if (bwin->midicontrol[cc][i] == NULL) { bwin->midicontrol[cc][i] = ((struct brightonDevice *) p->devlocn[ind].dev); bwin->midicontrolval[cc][i] = value; /* = ((brightonDevice *) p->devlocn[ind].dev)->value; */ break; } } if (i == BRIGHTON_GANG_COUNT) { bwin->midicontrol[cc][(i = BRIGHTON_GANG_COUNT - 1)] = ((struct brightonDevice *) p->devlocn[ind].dev); bwin->midicontrolval[cc][i] = value; } /* * Build our scaling value */ for (i = 0; i < BRIGHTON_GANG_COUNT; i++) { if (bwin->midicontrolval[cc][i] > maxvalue) maxvalue = bwin->midicontrolval[cc][i]; } if (maxvalue == 0.0) bwin->midicontrolscaler[cc] = 1.0; else bwin->midicontrolscaler[cc] = 1.0 / maxvalue; /* for (i = 0; i < BRIGHTON_GANG_COUNT; i++) if (bwin->midicontrol[cc][i] != NULL) printf("MIDI CC %i->%i/%i@%x (index %i: %f scaled by %f)\n", cc, ((brightonDevice *) bwin->midicontrol[cc][i])->panel, ((brightonDevice *) bwin->midicontrol[cc][i])->index, (size_t) bwin->midicontrol[cc][i], i, bwin->midicontrolval[cc][i], bwin->midicontrolscaler[cc]); */ } /* * Parse configuration file. Read the panel and index numbers for the devices * and find the actual device configure code for the controllers. * * This will also read the midi controller value mapping file. */ void brightonReadConfiguration(brightonWindow *bwin, brightonApp *app, int channel, char *synth, char *filename) { FILE *fd; char path[1024]; char param[256]; int kmnotdone = 1, i; if (filename == NULL) printf("Read Configuration: %s (no filename)\n", synth); else printf("Read Configuration: %s %s\n", synth, filename); /* * The build the value mapping table */ bristolMidiValueMappingTable(bwin->valuemap, bwin->midimap, synth); /* * We are going to look for a cached file. If we cannot find it then we * will look for a factory version */ if (filename == NULL) sprintf(path, "%s/memory/profiles/%s", getBristolCache(synth), synth); else sprintf(path, "%s", filename); if ((fd = fopen(path, "r")) == NULL) { /* * If we could not read an explicit profile then return. */ if (filename != NULL) return; sprintf(path, "%s/memory/profiles/%s", getenv("BRISTOL"), synth); if ((fd = fopen(path, "r")) == NULL) { /* * So, no profile. Build a default mapping. */ for (i = 0; i < 256; i++) { bwin->kbdmap[i][KM_KEY] = -1; bwin->kbdmap[i][KM_CHAN] = 0; } /* * This maps the top and bottom rows such that the bottom two rows * are from the first key on the GUI keyboard and the top row the * upper octaves of the keyboards. */ bwin->kbdmap['\\'][KM_KEY] = 0; bwin->kbdmap['a'][KM_KEY] = 1; bwin->kbdmap['z'][KM_KEY] = 2; bwin->kbdmap['s'][KM_KEY] = 3; bwin->kbdmap['x'][KM_KEY] = 4; bwin->kbdmap['c'][KM_KEY] = 5; bwin->kbdmap['f'][KM_KEY] = 6; bwin->kbdmap['v'][KM_KEY] = 7; bwin->kbdmap['g'][KM_KEY] = 8; bwin->kbdmap['b'][KM_KEY] = 9; bwin->kbdmap['h'][KM_KEY] = 10; bwin->kbdmap['n'][KM_KEY] = 11; bwin->kbdmap['m'][KM_KEY] = 12; bwin->kbdmap['k'][KM_KEY] = 13; bwin->kbdmap[','][KM_KEY] = 14; bwin->kbdmap['l'][KM_KEY] = 15; bwin->kbdmap['.'][KM_KEY] = 16; bwin->kbdmap['/'][KM_KEY] = 17; bwin->kbdmap['\''][KM_KEY] = 18; bwin->kbdmap['q'][KM_KEY] = 24; bwin->kbdmap['2'][KM_KEY] = 25; bwin->kbdmap['w'][KM_KEY] = 26; bwin->kbdmap['3'][KM_KEY] = 27; bwin->kbdmap['e'][KM_KEY] = 28; bwin->kbdmap['r'][KM_KEY] = 29; bwin->kbdmap['5'][KM_KEY] = 30; bwin->kbdmap['t'][KM_KEY] = 31; bwin->kbdmap['6'][KM_KEY] = 32; bwin->kbdmap['y'][KM_KEY] = 33; bwin->kbdmap['7'][KM_KEY] = 34; bwin->kbdmap['u'][KM_KEY] = 35; bwin->kbdmap['i'][KM_KEY] = 36; bwin->kbdmap['9'][KM_KEY] = 37; bwin->kbdmap['o'][KM_KEY] = 38; bwin->kbdmap['0'][KM_KEY] = 39; bwin->kbdmap['p'][KM_KEY] = 40; bwin->kbdmap['['][KM_KEY] = 41; bwin->kbdmap['='][KM_KEY] = 42; bwin->kbdmap[']'][KM_KEY] = 43; return; } } /* * So we got a file. */ while (fgets(param, 256, fd) != NULL) { if (param[0] == '#') continue; /* printf("read line %s", param); */ if (strncmp(param, "CC", 2) == 0) brightonSetControl(bwin, app, channel, ¶m[4]); if (strncmp(param, "CLI", 3) == 0) brightonSetCLIcode(¶m[5]); if (strncmp(param, "NRP", 3) == 0) brightonSetNRPControl(bwin, app, channel, ¶m[5]); if (strncmp(param, "CM", 2) == 0) brightonMapControl(bwin, app, channel, ¶m[4]); if (strncmp(param, "KM", 2) == 0) { /* * If this is the first keymap in this file then clear out the * existing table. This has the benefit that profiles that did not * contain keymaps will inherit the existing ones however if they * do contain maps then previous maps will be cleared out when new * ones are defined. We only do this once and only if we find a * KM mapping entry. */ if (kmnotdone) { for (i = 0; i < 256; i++) { bwin->kbdmap[i][KM_KEY] = -1; bwin->kbdmap[i][KM_CHAN] = 0; } kmnotdone = 0; } brightonMapKeyboard(bwin, app, channel, ¶m[4]); } } fclose(fd); if (kmnotdone) { for (i = 0; i < 256; i++) { bwin->kbdmap[i][KM_KEY] = -1; bwin->kbdmap[i][KM_CHAN] = 0; } /* * This maps the top and bottom rows such that the bottom two rows * are from the first key on the GUI keyboard and the top row the * upper octaves of the keyboards. */ bwin->kbdmap['\\'][KM_KEY] = 0; bwin->kbdmap['a'][KM_KEY] = 1; bwin->kbdmap['z'][KM_KEY] = 2; bwin->kbdmap['s'][KM_KEY] = 3; bwin->kbdmap['x'][KM_KEY] = 4; bwin->kbdmap['c'][KM_KEY] = 5; bwin->kbdmap['f'][KM_KEY] = 6; bwin->kbdmap['v'][KM_KEY] = 7; bwin->kbdmap['g'][KM_KEY] = 8; bwin->kbdmap['b'][KM_KEY] = 9; bwin->kbdmap['h'][KM_KEY] = 10; bwin->kbdmap['n'][KM_KEY] = 11; bwin->kbdmap['m'][KM_KEY] = 12; bwin->kbdmap['k'][KM_KEY] = 13; bwin->kbdmap[','][KM_KEY] = 14; bwin->kbdmap['l'][KM_KEY] = 15; bwin->kbdmap['.'][KM_KEY] = 16; bwin->kbdmap['/'][KM_KEY] = 17; bwin->kbdmap['\''][KM_KEY] = 18; bwin->kbdmap['q'][KM_KEY] = 24; bwin->kbdmap['2'][KM_KEY] = 25; bwin->kbdmap['w'][KM_KEY] = 26; bwin->kbdmap['3'][KM_KEY] = 27; bwin->kbdmap['e'][KM_KEY] = 28; bwin->kbdmap['r'][KM_KEY] = 29; bwin->kbdmap['5'][KM_KEY] = 30; bwin->kbdmap['t'][KM_KEY] = 31; bwin->kbdmap['6'][KM_KEY] = 32; bwin->kbdmap['y'][KM_KEY] = 33; bwin->kbdmap['7'][KM_KEY] = 34; bwin->kbdmap['u'][KM_KEY] = 35; bwin->kbdmap['i'][KM_KEY] = 36; bwin->kbdmap['9'][KM_KEY] = 37; bwin->kbdmap['o'][KM_KEY] = 38; bwin->kbdmap['0'][KM_KEY] = 39; bwin->kbdmap['p'][KM_KEY] = 40; bwin->kbdmap['['][KM_KEY] = 41; bwin->kbdmap['='][KM_KEY] = 42; bwin->kbdmap[']'][KM_KEY] = 43; } } /* * Save a configuration file. This should take the panel and index numbers for * each of the devices in the table, for a specific MIDI channel, and write * them out to a file with the controller ID. */ void brightonWriteConfiguration(brightonWindow *bwin, char *synth, int channel, char *filename) { int j, i, fd, null; char path[256]; char param[256]; if (global.synths->flags & REQ_MIDI_DEBUG) printf("Write CC Configuration file: %s\n", synth); if (filename == NULL) sprintf(path, "%s/memory/profiles/%s", getBristolCache(synth), synth); else sprintf(path, "%s", filename); if ((fd = open(path, O_WRONLY|O_TRUNC|O_CREAT, 0644)) < 0) { /* * If we were requested to write a specific file but couldn't (implies * permissions or path?) then return. */ if (filename != NULL) return; sprintf(path, "%s/memory/profiles/%s", getenv("BRISTOL"), synth); /* * We are unlikey to have write permissions on the factory set, however * with no alternative we will have a go */ if ((fd = open(path, O_WRONLY|O_TRUNC|O_CREAT, 0644)) < 0) return; } /* * This could be cleaned up a bit */ null = write(fd, pheader, strlen(pheader)); for (i = 0; i < 128; i++) { if (bwin->midimap[i] == i) continue; sprintf(param, "CM: %i %i\n", i, bwin->midimap[i]); if (global.synths->flags & REQ_MIDI_DEBUG) printf("%s", param); null = write(fd, param, strlen(param)); } for (i = 0; i < 128; i++) { for (j = 0; j < BRIGHTON_GANG_COUNT; j++) { if (bwin->midicontrol[i][j] != 0) { sprintf(param, "CC: %i %i/%i %i\n", i, ((brightonDevice *) bwin->midicontrol[i][j])->panel, ((brightonDevice *) bwin->midicontrol[i][j])->index, (int) (bwin->midicontrolval[i][j] * 16384)); if (global.synths->flags & REQ_MIDI_DEBUG) printf("%s", param); null = write(fd, param, strlen(param)); } } } for (i = 0; i < bwin->nrpcount; i++) { if (bwin->nrpcontrol[i].device != NULL) { sprintf(param, "NRP: %i %i/%i\n", bwin->nrpcontrol[i].nrp, ((brightonDevice *) bwin->nrpcontrol[i].device)->panel, ((brightonDevice *) bwin->nrpcontrol[i].device)->index); if (global.synths->flags & REQ_MIDI_DEBUG) printf("%s", param); null = write(fd, param, strlen(param)); } } brightonGetCLIcodes(fd); for (i = 0; i < 256; i++) { if (bwin->kbdmap[i][KM_KEY] >= 0) { sprintf(param, "KM: %c %i %i\n", i, bwin->kbdmap[i][KM_KEY], bwin->kbdmap[i][KM_CHAN]); null = write(fd, param, strlen(param)); } } close(fd); } extern char *gplwarranty; extern char *gplconditions; void brightonControlShiftKeyInput(brightonWindow *cid, int asckey, int on, int flags) { guiSynth *synth = findSynth(global.synths, cid); if ((synth->flags & REQ_DEBUG_MASK) >= REQ_DEBUG_2) printf("control shift key handler\n"); } static void brightonFillRatios(brightonWindow *win) { float wfact, hfact; wfact = ((float) win->display->width) * 0.95 / ((float) win->template->width); hfact = ((float) win->display->height) * 0.95 / ((float) win->template->height); if (hfact > wfact) { win->maxw = win->display->width * 0.95; win->minw = win->template->width; win->minh = win->template->height; win->maxh = win->template->height * wfact; } else { win->maxh = win->display->height * 0.95; win->minw = win->template->width; win->minh = win->template->height; win->maxw = win->template->width * hfact; } } void brightonShiftKeyInput(brightonWindow *cid, int asckey, int on, int flags) { guiSynth *synth = findSynth(global.synths, cid); if ((synth->flags & REQ_DEBUG_MASK) >= REQ_DEBUG_2) printf("shift key handler\n"); switch (asckey) { case '=': /* size up */ { int nw, nh; if ((synth->flags & REQ_DEBUG_MASK) >= REQ_DEBUG_3) printf("Increase window size\n"); if ((nw = synth->win->width * 1.1) > (synth->win->display->width * 0.9)) return; if ((nh = synth->win->height * 1.1) > (synth->win->display->height * 0.9)) return; synth->win->template->width = nw; synth->win->template->height = nh; brightonFillRatios(synth->win); brightonRequestResize(synth->win, synth->win->minw, synth->win->minh); break; } case '-': /* size down */ { int nw, nh; if ((synth->flags & REQ_DEBUG_MASK) >= REQ_DEBUG_3) printf("Decrease window size\n"); if ((nw = synth->win->width * 0.9) < (synth->win->display->width * 0.1)) return; if ((nh = synth->win->height * 0.9) < (synth->win->display->height * 0.1)) return; synth->win->template->width = nw; synth->win->template->height = nh; brightonFillRatios(synth->win); brightonRequestResize(synth->win, synth->win->minw, synth->win->minh); break; } /* * Put some stuff in to return to normal size, full screen, etc */ case 65293: /* size switch - this is native return key */ if ((synth->win->width >= (synth->win->display->width * 0.9)) || (synth->win->height >= (synth->win->display->height * 0.9))) { /* Go native size */ if ((synth->flags & REQ_DEBUG_MASK) >= REQ_DEBUG_3) printf("t: %i %i\nw: %i %i\nd: %i %i\n", synth->win->template->width, synth->win->template->height, synth->win->width, synth->win->height, synth->win->display->width, synth->win->display->height); if ((synth->win->minw == 0) || (synth->win->maxw == 0)) brightonFillRatios(synth->win); brightonRequestResize(synth->win, synth->win->minw, synth->win->minh); if ((synth->flags & REQ_DEBUG_MASK) >= REQ_DEBUG_1) printf("go %i %i\n", synth->win->minw, synth->win->minh); } else { /* Go full screen */ if ((synth->flags & REQ_DEBUG_MASK) >= REQ_DEBUG_3) printf("t: %i %i\nw: %i %i\nd: %i %i\n", synth->win->minw, synth->win->minh, synth->win->width, synth->win->height, synth->win->display->width, synth->win->display->height); if ((synth->win->minw == 0) || (synth->win->maxw == 0)) brightonFillRatios(synth->win); synth->win->display->flags |= BRIGHTON_ANTIALIAS_5; brightonRequestResize(synth->win, synth->win->maxw, synth->win->maxh); if ((synth->flags & REQ_DEBUG_MASK) >= REQ_DEBUG_1) printf("go %i %i\n", synth->win->maxw, synth->win->maxh); } break; } } /* * This is called with key press and the control pressed */ void brightonControlKeyInput(brightonWindow *cid, int asckey, int on) { guiSynth *synth = findSynth(global.synths, cid); if ((synth->flags & REQ_DEBUG_MASK) >= REQ_DEBUG_2) printf("control key event %i/%i\n", asckey, on); /* * So, we are going to be looking for diverse key settings to do some stuff. * * ^S: save * ^L: (re)load * ^R: restore previous = ^L? * ^H: help * ^?: help * * ^W: show warranty * ^C: show GLP copying conditions * * plus: BME Axxe B3 Juno Odyssey Poly6 monopoly Pro10 Pro52 Pro5 RR Solina * voxM2 * mult: Bass CS80 granular OBXa(s) OBX(s) Poly800(s) pro1 Sid/2(s) Sonic6 * Stratus * locn: 2600 DX(s) Explorer MemoryMoog Mini MS20 mg1 rBass Rhodes(s) SAKs * vox * odds: bitone(+100) Jupiter (+mw) */ switch (asckey) { case '+': /* mem up */ case '=': /* mem up */ //brightonRequestResize(synth->win, synth->win->width *= 1.1, //synth->win->height*=1.1); if ((synth->flags & REQ_DEBUG_MASK) > REQ_DEBUG_2) printf("mem up\n"); if (synth->loadMemory != NULL) synth->loadMemory(synth, synth->resources->name, 0, synth->cmem + 1, synth->mem.active, 0, 0); else loadMemory(synth, synth->resources->name, 0, synth->cmem + 1, synth->mem.active, 0, 0); break; case '-': /* mem down */ case '_': /* mem down */ //brightonRequestResize(synth->win, synth->win->width *= 0.9, //synth->win->height*=0.9); if ((synth->flags & REQ_DEBUG_MASK) > REQ_DEBUG_2) printf("mem down\n"); if (synth->loadMemory != NULL) synth->loadMemory(synth, synth->resources->name, 0, synth->cmem - 1 < 0? 0: synth->cmem - 1, synth->mem.active, 0, 0); else loadMemory(synth, synth->resources->name, 0, synth->cmem - 1 < 0? 0: synth->cmem - 1, synth->mem.active, 0, 0); break; case 'h': /* help */ case '/': /* help */ printBrightonHelp(synth->synthtype); break; case 'r': /* readme */ printBrightonReadme(); break; case 'k': printf("Keyboard shortcuts\n"); printf(" 's' - save settings to current memory\n"); printf(" 'l' - (re)load current memory\n"); printf(" 'u' - (re)load current memory (undo)\n"); printf(" '-' - load memory down\n"); printf(" '+' - load memory up\n"); printf(" 'x' - exchange current with previous memory\n"); printf(" 'g' - GNU GPL copying conditions\n"); printf(" 'h' - print emulator information\n"); printf(" 'r' - print readme information\n"); printf(" 'p' - screendump to /tmp/.xpm\n"); printf(" 't' - toggle opacity\n"); printf(" 'o' - decrease opacity of patch layer\n"); printf(" 'O' - increase opacity of patch layer\n"); printf(" 'w' - GNU GPL warranty\n"); printf(" UpArrow - controller motion up (shift key accelerator)\n"); printf(" DownArrow - controller motion down (shift key accelerator)\n"); printf(" RightArrow - controller motion up (shift key accelerator)\n"); printf(" LeftArrow - controller motion down (shift key accelerator)\n"); break; case 's': /* Save */ if ((synth->flags & REQ_DEBUG_MASK) > REQ_DEBUG_2) printf("excepted save memory\n"); if (synth->saveMemory != NULL) synth->saveMemory(synth, synth->resources->name, 0, synth->cmem, 0); else saveMemory(synth, synth->resources->name, 0, synth->cmem, 0); break; case 'l': /* load */ case 'u': /* load */ if ((synth->flags & REQ_DEBUG_MASK) > REQ_DEBUG_2) printf("excepted Control load memory: %s\n", synth->resources->name); if (synth->loadMemory != NULL) synth->loadMemory(synth, synth->resources->name, 0, synth->cmem, synth->mem.active, 0, 0); else loadMemory(synth, synth->resources->name, 0, synth->cmem, synth->mem.active, 0, 0); break; case 'x': /* Toggle */ { int cmem; if ((synth->flags & REQ_DEBUG_MASK) > REQ_DEBUG_2) printf("excepted Control switch memory: %s\n", synth->resources->name); cmem = synth->cmem; if (synth->loadMemory != NULL) synth->loadMemory(synth, synth->resources->name, 0, synth->lmem, synth->mem.active, 0, 0); else loadMemory(synth, synth->resources->name, 0, synth->lmem, synth->mem.active, 0, 0); synth->lmem = cmem; break; } case 'w': /* Warranty */ printf("%s", gplwarranty); break; case 'g': /* Conditions */ printf("%s", gplconditions); break; } } /* * We now want a set of keyboard mappings that can be defined, perhaps also * one per synth and probably also in the same controller mappings file. * * Due to the may X11 does the key mapping then we will get multiple key events * for presses - the key repeat is interpretted as KeyOff/KeyOn, and they KBD * will be monophonic as a newly pressed key will replace the previously held * one. For best results we would need to disable key repeat on entering the * window. FFS. */ void brightonKeyInput(brightonWindow *cid, int asckey, int on) { guiSynth *synth = findSynth(global.synths, cid); brightonEvent event; event.type = BRIGHTON_FLOAT; event.value = 1.0; if ((asckey < 0) || (asckey > 255)) return; if ((cid->kbdmap[asckey][KM_KEY] < 0) || (cid->kbdmap[asckey][KM_KEY] > 127)) return; /* * In release -121 this just sent the MIDI note on/off to start the voices * but by popular demand (my sole vote) this should preferably cause the * GUI keyboard to track the qwerty. This means, preferably, the API should * send the keycode to the synth? That is not easy, we could better tack * it in here. * * We need some generic call back to the synth (the right synth) with the * key number and midi channel. Hm, that would work but still would not * change the graphics as that needs a call to the GUI. */ if (on) { /* Filter out key repeat. */ if ((kbdstate[cid->kbdmap[asckey][KM_KEY]] & (1 << cid->kbdmap[asckey][KM_CHAN])) == 0) { /* * We have some logic required here. Firstly, if the keypanel is * denoted as -1 then there isn't one (hammond module, ARP2600, * synthi) so use native MIDI events. If the midi channel is * zero this is the first keypanel. Otherwise the second. * * This is all slightly damaged (0.20.3) since calls directly to * the midi interface did not use transpose and those to the GUI * did. That will be changed, tranpose will be an actual call to * bristol, dropped here, but will have to change most of the * profile files that give me the qwerty mappings. I want to change * those anyway to mimic some other well known qwerty mappings. */ if (synth->keypanel < 0) bristolMidiSendMsg(global.controlfd, synth->midichannel + cid->kbdmap[asckey][KM_CHAN], BRISTOL_EVENT_KEYON, 0, cid->kbdmap[asckey][KM_KEY]); else { if ((cid->kbdmap[asckey][KM_CHAN] == 0) || (synth->keypanel2 < 0)) brightonParamChange(synth->win, synth->keypanel, cid->kbdmap[asckey][KM_KEY], &event); else { if (synth->keypanel2 > 0) brightonParamChange(synth->win, synth->keypanel2, cid->kbdmap[asckey][KM_KEY], &event); } } kbdstate[cid->kbdmap[asckey][KM_KEY]] |= 1 << cid->kbdmap[asckey][KM_CHAN]; } } else { event.value = 0.0; if (synth->keypanel < 0) bristolMidiSendMsg(global.controlfd, synth->midichannel + cid->kbdmap[asckey][KM_CHAN], BRISTOL_EVENT_KEYOFF, 0, cid->kbdmap[asckey][KM_KEY]); else { if ((cid->kbdmap[asckey][KM_CHAN] == 0) || (synth->keypanel2 < 0)) brightonParamChange(synth->win, synth->keypanel, cid->kbdmap[asckey][KM_KEY], &event); else { if (synth->keypanel2 > 0) brightonParamChange(synth->win, synth->keypanel2, cid->kbdmap[asckey][KM_KEY], &event); } } kbdstate[cid->kbdmap[asckey][KM_KEY]] &= ~(1 << cid->kbdmap[asckey][KM_CHAN]); } } /* * Since this is going to have a graphical response to a MIDI event we need * to flag that the library should be idle, then forward the event to have the * keyboard mapping change, then re-enable the interface. If this is not done * then events may 'double strike', once in the engine and again here in the * GUI. Eventually we want to have this link optional so as not to waste CPU * cycles for live work. */ void brightonMidiNoteEvent(guimain *global, bristolMidiMsg *msg) { brightonEvent event; int flag; if (global->home == NULL) return; event.type = BRIGHTON_FLOAT; event.value = 1.0; if (global->synths->flags & REQ_MIDI_DEBUG) printf("brightonMidiNoteEvent(%i, %i) %i\n", msg->command, msg->params.key.key, msg->channel); /* * This tracking can only work for the first synth on the list. That is * currently not an issue since the list is probably only one entry. That * will have to change when we integrate GUI menuing to start more * emulations. * * Anyway, NO_KEYTRACK can stay as a global parameter, after that we will * have to scan for MIDI channel matching. if ((global->synths == NULL) || (global->synths->flags & NO_KEYTRACK)) */ if (global->synths->flags & NO_KEYTRACK) return; flag = global->libtest; global->libtest = 1; if (global->manual != 0) global->manual->libtest = 1; if (msg->command == MIDI_NOTE_ON) { /* if ((msg->params.key.key < global->synths->lowkey) || (msg->params.key.key > global->synths->highkey)) return; */ if (msg->params.key.velocity == 0) event.value = 0.0; else event.value = ((float) msg->params.key.velocity) / 127; if (msg->channel == global->synths->midichannel) brightonParamChange(global->synths->win, global->synths->keypanel, msg->params.key.key - global->synths->transpose, &event); else if ((global->synths->keypanel2 >= 0) && (msg->channel == global->synths->midichannel + 1)) brightonParamChange(global->synths->win, global->synths->keypanel2, msg->params.key.key - global->synths->transpose, &event); } else { /* if ((msg->params.key.key < global->synths->lowkey) || (msg->params.key.key > global->synths->highkey)) return; */ event.value = 0.0; if (msg->channel == global->synths->midichannel) brightonParamChange(global->synths->win, global->synths->keypanel, msg->params.key.key - global->synths->transpose, &event); else if ((global->synths->keypanel2 >= 0) && (msg->channel == global->synths->midichannel + 1)) brightonParamChange(global->synths->win, global->synths->keypanel2, msg->params.key.key - global->synths->transpose, &event); } global->libtest = flag; if (global->manual != 0) global->manual->libtest = flag; return; } void brightonChangeParam(guiSynth *synth, int panel, int ind, float value) { brightonEvent event; brightonIResource *p; event.type = BRIGHTON_FLOAT; event.type = BRIGHTON_PARAMCHANGE; event.value = value; if (panel < 0) return; if (panel >= synth->win->app->nresources) return; if (ind < 0) return; if (ind >= synth->win->app->resources[panel].ndevices) return; p = (brightonIResource *) &synth->win->app->resources[panel]; if ((p->devlocn[ind].type == 2) && (~p->devlocn[ind].flags & BRIGHTON_THREEWAY)) { if (value < ((brightonDevice *) synth->win->app->resources[panel].devlocn[ind].dev)->value) event.value = 0.0f; else event.value = 1.0f; } if (event.value < 0) event.value = 0.0f; if (event.value > p->devlocn[ind].to) event.value = p->devlocn[ind].to; /* * This might look odd, but if the 'to' is not 1.0 then the * interface expects 'N' integral steps so we have to round * value here. We perhaps should use 'truncf()'. if (p->devlocn[ind].to != 1.0) event.value = (float) ((int) (event.value * p->devlocn[ind].to)); */ /* * See if we need to reverse the value already, and to scale * it to a native controller range. There are other cases, such * as "from > to" without the REVERSE flag, etc. Will address * them on a case by case basis. if (p->devlocn[ind].flags & BRIGHTON_REVERSE) event.value = 1.0 - event.value; printf("\r%f %f %f", value, event.value, p->devlocn[ind].to); */ brightonParamChange(synth->win, panel, ind, &event); /* printf(" %f\n\r", ((brightonDevice *) synth->win->app->resources[panel].devlocn[ind].dev)->value); */ } /* * Common dispatch routine for controller to GUI events. Needs to find the * right synth, not trivial - may have multiple on this channel, then needs to * call parsing and mapping for each. */ void brightonMidiInput(bristolMidiMsg *msg, guimain *global) { int i, j; float maxvalue = 0.0; guiSynth *synth; if (global->synths == 0) return; if (global->synths->flags & REQ_MIDI_DEBUG) printf("brightonMidiInput: %x %i: from %i, cfg %i\n", msg->command, msg->channel, msg->params.bristol.from, global->controlfd); if (msg->command == MIDI_SYSTEM) { int memHold = global->synths->cmem; if (global->synths->flags & REQ_MIDI_DEBUG) printf("brightonMidiInput sysex\n"); /* printf("brightonMidiInput sysex: %i %i, %i\n", msg->command, msg->channel, global->synths->midichannel); * We need to see if anybody is waiting for a message */ if (msg->params.bristol.msgType >= 8) { switch (msg->params.bristolt2.operation) { case BRISTOL_MT2_WRITE: /* * The brighton load/save routines do not really handle * alternative locations, they all rotate around the cache. * * To support Jack here, and LADI later, then just save the * LADI memory file and copy it to wherever it was asked * to be put. */ printf("bsm save request to \"%s\"\n", msg->params.bristolt2.data); global->synths->cmem = global->synths->ladimem; brightonControlKeyInput(global->synths->win, 's', 0); bristolMemoryExport(global->synths->ladimem, msg->params.bristolt2.data, global->synths->resources->name); global->synths->cmem = memHold; break; case BRISTOL_MT2_READ: printf("bsm load request from \"%s\"\n", msg->params.bristolt2.data); bristolMemoryImport(global->synths->ladimem, msg->params.bristolt2.data, global->synths->resources->name); global->synths->cmem = global->synths->ladimem; brightonControlKeyInput(global->synths->win, 'l', 0); global->synths->cmem = memHold; break; } } else if (msg->params.bristol.operator == BRISTOL_LADI) { if (msg->params.bristol.controller == BRISTOL_LADI_SAVE_REQ) { printf("LADI save state request\n"); global->synths->cmem = global->synths->ladimem; brightonControlKeyInput(global->synths->win, 's', 0); global->synths->cmem = memHold; } if (msg->params.bristol.controller == BRISTOL_LADI_LOAD_REQ) { printf("LADI load state request\n"); global->synths->cmem = global->synths->ladimem; brightonControlKeyInput(global->synths->win, 'l', 0); global->synths->cmem = memHold; } } bristolMidiPost(msg); return; } if (global == NULL) return; #warning that we need to scan the synths to match the MIDI channel if ((synth = global->synths) == NULL) return; if (~synth->flags & OPERATIONAL) return; if (global->synths->flags & REQ_DEBUG_3) printf("not sysex: %x\n", msg->command); /* * We should consider what to do with channel changes, but we are not * responsible for those. This is what the controller sent although we * could copy the values across from one table to the other? * * We should also consider an interface to allow for note on/off events, * it would need to register with panel ID and transpose. * We should also consider an interface to allow for pitch wheel * reregistration. */ if (((msg->command & MIDI_COMMAND_MASK) == MIDI_NOTE_ON) || ((msg->command & MIDI_COMMAND_MASK) == MIDI_NOTE_OFF)) { if (global->synths->flags & REQ_DEBUG_3) printf("note event: %x\n", msg->command); brightonMidiNoteEvent(global, msg); return; } if (msg->command != MIDI_CONTROL) { if (msg->command == MIDI_PROGRAM) { /* printf("need a callback for this: prg %i\n", msg->params.program.p_id); * So who should have the callback. It is really a window function * however it only has callbacks for X Events, not MIDI events. * * This callback template is not used, it requires a window, then * a couple of ints and a float. Should we use controller and * value? */ if ((msg->channel == synth->midichannel) && (synth->win->template->callback != 0)) synth->win->template->callback(synth->win, msg->command, msg->params.program.p_id, 0); } return; } /* * At this point there are only control messages left. I want to have a * mapping of the controller value as well as the controller mapping and * the value should be translated first. bristolMidiToGM2(synth->win, msg); */ //printf("PRE: %f\n", msg->params.controller.c_val); bristolMidiToGM2(synth->win->GM2values, synth->win->midimap, synth->win->valuemap, msg); //printf("POST: %f\n", msg->params.controller.c_val); /* * This should search the synth list, here we just assume one synth per * GUI and that is damaged for dual manual synths. Only affects the GUI. * We should search for the MIDI channel by sid and sid2 - if sid2 then * the event is potentially for the second manual. */ if (msg->channel != synth->midichannel) return; /*printf("Midi Ctrl: %i\n", msg->GM2.c_id); */ if ((msg->params.controller.c_id == MIDI_GM_DATAENTRY_F) && (synth->flags & REQ_MIDI_DEBUG)) { /* * The GM2 conversions bury the controller ID in coarse for * the NRP operations. */ printf("found nrp: %i value %i\n", (synth->win->GM2values[MIDI_GM_NRP] << 7) + synth->win->GM2values[MIDI_GM_NRP_F], (synth->win->GM2values[MIDI_GM_DATAENTRY] << 7) + synth->win->GM2values[MIDI_GM_DATAENTRY_F]); printf(" %i %i %i %i: %i %i/%f (%i)\n", synth->win->GM2values[MIDI_GM_NRP], synth->win->GM2values[MIDI_GM_NRP_F], synth->win->GM2values[MIDI_GM_DATAENTRY], synth->win->GM2values[MIDI_GM_DATAENTRY_F], msg->GM2.coarse, msg->GM2.intvalue, msg->GM2.value, msg->GM2.c_id); } if (confflag > 0) { /* * Skip NRP/RP/DE if we have not allowed NRP */ if ((msg->params.controller.c_id == MIDI_GM_DATAENTRY) || (msg->params.controller.c_id == MIDI_GM_NRP) || (msg->params.controller.c_id == MIDI_GM_NRP_F) || (msg->params.controller.c_id == MIDI_GM_RP_F)) return; /* * React to MIDI_GM_DATAENTRY_F, find NRP, find value, decide where * to dispatch. */ if ((msg->GM2.c_id == MIDI_GM_NRP) && (msg->params.controller.c_id == MIDI_GM_DATAENTRY_F)) { confflag = 0; if (~synth->flags & GUI_NRP) { printf("NRP Registration Requests require -gnrp\n"); return; } if (synth->flags & REQ_MIDI_DEBUG) { /* * The GM2 conversions bury the controller ID in coarse for * the NRP operations. */ printf("register nrp: %i value %i\n", (synth->win->GM2values[MIDI_GM_NRP] << 7) + synth->win->GM2values[MIDI_GM_NRP_F], (synth->win->GM2values[MIDI_GM_DATAENTRY] << 7) + synth->win->GM2values[MIDI_GM_DATAENTRY_F]); printf(" %i %i %i %i: %i %i\n", synth->win->GM2values[MIDI_GM_NRP], synth->win->GM2values[MIDI_GM_NRP_F], synth->win->GM2values[MIDI_GM_DATAENTRY], synth->win->GM2values[MIDI_GM_DATAENTRY_F], msg->GM2.coarse, msg->GM2.intvalue); } /* * Now need to decide what to do. Firstly, drop ganging of NRP for * the time being, may build a second table of NRP registrations * where the table contains N entries only. We will insert this * NRP into the first free entry, then later when we are given NRP * messages we will search for them in this table. * * In the longer term we need to rewrite this to get rid of the * internal MIDI references, convert MIDI CC/RP/NRP, etc, into * an internal format in the library and then handle them here in * a common fashion. Perhaps this table will do that however then * it would need to support ganging. */ /* * Until we have ganging support, clear any old registrations. */ for (i = 0; i < synth->win->nrpcount; i++) { if ((synth->win->nrpcontrol[i].nrp == msg->GM2.coarse) && (synth->win->nrpcontrol[i].device != NULL)) { printf("NRP Controller Registration Cleared: %i@%p\n", synth->win->nrpcontrol[i].nrp, synth->win->nrpcontrol[i].device); synth->win->nrpcontrol[i].nrp = -1; synth->win->nrpcontrol[i].device = NULL; } } if (confdev[0] == NULL) return; for (i = 0; i < synth->win->nrpcount; i++) { if (synth->win->nrpcontrol[i].device == NULL) { synth->win->nrpcontrol[i].nrp = msg->GM2.coarse; synth->win->nrpcontrol[i].device = (struct brightonDevice *) confdev[0]; printf("NRP Controller Registration Honoured: %i@%p\n", synth->win->nrpcontrol[i].nrp, synth->win->nrpcontrol[i].device); confdev[0] = 0; return; } } } if (msg->GM2.c_id >= 127) { /* This should not happen so flag it */ printf("Current support limited to first 128 RP/NRP\n"); confflag = 0; return; } /* * Link this CC to the given device, by MIDI channel? This also * needs to be made into a GM-2 controller (perhaps that should * be buried in the MIDI MSG structure - native and GM-2?) */ for (j = 0; j < BRIGHTON_GANG_COUNT; j++) { if (confdev[j] == 0) continue; for (i = 0; i < BRIGHTON_GANG_COUNT; i++) { if ((brightonDevice *) synth->win->midicontrol[msg->GM2.c_id][i] == confdev[j]) { printf("Controller Registration Cleared: %i -> %i/%i@%p\n", msg->GM2.c_id, confdev[j]->panel, confdev[j]->index, confdev[j]); synth->win->midicontrol[msg->GM2.c_id][i] = 0; break; } else { if (synth->win->midicontrol[msg->GM2.c_id][i] != 0) { if (synth->win->midicontrolval[msg->GM2.c_id][i] > maxvalue) maxvalue = synth->win->midicontrolval[msg->GM2.c_id][i]; continue; } synth->win->midicontrol[msg->GM2.c_id][i] = (struct brightonDevice *) confdev[j]; synth->win->midicontrolval[msg->GM2.c_id][i] = confval[j]; /* = ((brightonDevice *) confdev[j])->value; */ printf("Controller Registration Honoured: %i -> %i/%i@%p %f\n", msg->GM2.c_id, confdev[j]->panel, confdev[j]->index, confdev[j], confval[j]); /* if (synth->win->midicontrolval[msg->GM2.c_id][i] */ /* > maxvalue) */ /* maxvalue = synth->win->midicontrolval[msg->GM2.c_id][i]; */ break; } } } confflag = 0; for (i = 0; i < BRIGHTON_GANG_COUNT; i++) { if (synth->win->midicontrolval[msg->GM2.c_id][i] > maxvalue) maxvalue = synth->win->midicontrolval[msg->GM2.c_id][i]; confdev[i] = 0; } /* * We now have a max value, we need to work on a scaler such that * this gang will scale to max */ if (maxvalue == 0.0f) { synth->win->midicontrolscaler[msg->GM2.c_id] = 1.0; } else { synth->win->midicontrolscaler[msg->GM2.c_id] = 1.0 / maxvalue; } } else { brightonEvent event; if ((msg->params.controller.c_id == MIDI_GM_DATAENTRY) || (msg->params.controller.c_id == MIDI_GM_NRP) || (msg->params.controller.c_id == MIDI_GM_NRP_F) || (msg->params.controller.c_id == MIDI_GM_RP) || (msg->params.controller.c_id == MIDI_GM_RP_F)) return; if (msg->GM2.c_id == MIDI_GM_NRP) { if (~synth->flags & GUI_NRP) return; if (synth->flags & REQ_MIDI_DEBUG) printf("NRP Message %i\n", msg->GM2.coarse); for (i = 0; i < synth->win->nrpcount; i++) { if (synth->win->nrpcontrol[i].nrp == msg->GM2.coarse) { brightonIResource *p; int panel, cc, ind, channel; if (synth->flags & REQ_MIDI_DEBUG) printf("Found %i@%p\n", synth->win->nrpcontrol[i].nrp, synth->win->nrpcontrol[i].device); panel = ((brightonDevice *) synth->win->nrpcontrol[i].device)->panel; ind = ((brightonDevice *) synth->win->nrpcontrol[i].device)->index; cc = msg->GM2.c_id; channel = msg->channel; event.value = msg->GM2.value; event.command = event.type = BRIGHTON_PARAMCHANGE; p = (brightonIResource *) &synth->win->app->resources[panel]; /* * See if we need to reverse the value already, and to scale * it to a native controller range. There are other cases, such * as "from > to" without the REVERSE flag, etc. Will address * them on a case by case basis. */ if (p->devlocn[ind].flags & BRIGHTON_REVERSE) event.value = 1.0 - event.value; /* * This might look odd, but if the 'to' is not 1.0 then the * interface expects 'N' integral steps so we have to round * value here. We perhaps should use 'truncf()'. */ if (p->devlocn[ind].to != 1.0) event.value = (float) ((int) (event.value * p->devlocn[ind].to)); /* if (((brightonDevice *) synth->win->midicontrol[msg->GM2.c_id][i])->device == 1) event.value = 1.0 - event.value; */ /* printf( */ /* "synth->win->midicontrol[%i][%i]->%x(%x, &event): %f\n", */ /* msg->GM2.c_id, */ /* msg->channel, */ /* synth->win->midicontrol[msg->GM2.c_id]->configure, */ /* synth->win->midicontrol[msg->GM2.c_id], */ /* event.value); */ ((brightonDevice *) synth->win->nrpcontrol[i].device)->configure( synth->win->nrpcontrol[i].device, &event); } } return; } /* * If this was bank select pass it to the synth */ if (msg->GM2.c_id == 0) { if ((msg->channel == synth->midichannel) && (synth->win->template->callback != 0)) synth->win->template->callback(synth->win, MIDI_BANK_SELECT, msg->GM2.intvalue, 0); return; } /* * This next routine should use a parser on the message that will * build a GM-2 value into the msg, this will take care of things like * controllers that have fine and coarse resolution and will suitably * adjust the value to a suitable float, also changing the controller * number if this is the fine adjustment of a coarse control. This * may already have been done by the library? */ for (i = 0; i < BRIGHTON_GANG_COUNT; i++) { if (synth->win->midicontrol[msg->GM2.c_id][i] != 0) { brightonIResource *p; int panel, cc, ind, channel; panel = ((brightonDevice *) synth->win->midicontrol[msg->GM2.c_id][i])->panel; ind = ((brightonDevice *) synth->win->midicontrol[msg->GM2.c_id][i])->index; cc = msg->GM2.c_id; channel = msg->channel; /* * This value needs to be scaled according to the limits that * were set by the original registration. We should check for * max values. */ /* event.value = msg->GM2.value; */ if ((event.value = msg->GM2.value * synth->win->midicontrolval[msg->GM2.c_id][i] * synth->win->midicontrolscaler[msg->GM2.c_id]) > 1.0) event.value = 1.0; event.command = event.type = BRIGHTON_PARAMCHANGE; p = (brightonIResource *) &synth->win->app->resources[panel]; /* * See if we need to reverse the value already, and to scale * it to a native controller range. There are other cases, such * as "from > to" without the REVERSE flag, etc. Will address * them on a case by case basis. */ if (p->devlocn[ind].flags & BRIGHTON_REVERSE) event.value = 1.0 - event.value; /* * This might look odd, but if the 'to' is not 1.0 then the * interface expects 'N' integral steps so we have to round * value here. We perhaps should use 'truncf()'. */ if (p->devlocn[ind].to != 1.0) event.value = (float) ((int) (event.value * p->devlocn[ind].to)); /* if (((brightonDevice *) synth->win->midicontrol[msg->GM2.c_id][i])->device == 1) event.value = 1.0 - event.value; */ /* printf( */ /* "synth->win->midicontrol[%i][%i]->%x(%x, &event): %f\n", */ /* msg->GM2.c_id, */ /* msg->channel, */ /* synth->win->midicontrol[msg->GM2.c_id]->configure, */ /* synth->win->midicontrol[msg->GM2.c_id], */ /* event.value); */ ((brightonDevice *) synth->win->midicontrol[msg->GM2.c_id][i])->configure( synth->win->midicontrol[msg->GM2.c_id][i], &event); } } } } /* * Common dispatch routine for Event selection to controller events. */ void brightonRegisterController(brightonDevice *dev) { int i; for (i = 0; i < BRIGHTON_GANG_COUNT; i++) { if (confdev[i] == dev) { printf("Controller Registration %i Cleared: ? -> %i/%i@%p\n", i, dev->panel, dev->index, dev); confdev[i] = 0; if (--confflag <= 0) { confflag = 0; for (i = 0; i < BRIGHTON_GANG_COUNT; i++) confdev[i] = 0; } return; } } /* * This should go into a table. Then, when we get the target controller * we change the device value and consider a paramchange message to be * sent to update the GUI (and send the value?). confflag = 0; confdev = dev; */ for (i = 0; i < BRIGHTON_GANG_COUNT; i++) { if (confdev[i] == 0) { confdev[i] = dev; if (dev->device == 1) confval[i] = 1.0 - dev->value; else confval[i] = dev->value; if (confval[i] == 0.0) confval[i] = 1.0; break; } } if (++confflag >= BRIGHTON_GANG_COUNT) { confflag = BRIGHTON_GANG_COUNT; confdev[BRIGHTON_GANG_COUNT - 1] = dev; } printf("Controller Registration %i Request: ? -> %i/%i@%p %f\n", i, dev->panel, dev->index, dev, dev->value); } bristol-0.60.11/brighton/brightonJupiter.c0000644000175000017500000026100311746476475015444 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include #include "brighton.h" #include "brightonMini.h" #include "brightoninternals.h" #include "bristolarpeggiation.h" static int jupiterInit(); static int jupiterConfigure(); static int jupiterCallback(brightonWindow *, int, int, float); static int midiCallback(brightonWindow *, int, int, float); static void jupiterSetSplit(guiSynth *); static void jupiterSetVoices(guiSynth *); extern guimain global; static guimain manual; static float *pcache; static float *scache; #define MODE_SINGLE 0 #define MODE_SPLIT 1 #define MODE_LAYER 2 static int debuglevel = 0; static int setsplit = 0; static int mode = MODE_SINGLE; static int seqLearn = 0, chordLearn = 0; static void jupiterSetSplit(guiSynth *); static int jupiterKeyCallback(brightonWindow *, int, int, float); #include "brightonKeys.h" /* * These are a pair of double click timers and mw is a memory weighting to * scale the 64 available memories into banks of banks */ static int dc1, mw = 0; #define DEVICE_COUNT 134 #define LAYER_DEVS 65 /* 65 voice devices */ #define REAL_DEVS 92 /* 65 layer + 14 mod + 9 dummy + 4 reserved */ #define ACTIVE_DEVS (REAL_DEVS + 9) /* 19 arpeg/mode buttons */ #define MEM_MGT (ACTIVE_DEVS + 5) #define MIDI_MGT (MEM_MGT + 18) #define FUNCTION (MIDI_MGT + 3) #define KEY_HOLD 7 #define CHORUS 32 #define PATCH_BUTTONS MEM_MGT #define BANK_BUTTONS (MEM_MGT + 9) #define LOAD_BUTTON (MEM_MGT + 8) #define KEY_PANEL 1 #define MODS_PANEL 2 /* For dual load options */ #define MY_MEM (REAL_DEVS - 1) #define MEM_LINK (REAL_DEVS - 2) #define SPLIT_POINT (REAL_DEVS - 3) #define FUNCTION_SAVE (REAL_DEVS - 4) #define MOD_ENABLE 94 #define ARPEG_RANGE 53 #define ARPEG_MODE 57 #define POLY_MODE 61 #define SEQ_MODE (DEVICE_COUNT - 6) #define HOLD_LOWER (REAL_DEVS) #define MOD_LOWER (REAL_DEVS + 2) #define MOD_UPPER (REAL_DEVS + 3) #define MODE_DUAL (REAL_DEVS + 4) #define KEY_MODE MODE_DUAL #define PANEL_SELECT (ACTIVE_DEVS + 4) #define DISPLAY_DEV (DEVICE_COUNT - 5) /* * This structure is for device definition. The structure is defined in * include/brighton.h, further definitions in brighton/brightonDevtable.h and * include/brightoninternals.h * * typedef int (*brightonCallback)(int, float); * typedef struct BrightonLocations { * int device; 0=rotary, 1=scale, etc. * float relx, rely; relative position with regards to 1000 by 1000 window * float relw, relh; relative height. * int from, to; * brightonCallback callback; specific to this dev * char *image; bitmap. If zero take a device default. * int flags; * } brightonLocations; * * This example is for a jupiterBristol type synth interface. */ #define D3 80 #define BR1 300 #define BR2 BR1 + D3 #define BR3 BR2 + D3 #define BR4 BR3 + D3 #define MBR2 BR4 #define MBR1 MBR2 - 100 #define MBR3 MBR2 + 100 #define MBR4 MBR3 + 100 #define R2 390 #define R1 (R2 + 130) #define R3 (R2 + 100) #define R4 650 #define JR1 90 #define JR2 JR1 - 20 #define JR3 JR1 - 30 #define RB1 430 #define RB2 (RB1 + JR3 + 2) #define RB3 (RB2 + JR3 + 2) #define RB4 (RB3 + JR3 + 2) #define RB5 (RB4 + JR3 + 2) #define D1 (980 / 41) #define D2 (D1 + 11) #define C1 (13) #define C2 (C1 + D2) #define C3 (C2 + D2) #define C4 (C3 + D1) #define C5 (C4 + D1) #define C6 (C5 + D1 - 6) #define C7 (C6 + D2 - 3) #define C8 (C7 + D2 - 1) #define C9 (C8 + D1 - 6) #define C10 (C9 + D1 - 7) #define C10a (C9 + D1 + 22) #define C11 (C10 + D1 + 22) #define C12 (C11 + D1) #define C13 (C12 + D1 - 5) #define C13a (C12 + D1 + 14) #define C14 (C13 + D1 + 9) #define C15 (C14 + D2 - 9) #define C16 (C15 + D2 + 2) #define C17 (C16 + D1 + 0) #define C18 (C17 + D1 - 6) #define C19 (C18 + D2 - 3) #define C20 (C19 + D2 - 2) #define C21 (C20 + D2) #define C22 (C21 + D2) #define C23 (C22 + D1) #define C24 (C23 + D1 - 6) #define C25 (C24 + D1 - 8) #define C26 (C25 + D1 + 2) #define C27 (C26 + D1 - 2) #define C28 (C27 + D1 - 4) #define C29 (C28 + D1 - 6) #define C30 (C29 + D1 - 1) #define C31 (C30 + D1 - 6) #define C32 (C31 + D1) #define C33 (C32 + D1 - 6) #define C34 (C33 + D1 - 6) #define C35 (C34 + D1 - 7) #define C36 (C35 + D1 - 2) #define C37 (C36 + D1 - 4) #define C38 (C37 + D1) #define C39 (C38 + D1 - 6) #define C40 (C39 + D1 - 6) #define C41 (C40 + D1 - 7) #define C42 (C41 + D1 - 2) #define W1 12 #define L1 310 #define S2 120 #define BS1 17 #define BS2 100 #define BS3 125 #define BS4 15 #define BS5 160 /* Selector buttons */ #define JBS 14 #define JBH 80 #define JBD 18 #define JBD2 8 #define JBD3 17 #define JBD4 5 #define JBC1 60 #define JBC2 (JBC1 + JBD + JBD2) #define JBC3 (JBC2 + JBD3) #define JBC4 (JBC3 + JBD3) #define JBC5 (JBC4 + JBD3) #define JBC6 (JBC5 + JBD3 + JBD4) #define JBC7 (JBC6 + JBD3) #define JBC8 (JBC7 + JBD3) #define JBC9 (JBC8 + JBD3) #define JBC9a (JBC9 + JBD3 + JBD4) #define JBC10 (JBC9a + JBD + JBD4 - 3) #define JBC11 (JBC10 + JBD) #define JBC12 (JBC11 + JBD) #define JBC13 (JBC12 + JBD) /* #define JBC14 (JBC13 + JBD + JBD2) */ #define JBC14 (326) #define JBC15 (JBC14 + JBD) #define JBC16 (JBC15 + JBD + JBD2) #define JBC17 (JBC16 + JBD) #define JBC18 (JBC17 + JBD) #define JBC19 (JBC18 + JBD) #define JBC20 (JBC19 + JBD) #define JBC20_2 (JBC20 + JBD + JBD2) /* Second half of buttons */ #define JBC21 (JBC1 + 512) #define JBC22 (JBC21 + JBD) #define JBC23 (JBC22 + JBD) #define JBC24 (JBC23 + JBD) #define JBC25 (JBC24 + JBD) #define JBC26 (JBC25 + JBD) #define JBC27 (JBC26 + JBD) #define JBC28 (JBC27 + JBD) #define JBC29 (JBC28 + JBD + JBD2) #define JBC30 (JBC29 + JBD) #define JBC31 (JBC30 + JBD) #define JBC32 (JBC31 + JBD) #define JBC33 (JBC32 + JBD) #define JBC34 (JBC33 + JBD) #define JBC35 (JBC34 + JBD) #define JBC36 (JBC35 + JBD) #define JBC37 (JBC36 + JBD + JBD2 - 2) #define JBC38 (JBC37 + JBD + 4) #define JBC39 (JBC38 + JBD + JBD2) #define JBC40 (JBC39 + JBD) #define JBC41 (JBC40 + JBD) #define JBC42 (JBC41 + JBD) #define JBCD (JBC1 + 440) /* 42 lines controls, 43rd in button line, then 41 buttons plus display */ static brightonLocations locations[DEVICE_COUNT] = { /* 0 - LFO */ {"LFO-Rate", 1, C5, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW}, {"LFO-Delay", 1, C6, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW}, {"LFO-Waveform", 0, C7 - 4, R1, JR1, JR1, 0, 3, 0, "bitmaps/knobs/knob1.xpm", 0, BRIGHTON_STEPPED}, /* 3 - mods */ {"Mod-LFO-lvl", 1, C8, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW}, {"Mod-Env-lvl", 1, C9, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW}, {"Mod-Osc1/2", 2, C10, R1 - 20, 10, JR2 + 35, 0, 2, 0, 0, 0, BRIGHTON_NOSHADOW|BRIGHTON_THREEWAY}, {"Mod-PWM", 1, C11, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW}, /* PWM */ {"ModPWM-EnvLFO", 2, C12, R1, 10, JR2, 0, 1.01, 0, "bitmaps/buttons/sw1.xpm", "bitmaps/buttons/sw2.xpm", BRIGHTON_NOSHADOW}, {"Mod-XMod", 1, C13, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW}, /* * Transpose - replace with 4 buttons as multiselectors, this one and * three more in the 'free' section - 9 */ {"VCO1-2'", 2, C14 + 2, RB1, 11, JR3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"VCA1-4'", 2, C14 + 2, RB2, 11, JR3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"VCA1-8'", 2, C14 + 2, RB3, 11, JR3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"VCA1-16'", 2, C14 + 2, RB4, 11, JR3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* * Waveform buttons - 13 */ {"VCO1-Tri", 2, C15 + 4, RB1, 11, JR3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"VCO1-Ramp", 2, C15 + 4, RB2, 11, JR3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"VCO1-Pulse", 2, C15 + 4, RB3, 11, JR3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"VCO1-Square", 2, C15 + 4, RB4, 11, JR3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* Sync, sub - 17 */ {"VCO-Sync", 2, C16, R1 - 20, 10, JR2 + 35, 0, 2, 0, 0, 0, BRIGHTON_NOSHADOW|BRIGHTON_THREEWAY}, {"VCO2-Sub", 2, C17, R1, 10, JR2, 0, 1, 0, "bitmaps/buttons/sw1.xpm", "bitmaps/buttons/sw2.xpm", BRIGHTON_NOSHADOW}, /* * 4 transpose buttons for OSC-2. They were 5 however we already have one * button for sub wave - 19. */ {"VCO2-2'", 2, C18 + 1, RB1, 11, JR3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"VCO2-4'", 2, C18 + 1, RB2, 11, JR3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"VCO2-8'", 2, C18 + 1, RB3, 11, JR3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"VCO2-16'", 2, C18 + 1, RB4, 11, JR3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"VCO2-Tune", 0, C19, R1, JR1, JR1, 0, 1, 0, "bitmaps/knobs/knob1.xpm", 0, BRIGHTON_NOTCH}, /* * Waveform buttons - 24 */ {"VCO2-Tri", 2, C20 + 0, RB1, 11, JR3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"VCO2-Ramp", 2, C20 + 0, RB2, 11, JR3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"VCO2-Pulse", 2, C20 + 0, RB3, 11, JR3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"VCO2-Noise", 2, C20 + 0, RB4, 11, JR3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* Mix, HPF - 28 */ {"Mix Osc1/2", 0, C21, R1, JR1, JR1, 0, 1, 0, "bitmaps/knobs/knob1.xpm", 0, BRIGHTON_NOTCH}, {"HPF", 1, C22, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW}, /* Filter - 30 */ {"VCF-Cutoff", 1, C23, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW}, {"VCF-Resonance", 1, C24, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW}, {"VCF-Mode", 2, C25, R1 - 20, 10, JR2 + 35, 0, 2, 0, 0, 0, BRIGHTON_NOSHADOW|BRIGHTON_THREEWAY}, {"VCF-EnvLvl", 1, C26, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW}, {"VCF-EnvSel", 2, C27, R1, 10, JR2, 0, 1, 0, "bitmaps/buttons/sw1.xpm", "bitmaps/buttons/sw2.xpm", BRIGHTON_NOSHADOW}, {"VCF-LFO", 1, C28, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW}, {"VCF-KBD", 1, C29, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW}, /* AMP - 37 */ {"VCA-Env", 1, C30, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW}, {"VCA-LFO", 1, C31 - 1, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW}, /* {"", 1, C31 + 1, R1 - 38, 5, JR2 + 75, 0, 3, 0, "bitmaps/buttons/klunk3.xpm", 0, 0}, */ /* ADSR1 - 39 */ {"ADSR1-Attack", 1, C32 + 1, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW}, {"ADSR1-Decay", 1, C33, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW}, {"ADSR1-Sustain", 1, C34, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW}, {"ADSR1-Release", 1, C35, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW}, {"ADSR1-Kbd", 1, C36 - 6, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW}, /* {"", 2, C36, R1, 10, JR2, 0, 1, 0, "bitmaps/buttons/sw1.xpm", "bitmaps/buttons/sw2.xpm", BRIGHTON_NOSHADOW}, */ {"ADSR1-+/-", 2, C37 + 1, R1, 10, JR2, 0, 1, 0, "bitmaps/buttons/sw1.xpm", "bitmaps/buttons/sw2.xpm", BRIGHTON_NOSHADOW}, /* ADSR1 - 45 */ {"ADSR2-Attack", 1, C38 + 1, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW}, {"ADSR2-Decay", 1, C39, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW}, {"ADSR2-Sustain", 1, C40, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW}, {"ADSR2-Release", 1, C41, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW}, {"ADSR2-Kdb", 1, C42 - 6, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW}, /* {"", 2, C42, R1, 10, JR2, 0, 1, 0, "bitmaps/buttons/sw1.xpm", "bitmaps/buttons/sw2.xpm", BRIGHTON_NOSHADOW}, */ /* PWM, XMOD env - 50 */ {"Mod-Osc-PW", 1, C10a, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW}, {"Mod-XMod-Lvl", 2, C13a, R1, 10, JR2, 0, 1.01, 0, "bitmaps/buttons/sw1.xpm", "bitmaps/buttons/sw2.xpm", BRIGHTON_NOSHADOW}, /* Layer Pan */ {"Layer Pan", 0, C2, R2 + 50, JR1, JR1, 0, 1, 0, "bitmaps/knobs/knob1.xpm", 0, BRIGHTON_NOTCH}, /* Arpeg range - 53 */ {"Arpeg 1 Oct", 2, JBC2, 800, JBS, JBH, 0, 4, 0, "bitmaps/buttons/jbo.xpm", "bitmaps/buttons/jboo.xpm", 0}, {"Arpeg 2 Oct", 2, JBC3, 800, JBS, JBH, 0, 4, 0, "bitmaps/buttons/jbo.xpm", "bitmaps/buttons/jboo.xpm", 0}, {"Arpeg 3 Oct", 2, JBC4, 800, JBS, JBH, 0, 4, 0, "bitmaps/buttons/jbo.xpm", "bitmaps/buttons/jboo.xpm", 0}, {"Arpeg 4 Oct", 2, JBC5, 800, JBS, JBH, 0, 4, 0, "bitmaps/buttons/jbo.xpm", "bitmaps/buttons/jboo.xpm", 0}, /* Arpeg mode - 57 */ {"Arpeg Mode Up", 2, JBC6, 800, JBS, JBH, 0, 4, 0, "bitmaps/buttons/jby.xpm", "bitmaps/buttons/jbyo.xpm", 0}, {"Arpeg Mode Down", 2, JBC7, 800, JBS, JBH, 0, 4, 0, "bitmaps/buttons/jby.xpm", "bitmaps/buttons/jbyo.xpm", 0}, {"Arpeg Mode UpDn", 2, JBC8, 800, JBS, JBH, 0, 4, 0, "bitmaps/buttons/jby.xpm", "bitmaps/buttons/jbyo.xpm", 0}, {"Arpeg Mode Rand", 2, JBC9, 800, JBS, JBH, 0, 4, 0, "bitmaps/buttons/jby.xpm", "bitmaps/buttons/jbyo.xpm", 0}, /* Key assign mode - 61 */ {"Mode Solo", 2, JBC10, 800, JBS, JBH, 0, 4, 0, "bitmaps/buttons/jbw.xpm", "bitmaps/buttons/jbwo.xpm", 0}, {"Mode Uni", 2, JBC11, 800, JBS, JBH, 0, 4, 0, "bitmaps/buttons/jbw.xpm", "bitmaps/buttons/jbwo.xpm", 0}, {"Mode Poly1", 2, JBC12, 800, JBS, JBH, 0, 4, 0, "bitmaps/buttons/jbw.xpm", "bitmaps/buttons/jbwo.xpm", 0}, {"Mode Poly2", 2, JBC13, 800, JBS, JBH, 0, 4, 0, "bitmaps/buttons/jbw.xpm", "bitmaps/buttons/jbwo.xpm", 0}, /* Holders - 15 for mods panel - 65 */ {"", 0, 0, 0, JBH, JBH, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, JBH, JBH, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, JBH, JBH, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, JBH, JBH, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, JBH, JBH, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, JBH, JBH, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, JBH, JBH, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, JBH, JBH, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, JBH, JBH, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, JBH, JBH, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, JBH, JBH, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, JBH, JBH, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, JBH, JBH, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, JBH, JBH, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, JBH, JBH, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, /* * Dummies - 8 from 80 */ {"", 0, 0, 0, JBH, JBH, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, JBH, JBH, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, JBH, JBH, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, JBH, JBH, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, JBH, JBH, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, JBH, JBH, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, JBH, JBH, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, JBH, JBH, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, /* * These are reserved already for two memory links, split point and function * settings. From 88 */ {"", 0, 0, 0, JBH, JBH, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, JBH, JBH, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, JBH, JBH, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, {"", 0, 0, 0, JBH, JBH, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN}, /* * Total of 65 layer controls - 0 to 49 plus 30 dummies, 14 of which are * used by the mod panel. * * The above will be replicated per layer, the rest will be global to the * whole synth. */ /* * 92 - Second row Hold up/down */ {"Hold Lower", 2, JBC14, 800, JBS, JBH, 0, 4, 0, "bitmaps/buttons/jbg.xpm", "bitmaps/buttons/jbgo.xpm", 0}, {"Hold Upper", 2, JBC15, 800, JBS, JBH, 0, 4, 0, "bitmaps/buttons/jbg.xpm", "bitmaps/buttons/jbgo.xpm", 0}, /* layer mod enable - 94 */ {"Mod Layer 1", 2, JBC19, 800, JBS, JBH, 0, 1, 0, "bitmaps/buttons/jbb2.xpm", "bitmaps/buttons/jbb2o.xpm", 0}, {"Mod Layer 2", 2, JBC20, 800, JBS, JBH, 0, 1, 0, "bitmaps/buttons/jbb2.xpm", "bitmaps/buttons/jbb2o.xpm", 0}, /* Dual/Split/Layer - 96 */ {"Dual", 2, JBC16, 800, JBS, JBH, 0, 4, 0, "bitmaps/buttons/jbb1.xpm", "bitmaps/buttons/jbb1o.xpm", 0}, {"Split", 2, JBC17, 800, JBS, JBH, 0, 4, 0, "bitmaps/buttons/jbb1.xpm", "bitmaps/buttons/jbb1o.xpm", 0}, {"All", 2, JBC18, 800, JBS, JBH, 0, 4, 0, "bitmaps/buttons/jbb1.xpm", "bitmaps/buttons/jbb1o.xpm", 0}, /* * The preceeding parameters are unique per synth and need to be loaded * from different memory files? Alternatively just load the mem and let * the last loaded parameters be active for the following ones: * * From 99: * * These are global to both layers - Vol/Balance/Arpeg rate and clock * * It could be worthwhile having the arpeggiator clock within the memory? */ {"Arpeg Rate", 1, C3, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW}, {"Arpeg Int/Ext", 2, C4, R1, 10, JR2, 0, 1, 0, "bitmaps/buttons/sw1.xpm", "bitmaps/buttons/sw2.xpm", BRIGHTON_NOSHADOW}, /* Volume and Balance 101 and 102 */ {"MasterVolume", 0, C1, R2 + 50, JR1, JR1, 0, 1, 0, "bitmaps/knobs/knob1.xpm", 0, 0}, {"LayerBalance", 0, C1 +18, R1 +30, JR1, JR1, 0, 1, 0, "bitmaps/knobs/knob1.xpm", 0, BRIGHTON_NOTCH}, /* Second row, tuning - 103 */ {"MasterTuning", 0, 15, 800, JR1, JR1, 0, 1, 0, "bitmaps/knobs/knob1.xpm", 0, BRIGHTON_NOTCH}, {"Tune", 2, JBC1, 800, JBS, JBH, 0, 4, 0, "bitmaps/buttons/jbr.xpm", "bitmaps/buttons/jbro.xpm", BRIGHTON_CHECKBUTTON}, /* Panel switch - 105 */ {"LayerSelect", 2, JBC20_2, 800, JBS, JBH, 0, 1, 0, "bitmaps/buttons/jbb2.xpm", "bitmaps/buttons/jbb2o.xpm", 0}, /* Second half - memories and MIDI, not saved - 106 */ {"", 2, JBC21, 800, JBS, JBH, 0, 1, 0, "bitmaps/buttons/jbw.xpm", "bitmaps/buttons/jbwo.xpm", 0}, {"", 2, JBC22, 800, JBS, JBH, 0, 1, 0, "bitmaps/buttons/jbw.xpm", "bitmaps/buttons/jbwo.xpm", 0}, {"", 2, JBC23, 800, JBS, JBH, 0, 1, 0, "bitmaps/buttons/jbw.xpm", "bitmaps/buttons/jbwo.xpm", 0}, {"", 2, JBC24, 800, JBS, JBH, 0, 1, 0, "bitmaps/buttons/jbw.xpm", "bitmaps/buttons/jbwo.xpm", 0}, {"", 2, JBC25, 800, JBS, JBH, 0, 1, 0, "bitmaps/buttons/jbw.xpm", "bitmaps/buttons/jbwo.xpm", 0}, {"", 2, JBC26, 800, JBS, JBH, 0, 1, 0, "bitmaps/buttons/jbw.xpm", "bitmaps/buttons/jbwo.xpm", 0}, {"", 2, JBC27, 800, JBS, JBH, 0, 1, 0, "bitmaps/buttons/jbw.xpm", "bitmaps/buttons/jbwo.xpm", 0}, {"", 2, JBC28, 800, JBS, JBH, 0, 1, 0, "bitmaps/buttons/jbw.xpm", "bitmaps/buttons/jbwo.xpm", 0}, /* Load */ {"", 2, JBC37, 800, JBS, JBH, 0, 1, 0, "bitmaps/buttons/jbg.xpm", "bitmaps/buttons/jbgo.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, JBC29, 800, JBS, JBH, 0, 1, 0, "bitmaps/buttons/jbo.xpm", "bitmaps/buttons/jboo.xpm", 0}, {"", 2, JBC30, 800, JBS, JBH, 0, 1, 0, "bitmaps/buttons/jbo.xpm", "bitmaps/buttons/jboo.xpm", 0}, {"", 2, JBC31, 800, JBS, JBH, 0, 1, 0, "bitmaps/buttons/jbo.xpm", "bitmaps/buttons/jboo.xpm", 0}, {"", 2, JBC32, 800, JBS, JBH, 0, 1, 0, "bitmaps/buttons/jbo.xpm", "bitmaps/buttons/jboo.xpm", 0}, {"", 2, JBC33, 800, JBS, JBH, 0, 1, 0, "bitmaps/buttons/jby.xpm", "bitmaps/buttons/jbyo.xpm", 0}, {"", 2, JBC34, 800, JBS, JBH, 0, 1, 0, "bitmaps/buttons/jby.xpm", "bitmaps/buttons/jbyo.xpm", 0}, {"", 2, JBC35, 800, JBS, JBH, 0, 1, 0, "bitmaps/buttons/jby.xpm", "bitmaps/buttons/jbyo.xpm", 0}, {"", 2, JBC36, 800, JBS, JBH, 0, 1, 0, "bitmaps/buttons/jby.xpm", "bitmaps/buttons/jbyo.xpm", 0}, /* Save */ {"", 2, JBC38, 800, JBS, JBH, 0, 1, 0, "bitmaps/buttons/jbr.xpm", "bitmaps/buttons/jbro.xpm", BRIGHTON_CHECKBUTTON}, /* MIDI */ {"", 2, JBC39, 800, JBS, JBH, 0, 1, 0, "bitmaps/buttons/jbb1.xpm", "bitmaps/buttons/jbb1o.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, JBC40, 800, JBS, JBH, 0, 1, 0, "bitmaps/buttons/jbb1.xpm", "bitmaps/buttons/jbb1o.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, JBC41, 800, JBS, JBH, 0, 1, 0, "bitmaps/buttons/jbb2.xpm", "bitmaps/buttons/jbb2o.xpm", BRIGHTON_CHECKBUTTON}, /* Fn */ {"", 2, JBC42, 800, JBS, JBH, 0, 1, 0, "bitmaps/buttons/jbb2.xpm", "bitmaps/buttons/jbb2o.xpm", 0}, {"", 2, JBC9a, 800, JBS, JBH, 0, 4, 0, "bitmaps/buttons/jby.xpm", "bitmaps/buttons/jbyo.xpm", 0}, /* RED LED display */ {"", 8, JBCD, 813, JBS - 2, JBH - 8, 0, 9, 0, 0, 0, 0}, {"", 8, JBS + JBCD - 2, 813, JBS - 2, JBH - 8, 0, 9, 0, 0, 0, 0}, {"", 8, JBS * 2 + JBCD + 2, 813, JBS - 2, JBH - 8, 0, 9, 0, 0, 0, 0}, {"", 8, JBS * 3 + JBCD + 1 ,813, JBS - 2, JBH - 8, 0, 9, 0, 0, 0, 0}, {"", 3, JBCD, 818, 75, 55, 0, 1, 0, 0, "bitmaps/images/alphadisplay3.xpm", BRIGHTON_WITHDRAWN}, }; /* * Mod panel */ static brightonLocations jmods[15] = { {"", 1, 75, 395, 70, 505, 0, 1, 0, "bitmaps/knobs/sliderblack5.xpm", 0, 0}, {"", 1, 175, 395, 70, 505, 0, 1, 0, "bitmaps/knobs/sliderblack5.xpm", 0, 0}, {"", 1, 275, 395, 70, 505, 0, 1, 0, "bitmaps/knobs/sliderblack5.xpm", 0, 0}, {"", 1, 375, 395, 70, 505, 0, 1, 0, "bitmaps/knobs/sliderblack5.xpm", 0, 0}, {"", 2, 50, 150, 60, 160, 0, 1, 0, "bitmaps/buttons/sw1.xpm", "bitmaps/buttons/sw2.xpm", BRIGHTON_NOSHADOW}, {"", 2, 115, 150, 60, 160, 0, 1, 0, "bitmaps/buttons/sw1.xpm", "bitmaps/buttons/sw2.xpm", BRIGHTON_NOSHADOW}, {"", 2, 185, 150, 60, 160, 0, 1, 0, "bitmaps/buttons/sw1.xpm", "bitmaps/buttons/sw2.xpm", BRIGHTON_NOSHADOW}, {"", 2, 285, 150, 60, 160, 0, 1, 0, "bitmaps/buttons/sw1.xpm", "bitmaps/buttons/sw2.xpm", BRIGHTON_NOSHADOW}, {"", 2, 385, 150, 60, 160, 0, 1, 0, "bitmaps/buttons/sw1.xpm", "bitmaps/buttons/sw2.xpm", BRIGHTON_NOSHADOW}, {"", 0, 580, 130, 195, 195, 0, 1, 0, "bitmaps/knobs/knob1.xpm", 0, 0}, {"", 0, 780, 130, 195, 195, 0, 1, 0, "bitmaps/knobs/knob1.xpm", 0, 0}, {"", 2, 820, 400, 60, 200, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW}, {"", 2, 550, 400, 60, 200, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW}, {"", 2, 690, 400, 60, 200, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW}, /* {"", 2, 550, 460, 190, 130, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlw.xpm", 0}, */ {"", 1, 520, 715, 500, 100, 0, 1, 0, "bitmaps/knobs/knob8.xpm", 0, BRIGHTON_VERTICAL|BRIGHTON_CENTER|BRIGHTON_NOSHADOW|BRIGHTON_REVERSE}, }; static int jupiterDestroySynth(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); /* * Since we registered two synths, we now need to remove the upper * manual. */ bristolMidiSendMsg(manual.controlfd, synth->sid2, 127, 0, BRISTOL_EXIT_ALGO); bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_EXIT_ALGO); return(0); } /* * This is a set of globals for the main window rendering. Again taken from * include/brighton.h */ brightonApp jupiterApp = { "jupiter8", 0, "bitmaps/textures/metal4.xpm", 0, jupiterInit, jupiterConfigure, /* 3 callbacks, unused? */ midiCallback, jupiterDestroySynth, {8, 50, 32, 2, 5, 520, 0, 0}, 900, 350, 0, 0, 5, { { "Jupiter", "bitmaps/blueprints/jupiter.xpm", "bitmaps/textures/metal6.xpm", BRIGHTON_STRETCH, /* flags */ 0, 0, jupiterCallback, 5, 30, 990, 670, DEVICE_COUNT, locations }, { "Keyboard", 0, "bitmaps/newkeys/kbg.xpm", /* flags */ 0x020|BRIGHTON_STRETCH, 0, 0, jupiterKeyCallback, 180, 695, 810, 300, KEY_COUNT, keysprofile }, { "Mods", "bitmaps/blueprints/jupitermods.xpm", "bitmaps/textures/metal6.xpm", /* flags */ BRIGHTON_STRETCH, 0, 0, jupiterCallback, 5, 695, 175, 300, 15, jmods }, { "Metal Edge", 0, "bitmaps/textures/metal5.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 0, 0, 5, 1000, 0, 0 }, { "Metal Edge", 0, "bitmaps/textures/metal5.xpm", BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */ 0, 0, 0, 995, 0, 5, 1000, 0, 0 }, } }; static int jupiterDebug(guiSynth *synth, int level) { if (debuglevel >= level) return(1); return(0); } static void jupiterSeqInsert(guiSynth *synth, int note) { arpeggiatorMemory *seq = (arpeggiatorMemory *) synth->seq1.param; if (synth->mem.param[PANEL_SELECT] != 0) { printf(" Learning on upper layer\n"); seq = (arpeggiatorMemory *) synth->seq2.param; } if (seq->s_max == 0) seq->s_dif = note + synth->transpose; seq->sequence[(int) (seq->s_max)] = (float) (note + synth->transpose - seq->s_dif); if (jupiterDebug(synth, 0)) printf("Seq put %i into %i\n", (int) seq->sequence[(int) (seq->s_max)], (int) (seq->s_max)); if ((seq->s_max += 1) >= BRISTOL_SEQ_MAX) seq->s_max = BRISTOL_SEQ_MAX; } static void jupiterChordInsert(guiSynth *synth, int note) { arpeggiatorMemory *seq = (arpeggiatorMemory *) synth->seq1.param; if (synth->mem.param[HOLD_LOWER] == 0) seq = (arpeggiatorMemory *) synth->seq2.param; if (seq->c_count == 0) seq->c_dif = note + synth->transpose; seq->chord[(int) (seq->c_count)] = (float) (note + synth->transpose - seq->c_dif); if (jupiterDebug(synth, 0)) printf("Chord put %i into %i\n", (int) seq->chord[(int) (seq->c_count)], (int) (seq->c_count)); if ((seq->c_count += 1) >= BRISTOL_CHORD_MAX) seq->c_count = BRISTOL_CHORD_MAX; } static int jupiterKeyCallback(brightonWindow *win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); if (setsplit != 0) { if (jupiterDebug(synth, 1)) printf("setSplit at %i\n", index); synth->mem.param[SPLIT_POINT] = index; jupiterSetSplit(synth); } if ((chordLearn) && (value != 0)) jupiterChordInsert(synth, index); if ((seqLearn) && (value != 0)) jupiterSeqInsert(synth, index); if (global.libtest) return(0); if (jupiterDebug(synth, 2)) printf("keyCallback(%i)\n", index); /* * Want to send a note event, on or off, for this index + transpose. */ if (value) bristolMidiSendMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_KEYON, 0, index + synth->transpose); else bristolMidiSendMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_KEYOFF, 0, index + synth->transpose); return(0); } static void jupiterDualSend(guiSynth *synth, int fd, int c, int o, int v) { bristolMidiSendMsg(global.controlfd, synth->sid, c, o, v); bristolMidiSendMsg(global.controlfd, synth->sid2, c, o, v); } static void midiRelease(guiSynth *synth, int fd, int chan, int c, int o, int v) { if (jupiterDebug(synth, 1)) printf("midiRelease()\n"); if (!global.libtest) { /* * Midi release is ALL notes, ALL synths. If this behaviour (in the * engine) changes we may need to put in an all_notes_off on the * second manual as well. */ bristolMidiSendMsg(fd, synth->sid, 127, 0, BRISTOL_ALL_NOTES_OFF); } } static void modPanelFix(brightonWindow *win, guiSynth *synth) { int i; brightonEvent event; event.type = BRIGHTON_FLOAT; for (i = 0; i < 14; i++) { event.value = synth->mem.param[LAYER_DEVS + i]; brightonParamChange(win, MODS_PANEL, i, &event); } } static int midiCallback(brightonWindow *win, int controller, int value, float n) { guiSynth *synth = findSynth(global.synths, win); if (jupiterDebug(synth, 1)) printf("midi callback: %x, %i\n", controller, value); switch(controller) { case MIDI_PROGRAM: if (jupiterDebug(synth, 2)) printf("midi program: %x, %i\n", controller, value); synth->location = value; loadMemory(synth, "jupiter8", 0, synth->bank + synth->location, synth->mem.active, 0, 0); modPanelFix(win, synth); break; case MIDI_BANK_SELECT: if (jupiterDebug(synth, 2)) printf("midi banksel: %x, %i\n", controller, value); synth->bank = value + 10; loadMemory(synth, "jupiter8", 0, synth->bank + synth->location, synth->mem.active, 0, 0); modPanelFix(win, synth); break; } return(0); } static int jupiterMidiSendMsg(guiSynth *synth, int fd, int chan, int c, int o, int v) { if (jupiterDebug(synth, 5)) printf("%i, %i, %i\n", c, o, v); if (synth->mem.param[PANEL_SELECT] != 0) bristolMidiSendMsg(fd, synth->sid2, c, o, v); else bristolMidiSendMsg(fd, synth->sid, c, o, v); return(0); } static void jupiterSetDisplay(guiSynth *synth) { brightonEvent event; if (jupiterDebug(synth, 3)) printf("jupiterSetDisplay(%f, %f)\n", synth->mem.param[MY_MEM], synth->mem.param[MEM_LINK]); event.type = BRIGHTON_FLOAT; /* * Load will set the displays and nothing else, they will always point to * the active patches. * * The buttons selections should come from the layer select or from being * pressed themselves. */ if (synth->mem.param[PANEL_SELECT] != 0) { event.value = ((int) synth->mem.param[MY_MEM]) / 10; brightonParamChange(synth->win, 0, DISPLAY_DEV + 2, &event); event.value = ((int) synth->mem.param[MY_MEM]) % 10; brightonParamChange(synth->win, 0, DISPLAY_DEV + 3, &event); event.value = ((int) synth->mem.param[MEM_LINK]) / 10; brightonParamChange(synth->win, 0, DISPLAY_DEV + 0, &event); event.value = ((int) synth->mem.param[MEM_LINK]) % 10; brightonParamChange(synth->win, 0, DISPLAY_DEV + 1, &event); } else { event.value = ((int) synth->mem.param[MY_MEM]) / 10; brightonParamChange(synth->win, 0, DISPLAY_DEV + 0, &event); event.value = ((int) synth->mem.param[MY_MEM]) % 10; brightonParamChange(synth->win, 0, DISPLAY_DEV + 1, &event); event.value = ((int) synth->mem.param[MEM_LINK]) / 10; brightonParamChange(synth->win, 0, DISPLAY_DEV + 2, &event); event.value = ((int) synth->mem.param[MEM_LINK]) % 10; brightonParamChange(synth->win, 0, DISPLAY_DEV + 3, &event); } } static int exclude = 0; static int fPmask = 0x00; static int fBmask = 0x00; typedef struct FArray { int c; int o; } farray; static struct { farray pFuncs[8]; farray bFuncs[8]; } functions = { { {7, 6}, /* Env-1 rezero, condition, attack tracking. */ {7, 7}, {7, 8}, {9, 6}, /* Env-2 rezero, condition, attack tracking. */ {9, 7}, {9, 8}, {126, 31}, /* Noise per layer */ {10, 1} /* White/Pink */ }, { {126, 29}, /* LFO-1 uni */ {0, 1}, /* LFO-1 uni */ {2, 5}, /* LFO-1 gain velocity tracking */ {BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_TRIGGER}, /* Arpeggiator retrig */ {127, 33}, /* LFO Touch Sense */ {127, 115}, /* NRP enable */ {127, 116}, /* MIDI Debug */ {127, 117} /* Internal debug */ } }; static int width; static void jupiterFunctionKey(guiSynth *synth, int fd, int chan, int c, int o, int v) { int i; brightonEvent event; if (jupiterDebug(synth, 1)) printf("jupiterFunctionKey(%i, %i, %i)\n", c, o, v); if (synth->win->width != width) { brightonPut(synth->win, "bitmaps/blueprints/jupitershade.xpm", 0, 0, synth->win->width, synth->win->height); width = synth->win->width; } if (exclude == 1) return; if ((c == 2) && (v != 0)) { /* * Turn on any active function keys. TBD. */ exclude = 1; event.type = BRIGHTON_FLOAT; for (i = 0; i < 8; i++) { event.value = fPmask & (1 << i); brightonParamChange(synth->win, 0, MEM_MGT + i, &event); event.value = fBmask & (1 << i); brightonParamChange(synth->win, 0, MEM_MGT + 9 + i, &event); } exclude = 0; } if ((c == 2) && (v == 0)) { /* * Turning off - clear all the buttons and stuff the memory value */ exclude = 1; event.type = BRIGHTON_FLOAT; event.value = 0; for (i = 0; i < 8; i++) { brightonParamChange(synth->win, 0, MEM_MGT + i, &event); brightonParamChange(synth->win, 0, MEM_MGT + 9 + i, &event); } /* * set the buttons according to the display digits */ if (synth->mem.param[PANEL_SELECT] == 0) { event.value = 1.0; i = synth->mem.param[DISPLAY_DEV + 0] - 1; brightonParamChange(synth->win, 0, MEM_MGT + 9 + i, &event); i = synth->mem.param[DISPLAY_DEV + 1] - 1; brightonParamChange(synth->win, 0, MEM_MGT + i, &event); } else { event.value = 1.0; i = synth->mem.param[DISPLAY_DEV + 3] - 1; brightonParamChange(synth->win, 0, MEM_MGT + i, &event); i = synth->mem.param[DISPLAY_DEV + 2] - 1; brightonParamChange(synth->win, 0, MEM_MGT + 9 + i, &event); } exclude = 0; } /* * The functions will be on, or off. We could consider how to make them * continuous however we don't really have a data entry pot we could * reasonably consider using. We should also consider that using just a * set of bits as a mask makes them easy to save. */ if (c == 0) { if (v != 0) /* * Prog functions on, keep mask to track them. */ fPmask |= 0x01 << o; if (v == 0) /* * Prog functions off. */ fPmask &= ~(0x01 << o); if (jupiterDebug(synth, 1)) { if (v != 0) printf("call f(p): %i, %i ON\n", functions.pFuncs[o].c, functions.pFuncs[o].o); else printf("call f(p): %i, %i OFF\n", functions.pFuncs[o].c, functions.pFuncs[o].o); } if (exclude == 0) jupiterDualSend(synth, synth->sid, functions.pFuncs[o].c, functions.pFuncs[o].o, v); return; } if (c == 1) { if (v != 0) /* * Prog functions on, keep mask to track them. */ fBmask |= 0x01 << o; if (v == 0) /* * Prog functions off. */ fBmask &= ~(0x01 << o); if (jupiterDebug(synth, 1)) { if (v != 0) printf("call f(p): %i, %i ON\n", functions.bFuncs[o].c, functions.bFuncs[o].o); else printf("call f(b): %i, %i OFF\n", functions.bFuncs[o].c, functions.bFuncs[o].o); } /* LFO-2 (mods) keyboard control */ if (o == 4) { if (v != 0) v = 1; /* LFO sync, LFO frequency tracking KBD, Env tracking */ jupiterDualSend(synth, synth->sid, 1, 1, v); jupiterDualSend(synth, synth->sid, 1, 2, v); jupiterDualSend(synth, synth->sid, 3, 5, v); return; } /* NRP Enable */ if (o == 5) { if (v != 0) v = 1; if (!global.libtest) { bristolMidiSendNRP(global.controlfd, synth->sid, BRISTOL_NRP_ENABLE_NRP, v); bristolMidiSendNRP(global.controlfd, synth->sid2, BRISTOL_NRP_ENABLE_NRP, v); } return; } /* Midi debug */ if (o == 6) { if (v != 0) v = 1; if (!global.libtest) { bristolMidiSendNRP(global.controlfd, synth->sid, BRISTOL_NRP_DEBUG, v); bristolMidiSendNRP(global.controlfd, synth->sid2, BRISTOL_NRP_DEBUG, v); } return; } /* Internal debug */ if (o == 7) { debuglevel = v; return; } if (exclude == 0) { jupiterDualSend(synth, synth->sid, functions.bFuncs[o].c, functions.bFuncs[o].o, v); } return; } } static void jupiterSetFuncs(guiSynth *synth) { int i; for (i = 0; i < 8; i++) jupiterFunctionKey(synth, global.controlfd, synth->sid, 0, i, fPmask & (1 << i)); for (i = 0; i < 8; i++) jupiterFunctionKey(synth, global.controlfd, synth->sid, 1, i, fBmask & (1 << i)); } static void jupiterButtonPanel(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; event.type = BRIGHTON_FLOAT; if (jupiterDebug(synth, 1)) printf("jupiterButtonPanel(%i, %i, %i)\n", c, o, v); if (synth->mem.param[FUNCTION] != 0) return(jupiterFunctionKey(synth, fd, chan, c, o, v)); switch (c) { case 0: /* patch selector */ if (jupiterDebug(synth, 2)) printf("memory\n"); /* * Force exclusion */ if (synth->dispatch[MEM_MGT + c].other2) { synth->dispatch[MEM_MGT + c].other2 = 0; return; } if (synth->dispatch[MEM_MGT + c].other1 != -1) { synth->dispatch[MEM_MGT + c].other2 = 1; if (synth->dispatch[MEM_MGT + c].other1 != MEM_MGT + o) event.value = 0; else event.value = 1; brightonParamChange(synth->win, synth->panel, synth->dispatch[MEM_MGT + c].other1, &event); } synth->dispatch[MEM_MGT + c].other1 = MEM_MGT + o; synth->location = o + 1; break; case 1: /* Bank selector */ if (jupiterDebug(synth, 2)) printf("bank\n"); /* * Force exclusion */ if (synth->dispatch[MEM_MGT + c].other2) { synth->dispatch[MEM_MGT + c].other2 = 0; return; } if (synth->dispatch[MEM_MGT + c].other1 != -1) { synth->dispatch[MEM_MGT + c].other2 = 1; if (synth->dispatch[MEM_MGT + c].other1 != MEM_MGT + o + 9) event.value = 0; else event.value = 1; brightonParamChange(synth->win, synth->panel, synth->dispatch[MEM_MGT + c].other1, &event); } synth->dispatch[MEM_MGT + c].other1 = MEM_MGT + o + 9; synth->bank = (o + 1) * 10; break; } } /* * All the synth->second stuff is seriously painful. We are going to remove * it all and go for a single layer with backing stores. Panel switch will be * responsible for those two stores. */ static void jupiterPanelSwitch(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; int i, mymem, mylink; mymem = synth->mem.param[MY_MEM]; mylink = synth->mem.param[MEM_LINK]; if (jupiterDebug(synth, 1)) printf("jupiterPanelSwitch(%i, %i, %i) %f\n", c, o, v, synth->mem.param[PANEL_SELECT]); if (jupiterDebug(synth, 5)) { int i; for (i = 0; i < LAYER_DEVS; i+= 8) printf("%f %f %f %f %f %f %f %f\n", pcache[i], pcache[i + 1], pcache[i + 2], pcache[i + 3], pcache[i + 4], pcache[i + 5], pcache[i + 6], pcache[i + 7]); printf("\n"); for (i = 0; i < LAYER_DEVS; i+= 8) printf("%f %f %f %f %f %f %f %f\n", scache[i], scache[i + 1], scache[i + 2], scache[i + 3], scache[i + 4], scache[i + 5], scache[i + 6], scache[i + 7]); } /* * Copy from either the p or s cache into the synth then request updating * the whole shebang. */ if (v != 0) { if (jupiterDebug(synth, 1)) printf("converge secondary layer\n"); /* * Save pcache, copy in the scache */ bcopy(synth->mem.param, pcache, LAYER_DEVS * sizeof(float)); if (jupiterDebug(synth, 3)) printf("PS: my mem is %f, will be %f\n", synth->mem.param[MY_MEM], synth->mem.param[MEM_LINK]); event.type = BRIGHTON_FLOAT; for (i = 0; i < LAYER_DEVS; i++) { event.value = scache[i]; brightonParamChange(synth->win, 0, i, &event); } } else { if (jupiterDebug(synth, 1)) printf("converge primary layer\n"); /* * Save scache, copy in the pcache */ bcopy(synth->mem.param, scache, LAYER_DEVS * sizeof(float)); if (jupiterDebug(synth, 3)) printf("PS: my mem is %f, will be %f\n", synth->mem.param[MY_MEM], synth->mem.param[MEM_LINK]); event.type = BRIGHTON_FLOAT; for (i = 0; i < LAYER_DEVS; i++) { event.value = pcache[i]; brightonParamChange(synth->win, 0, i, &event); } } synth->mem.param[MY_MEM] = mylink; synth->mem.param[MEM_LINK] = mymem; event.type = BRIGHTON_FLOAT; event.value = 1.0; if (((i = (mylink / 10) - 1) >= 0) && (i < 8)) brightonParamChange(synth->win, 0, BANK_BUTTONS + i, &event); event.type = BRIGHTON_FLOAT; event.value = 1.0; if (((i = (mylink % 10) - 1) >= 0) && (i < 8)) brightonParamChange(synth->win, 0, PATCH_BUTTONS + i, &event); if (jupiterDebug(synth, 5)) { int i; for (i = 0; i < LAYER_DEVS; i+= 8) printf("%f %f %f %f %f %f %f %f\n", pcache[i], pcache[i + 1], pcache[i + 2], pcache[i + 3], pcache[i + 4], pcache[i + 5], pcache[i + 6], pcache[i + 7]); printf("\n"); for (i = 0; i < LAYER_DEVS; i+= 8) printf("%f %f %f %f %f %f %f %f\n", scache[i], scache[i + 1], scache[i + 2], scache[i + 3], scache[i + 4], scache[i + 5], scache[i + 6], scache[i + 7]); } jupiterSetDisplay(synth); } static void jupiterMemory(guiSynth *synth, int fd, int chan, int c, int o, int v) { if (synth->flags & MEM_LOADING) return; if ((synth->flags & OPERATIONAL) == 0) return; if (jupiterDebug(synth, 1)) printf("jupiterMemory(%i, %i, %i)\n", c, o, v); switch (c) { case 2: /* Memory load */ if (jupiterDebug(synth, 2)) printf("load\n"); /* * Changed some of the original logic here. Rather than load all * parameters on a first load, then just the layer devs on a double * click we are only ever going to load the layer devs unless we * double click, then we load everything including peer layer if * configured. If there is no peer layer then we should put the * emulation into mode All and potentially put it into Poly-1 if * it was in Solo. * * This code should also invistigate how to load some arpeggiator * information, automated if possible into the library. */ if (brightonDoubleClick(dc1)) { brightonEvent event; int mymem, mylink; int flags = BRISTOL_SEQLOAD|BRISTOL_SEQFORCE; if (synth->mem.param[PANEL_SELECT] != 0) flags |= BRISTOL_SID2; /* * Do a full load of my memory, fix any mod panel controls, * set up the function masks and activate them. */ if (loadMemory(synth, "jupiter8", 0, synth->bank + synth->location + mw, synth->mem.active, 0, flags) >= 0) { if (jupiterDebug(synth, 2)) printf("am %2.0f (%i), peer layer loading %2.0f\n", synth->mem.param[MY_MEM], synth->bank + synth->location, synth->mem.param[MEM_LINK]); modPanelFix(synth->win, synth); fBmask = ((int) synth->mem.param[FUNCTION_SAVE]) >> 8; fPmask = ((int) synth->mem.param[FUNCTION_SAVE]) & 0x00ff; if (jupiterDebug(synth, 4)) printf("loading functions %x %x from %x\n", fBmask, fPmask, (int) synth->mem.param[FUNCTION_SAVE]); jupiterSetFuncs(synth); } else return; /* * Build our links and also set our display values. */ mymem = synth->mem.param[MY_MEM] = synth->bank + synth->location; flags = BRISTOL_SEQLOAD|BRISTOL_SEQFORCE; /* * Take a peek at the peer memory to see if one is configured. * If there is one and we have split/double selected then load * it and activate the splits, etc. */ if ((mylink = synth->mem.param[MEM_LINK]) >= 0) { event.type = BRIGHTON_FLOAT; event.value = 1.0 - synth->mem.param[PANEL_SELECT]; brightonParamChange(synth->win, 0, PANEL_SELECT, &event); /* * This should actually have happened due to the fully * loaded memory. jupiterSetSplit(synth); jupiterSetVoices(synth); */ if (jupiterDebug(synth, 2)) printf("dual load %i (%i), peer layer is %2.0f\n", mylink, synth->bank + synth->location, synth->mem.param[MEM_LINK]); if (synth->mem.param[PANEL_SELECT] != 0) flags |= BRISTOL_SID2; loadMemory(synth, "jupiter8", 0, mylink + mw, LAYER_DEVS, 0, flags); synth->mem.param[MY_MEM] = mylink; synth->mem.param[MEM_LINK] = mymem; } else { /* * Clear any dual/split state */ event.type = BRIGHTON_FLOAT; event.value = 1.0; /* Set 'All' state */ brightonParamChange(synth->win, 0, KEY_MODE + 2, &event); /* Set 'Poly-1' state */ brightonParamChange(synth->win, 0, POLY_MODE + 2, &event); } } else { int link = synth->mem.param[MEM_LINK]; if (jupiterDebug(synth, 1)) printf("Single load %i of %i params\n", synth->bank + synth->location + mw, LAYER_DEVS); loadMemory(synth, "jupiter8", 0, synth->bank + synth->location + mw, LAYER_DEVS, 0, 0); if (jupiterDebug(synth, 1)) printf("am %2.0f (%i), no peer layer loading (%2.0f)\n", synth->mem.param[MY_MEM], synth->bank + synth->location, synth->mem.param[MEM_LINK]); /* * Build our links and also set our display values. */ synth->mem.param[MY_MEM] = synth->bank + synth->location; synth->mem.param[MEM_LINK] = link; } break; case 3: /* Memory save */ if (brightonDoubleClick(dc1)) { if (jupiterDebug(synth, 2)) printf("save\n"); if (synth->flags & MEM_LOADING) return; /* * I have my memory setup, I need to make sure that my linked * memory is correct. The linked in memory changes by layer but * the panel switch should have taken care of that. */ synth->mem.param[MY_MEM] = synth->bank + synth->location; if (synth->mem.param[PANEL_SELECT] != 0) synth->mem.param[MEM_LINK] = synth->mem.param[DISPLAY_DEV + 0] * 10 + synth->mem.param[DISPLAY_DEV + 1]; else synth->mem.param[MEM_LINK] = synth->mem.param[DISPLAY_DEV + 2] * 10 + synth->mem.param[DISPLAY_DEV + 3]; if (jupiterDebug(synth, 4)) printf("saving functions %x %x\n", fBmask, fPmask); synth->mem.param[FUNCTION_SAVE] = (fBmask << 8) + fPmask; saveMemory(synth, "jupiter8", 0, synth->bank + synth->location + mw, 0); if (synth->mem.param[PANEL_SELECT] != 0) saveSequence(synth, "jupiter8", synth->bank + synth->location + mw, BRISTOL_SID2); else saveSequence(synth, "jupiter8", synth->bank + synth->location + mw, 0); if (jupiterDebug(synth, 1)) printf(" am %2.0f (%i), peer layer saved %2.0f\n", synth->mem.param[MY_MEM], synth->bank + synth->location, synth->mem.param[MEM_LINK]); } break; } if (synth->mem.param[PANEL_SELECT] == 0) { synth->mem.param[DISPLAY_DEV + 0] = ((int) synth->mem.param[MY_MEM]) / 10; synth->mem.param[DISPLAY_DEV + 1] = ((int) synth->mem.param[MY_MEM]) % 10; synth->mem.param[DISPLAY_DEV + 2] = ((int) synth->mem.param[MEM_LINK]) / 10; synth->mem.param[DISPLAY_DEV + 3] = ((int) synth->mem.param[MEM_LINK]) % 10; } else { synth->mem.param[DISPLAY_DEV + 0] = ((int) synth->mem.param[MEM_LINK]) / 10; synth->mem.param[DISPLAY_DEV + 1] = ((int) synth->mem.param[MEM_LINK]) % 10; synth->mem.param[DISPLAY_DEV + 2] = ((int) synth->mem.param[MY_MEM]) / 10; synth->mem.param[DISPLAY_DEV + 3] = ((int) synth->mem.param[MY_MEM]) % 10; } /* printf("am showing %1.0f %1.0f, %1.0f %1.0f from %1.0f %1.0f (%1.0f)\n", synth->mem.param[DISPLAY_DEV + 0], synth->mem.param[DISPLAY_DEV + 1], synth->mem.param[DISPLAY_DEV + 2], synth->mem.param[DISPLAY_DEV + 3], synth->mem.param[MY_MEM], synth->mem.param[MEM_LINK], synth->mem.param[PANEL_SELECT]); */ /* * Load will set the displays and nothing else, they will alsways point to * the active patches. * * The buttons selections should come from the layer select or from being * pressed themselves. */ jupiterSetDisplay(synth); } static void jupiterMidi(guiSynth *synth, int fd, int chan, int c, int o, int v) { int newchan; if ((synth->flags & OPERATIONAL) == 0) return; if (c == 1) { if ((newchan = synth->midichannel - 1) < 0) newchan = synth->midichannel = 0; } else { /* * This is a little incorrect - if we are layered then we can go to * midi channel 15. */ if ((newchan = synth->midichannel + 1) >= 14) newchan = synth->midichannel = 14; } if (global.libtest == 0) { bristolMidiSendMsg(global.controlfd, synth->sid2, 127, 0, (BRISTOL_MIDICHANNEL|newchan) + 1); bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_MIDICHANNEL|newchan); } synth->midichannel = newchan; } /* * For the sake of ease of use, links have been placed here to be called * by any of the devices created. They would be better in some other file, * perhaps with this as a dispatch. * * Param refers to the device index in the locations table given below. */ static int jupiterCallback(brightonWindow * win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); int sendvalue; if ((synth == 0) || (synth->flags & SUPPRESS)) return(0); if (jupiterDebug(synth, 2)) printf("jupiterCallback(%i, %i, %f)\n", panel, index, value); if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0)) return(0); if (panel == 2) { index += LAYER_DEVS; sendvalue = value * C_RANGE_MIN_1; } else { if (jupiterApp.resources[0].devlocn[index].to == 1) sendvalue = value * C_RANGE_MIN_1; else sendvalue = value; } /* * If the index is less than LAYER_DEVS then write the value to the desired * layer only, otherwise write the value to both/top layers? */ synth->mem.param[index] = value; synth->dispatch[index].routine(synth, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); return(0); } /* * The Jupiter does not actually have a sequencer feature, just the arpeggiator * and chording. */ static void jupiterSeqMode(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; int sid = synth->sid; if (jupiterDebug(synth, 1)) printf("jupiterSeqMode(%i, %i)\n", c, v); event.type = BRIGHTON_FLOAT; if (synth->mem.param[PANEL_SELECT] == 0) sid = synth->sid; else sid = synth->sid2; if (synth->mem.param[FUNCTION] != 0) { if (v != 0) { if ((synth->flags & OPERATIONAL) == 0) return; if (synth->flags & MEM_LOADING) return; if (jupiterDebug(synth, 0)) printf("Arpeg learn mode requested %x\n", synth->flags); if (synth->seq1.param == NULL) loadSequence(&synth->seq1, "jupiter8", 0, 0); if (synth->seq2.param == NULL) loadSequence(&synth->seq2, "jupiter8", 0, BRISTOL_SID2); seqLearn = 1; /* Reset the counter */ if (synth->mem.param[PANEL_SELECT] == 0) synth->seq1.param[0] = 0; else synth->seq2.param[0] = 0; /* * Stop the arpeggiator and send a learn request */ bristolMidiSendMsg(global.controlfd, sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_ENABLE, 0); bristolMidiSendMsg(global.controlfd, sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RESEQ, 1); } else { /* * Stop the learning process */ seqLearn = 0; bristolMidiSendMsg(global.controlfd, sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RESEQ, 0); } return; } if (seqLearn == 1) { /* * This is a button press during the learning sequence, in which case * it needs to be terminated. */ seqLearn = 0; bristolMidiSendMsg(global.controlfd, sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RESEQ, 0); } if (v != 0) { bristolMidiSendMsg(global.controlfd, sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_DIR, o); /* And enable it */ bristolMidiSendMsg(global.controlfd, sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_ENABLE, 1); return; } else { /* * OK, the value is zero. If this is the same controller going off * then disable the arpeggiator, otherwise do nothing. */ if (synth->dispatch[ARPEG_MODE].other1 == c) bristolMidiSendMsg(global.controlfd, sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_ENABLE, 0); return; } } static void jupiterArpegRate(guiSynth *synth, int fd, int chan, int c, int o, int v) { /* * We need a shim since this needs to go to both SEQ and ARPEG and both * layers (as we only have a single controller). */ bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RATE, v); bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_RATE, v); bristolMidiSendMsg(global.controlfd, synth->sid2, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RATE, v); bristolMidiSendMsg(global.controlfd, synth->sid2, BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_RATE, v); } static void jupiterArpegMode(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; int sid = synth->sid; /* * Force exclusion */ if (synth->dispatch[ARPEG_MODE].other2) { synth->dispatch[ARPEG_MODE].other2 = 0; return; } if (jupiterDebug(synth, 1)) printf("jupiterArpegMode(%i, %i)\n", c, v); event.type = BRIGHTON_FLOAT; if (synth->mem.param[PANEL_SELECT] == 0) sid = synth->sid; else sid = synth->sid2; if (v != 0) { if (synth->dispatch[ARPEG_MODE].other1 != -1) { synth->dispatch[ARPEG_MODE].other2 = 1; if (synth->dispatch[ARPEG_MODE].other1 != c) event.value = 0; else event.value = 1; brightonParamChange(synth->win, synth->panel, synth->dispatch[ARPEG_MODE].other1, &event); } synth->dispatch[ARPEG_MODE].other1 = c; bristolMidiSendMsg(global.controlfd, sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_DIR, o); bristolMidiSendMsg(global.controlfd, sid, BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_DIR, o); /* And enable it */ bristolMidiSendMsg(global.controlfd, sid, BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_ENABLE, 1); return; } /* * If we are going off then disable the arpeggiator, otherwise set the * mode and start it. */ if ((v == 0) && (synth->dispatch[ARPEG_MODE].other1 == c)) /* * OK, the value is zero. If this is the same controller going off * then disable the arpeggiator, otherwise do nothing. */ bristolMidiSendMsg(global.controlfd, sid, BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_ENABLE, 0); } static void jupiterArpegRange(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; int sid; if (jupiterDebug(synth, 1)) printf("jupiterArpegRange(%i, %i) %i\n", c, o, v); event.type = BRIGHTON_FLOAT; /* * Force exclusion */ if (synth->dispatch[ARPEG_RANGE].other2) { synth->dispatch[ARPEG_RANGE].other2 = 0; return; } if (v == 0) { if (synth->dispatch[ARPEG_RANGE].other1 == c) { event.value = 1; brightonParamChange(synth->win, synth->panel, c, &event); } return; } if (synth->dispatch[ARPEG_RANGE].other1 != -1) { synth->dispatch[ARPEG_RANGE].other2 = 1; if (synth->dispatch[ARPEG_RANGE].other1 != c) event.value = 0; else event.value = 1; brightonParamChange(synth->win, 0, synth->dispatch[ARPEG_RANGE].other1, &event); } synth->dispatch[ARPEG_RANGE].other1 = c; /* * Then do whatever */ if (synth->mem.param[PANEL_SELECT] == 0) sid = synth->sid; else sid = synth->sid2; bristolMidiSendMsg(global.controlfd, sid, BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RANGE, o); bristolMidiSendMsg(global.controlfd, sid, BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_RANGE, o); return; } static void jupiterSetVoices(guiSynth *synth) { int sid; /* * If we are in 'All' mode then sid is for lower layer only, otherwise * we need to look at the layer selection. */ if (synth->mem.param[KEY_MODE + 2] != 0) sid = synth->sid; else if (synth->mem.param[PANEL_SELECT] == 0) sid = synth->sid; else sid = synth->sid2; /* * Take a peek at the Poly and Key modes to set either: * * Solo: 1 voice * Uni: Unify: * All: all voices else half * Poly: clear unison: * All: all voices else half */ if (synth->mem.param[POLY_MODE] != 0) { /* * Solo. One voice no Unison. */ bristolMidiSendMsg(global.controlfd, sid, BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_POLY_2, 0); bristolMidiSendMsg(global.controlfd, sid, 126, 2, 2); bristolMidiSendMsg(global.controlfd, sid, 126, 7, 0); } else if (synth->mem.param[POLY_MODE + 1] != 0) { /* * Unison all voices */ bristolMidiSendMsg(global.controlfd, sid, BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_POLY_2, 0); if (synth->mem.param[KEY_MODE + 2] != 0) bristolMidiSendMsg(global.controlfd, sid, 126, 2, 1); else bristolMidiSendMsg(global.controlfd, sid, 126, 2, 0); bristolMidiSendMsg(global.controlfd, sid, 126, 7, 1); } else if (synth->mem.param[POLY_MODE + 2] != 0) { /* * Poly-1 */ bristolMidiSendMsg(global.controlfd, sid, BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_POLY_2, 0); if (synth->mem.param[KEY_MODE + 2] != 0) bristolMidiSendMsg(global.controlfd, sid, 126, 2, 1); else bristolMidiSendMsg(global.controlfd, sid, 126, 2, 0); bristolMidiSendMsg(global.controlfd, sid, 126, 7, 0); } else if (synth->mem.param[POLY_MODE + 3] != 0) { /* * Poly-2 is not operational at the moment. Configure as per Poly-1 */ if (synth->mem.param[KEY_MODE + 2] != 0) { bristolMidiSendMsg(global.controlfd, sid, 126, 2, 1); } else { bristolMidiSendMsg(global.controlfd, sid, 126, 2, 0); } bristolMidiSendMsg(global.controlfd, sid, BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_POLY_2, 1); } } /* * This may have to move to within the Layer parameters since assuming the JP-8 * was the same as the JP6 and MKS-80 these were accorded to each layer. * * We could leave that for later study since the JP-8 arpeggiator was officially * only on the lower layer - the JP-6 and MKS-80 could have them on either * layer so we may move all these arpeggiator and key modes into the layer * parameters. */ static void jupiterUniPoly(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; if (jupiterDebug(synth, 2)) printf("jupiterUniPoly(%i, %i)\n", c, v); event.type = BRIGHTON_FLOAT; /* * Force exclusion */ if (synth->dispatch[POLY_MODE].other2) { synth->dispatch[POLY_MODE].other2 = 0; return; } if (v == 0) { if (synth->dispatch[POLY_MODE].other1 == c) { event.value = 1; brightonParamChange(synth->win, synth->panel, c, &event); } else return; } if (synth->dispatch[POLY_MODE].other1 != -1) { synth->dispatch[POLY_MODE].other2 = 1; if (synth->dispatch[POLY_MODE].other1 != c) event.value = 0; else event.value = 1; brightonParamChange(synth->win, synth->panel, synth->dispatch[POLY_MODE].other1, &event); } synth->dispatch[POLY_MODE].other1 = c; if (v == 0) return; /* * Do what needs to be done */ switch (o) { case 0: if (jupiterDebug(synth, 1)) printf("Solo Mode\n"); /* * Set single voice, no uni */ jupiterSetVoices(synth); break; case 1: if (jupiterDebug(synth, 1)) printf("Uni Mode\n"); /* * Set X voices depending on mode, unison all of them */ jupiterSetVoices(synth); break; case 2: if (jupiterDebug(synth, 1)) printf("Poly-1 Mode\n"); /* * Set X voices depending on mode, no Unison */ jupiterSetVoices(synth); break; case 3: if (jupiterDebug(synth, 1)) printf("Poly-2 Mode\n"); /* * Not implemented */ jupiterSetVoices(synth); break; } return; } static void jupiterSetSplit(guiSynth *synth) { int lsp, usp; if (jupiterDebug(synth, 1)) printf("setSplit: %i\n", (int) synth->mem.param[SPLIT_POINT]); if (mode == MODE_SINGLE) /* We could consider clearing any splitpoints here as well */ return; /* * Find and apply split points * We need to consider DE-121 for multiple splits. */ if (mode == MODE_SPLIT) { lsp = synth->mem.param[SPLIT_POINT] + synth->transpose; usp = lsp + 1; } else { lsp = 127; usp = 0; } if (global.libtest == 0) { bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_HIGHKEY|lsp); bristolMidiSendMsg(global.controlfd, synth->sid2, 127, 0, BRISTOL_LOWKEY|usp); } setsplit = 0; } /* * Dual, split and layer. One button needs to be on constantly */ static void jupiterKeyMode(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; if (jupiterDebug(synth, 1)) printf("jupiterKeyMode(%i, %i)\n", c, v); event.type = BRIGHTON_FLOAT; /* * Force exclusion */ if (synth->dispatch[KEY_MODE].other2) { synth->dispatch[KEY_MODE].other2 = 0; return; } if (v == 0) { if (synth->dispatch[KEY_MODE].other1 == c) { event.value = 1; brightonParamChange(synth->win, synth->panel, c, &event); } else return; } if (synth->dispatch[KEY_MODE].other1 != -1) { synth->dispatch[KEY_MODE].other2 = 1; if (synth->dispatch[KEY_MODE].other1 != c) event.value = 0; else event.value = 1; brightonParamChange(synth->win, synth->panel, synth->dispatch[KEY_MODE].other1, &event); } synth->dispatch[KEY_MODE].other1 = c; /* * Do what needs to be done */ switch (o) { case 0: if (jupiterDebug(synth, 1)) printf("Dual mode\n"); mode = MODE_DUAL; /* * Configure split points to cover whole keyboard, halve notes on * lower layer or 1 if Solo. */ bristolMidiSendMsg(fd, synth->sid, 126, 2, 0); if (global.libtest == 0) { bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_HIGHKEY|127); bristolMidiSendMsg(global.controlfd, synth->sid2, 127, 0, BRISTOL_LOWKEY|0); } jupiterSetVoices(synth); break; case 1: if (jupiterDebug(synth, 1)) printf("Split mode\n"); mode = MODE_SPLIT; /* * Configure split points to cover whole keyboard, halve notes on * lower layer or 1 if Solo.. If double click then clear splitpoint * until next key. */ bristolMidiSendMsg(fd, synth->sid, 126, 2, 0); if (brightonDoubleClick(dc1)) { if (synth->flags & MEM_LOADING) return; if (jupiterDebug(synth, 1)) printf("Split mode\n"); synth->mem.param[SPLIT_POINT] = 0; setsplit = 1; return; } jupiterSetSplit(synth); jupiterSetVoices(synth); break; case 2: if (jupiterDebug(synth, 1)) printf("All mode\n"); mode = MODE_SINGLE; /* * Move upper split out of range, increase notes on lower layer * or 1 if Solo. */ bristolMidiSendMsg(fd, synth->sid, 126, 2, 1); if (global.libtest == 0) { bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_HIGHKEY|127); bristolMidiSendMsg(global.controlfd, synth->sid2, 127, 0, BRISTOL_LOWKEY|127); } jupiterSetVoices(synth); break; } return; } static void jupiterBend(guiSynth *synth, int fd, int chan, int c, int o, int v) { if (jupiterDebug(synth, 4)) printf("bend %i\n", v); if (global.libtest == 0) bristolMidiControl(global.controlfd, synth->midichannel, 0, 1, v >> 7); } static void jupiterGlide(guiSynth *synth, int fd, int chan, int c, int o, int v) { if (jupiterDebug(synth, 4)) printf("glide %i %f to %i/%i\n", v, synth->mem.param[LAYER_DEVS + 11], synth->sid, synth->sid2); /* * Glide can be up/off/on, which I don't like (since it is in the memory) * and may go for up/both/lower instead. */ if (synth->mem.param[LAYER_DEVS + 11] == 2) { /* * Upper only */ bristolMidiSendMsg(global.controlfd, synth->sid, 126, 0, 0); bristolMidiSendMsg(global.controlfd, synth->sid2, 126, 0, (int) (synth->mem.param[LAYER_DEVS + 10] * C_RANGE_MIN_1)); } else if (synth->mem.param[LAYER_DEVS + 11] == 1) { /* * Both */ bristolMidiSendMsg(global.controlfd, synth->sid, 126, 0, (int) (synth->mem.param[LAYER_DEVS + 10] * C_RANGE_MIN_1)); bristolMidiSendMsg(global.controlfd, synth->sid2, 126, 0, (int) (synth->mem.param[LAYER_DEVS + 10] * C_RANGE_MIN_1)); } else { /* * Lower */ bristolMidiSendMsg(global.controlfd, synth->sid, 126, 0, (int) (synth->mem.param[LAYER_DEVS + 10] * C_RANGE_MIN_1)); bristolMidiSendMsg(global.controlfd, synth->sid2, 126, 0, 0); } } static void jupiterLFODelay(guiSynth *synth, int fd, int chan, int c, int o, int v) { if (jupiterDebug(synth, 4)) printf("LFODelay %i\n", v); jupiterDualSend(synth, synth->sid, 3, 0, v); } static void jupiterUME(guiSynth *synth, int sid, int chan, int c, int o, int v) { if (o == 40) bristolMidiSendMsg(global.controlfd, synth->sid, c, 40, v); else bristolMidiSendMsg(global.controlfd, synth->sid2, c, 40, v); } /* * This is a conditional dual send, it first checks for the Mod enable flags * before sending the codes. */ static void jupiterDSM(guiSynth *synth, int sid, int c, int o, int v) { if (--v < 0) v = 0; bristolMidiSendMsg(global.controlfd, synth->sid, c, o, v); bristolMidiSendMsg(global.controlfd, synth->sid2, c, o, v); } static void jupiterLFOVCF(guiSynth *synth, int fd, int chan, int c, int o, int v) { float depth; if (jupiterDebug(synth, 4)) printf("LFOVCF %i\n", v); depth = synth->mem.param[LAYER_DEVS + 3]; if (synth->mem.param[LAYER_DEVS + 8] != 0) jupiterDSM(synth, synth->sid, 126, 27, depth * C_RANGE_MIN_1); else jupiterDSM(synth, synth->sid, 126, 27, 0); // VCF } static void jupiterLFOVCO(guiSynth *synth, int fd, int chan, int c, int o, int v) { float depth; if (jupiterDebug(synth, 4)) printf("LFOVCO %i\n", v); depth = synth->mem.param[LAYER_DEVS + 2]; if (synth->mem.param[LAYER_DEVS + 7] != 0) jupiterDSM(synth, synth->sid, 126, 26, depth * C_RANGE_MIN_1); else jupiterDSM(synth, synth->sid, 126, 26, 0); // VCF } static void jupiterBendVCF(guiSynth *synth, int fd, int chan, int c, int o, int v) { float depth; if (jupiterDebug(synth, 4)) printf("BendVCF %i\n", v); depth = synth->mem.param[LAYER_DEVS + 1]; if (synth->mem.param[LAYER_DEVS + 6] != 0) jupiterDSM(synth, synth->sid, 126, 25, depth * C_RANGE_MIN_1); else jupiterDSM(synth, synth->sid, 126, 25, 0); // VCF } static void jupiterBendVCO(guiSynth *synth, int fd, int chan, int c, int o, int v) { float depth; if (jupiterDebug(synth, 4)) printf("BendVCO %i\n", v); /* * We expect 3 operators here, they are depth of bend plus direction. * 65 = VCO, 70 = VCO1, 71 = VCO2. */ depth = synth->mem.param[LAYER_DEVS]; if (synth->mem.param[LAYER_DEVS + 4] != 0) jupiterDSM(synth, synth->sid, 126, 23, depth * C_RANGE_MIN_1); else jupiterDSM(synth, synth->sid, 126, 23, 0); // VCO 1 level; if (synth->mem.param[LAYER_DEVS + 5] != 0) jupiterDSM(synth, synth->sid, 126, 24, depth * C_RANGE_MIN_1); else jupiterDSM(synth, synth->sid, 126, 24, 0); // VCO 2 level; } static void jupiterVolume(guiSynth *synth, int fd, int chan, int c, int o, int v) { float volume = synth->mem.param[101]; float balance = synth->mem.param[102]; if (jupiterDebug(synth, 4)) printf("Volume %i\n", v); /* * We have to consider layer balance and volume here, they multiply out. * These are linear controls. They may become constand power curves but * that reponse is not too great. */ bristolMidiSendMsg(fd, synth->sid, 126, 3, (int) (volume * (1.0 - balance) * C_RANGE_MIN_1)); bristolMidiSendMsg(fd, synth->sid2, 126, 3, (int) (volume * balance * C_RANGE_MIN_1)); } static void jupiterPW(guiSynth *synth, int fd, int chan, int c, int o, int v) { if (jupiterDebug(synth, 4)) printf("PW %i\n", v); jupiterMidiSendMsg(synth, fd, chan, 4, 7, v); jupiterMidiSendMsg(synth, fd, chan, 5, 7, v); } static void jupiterLFOwave(guiSynth *synth, int fd, int chan, int c, int o, int v) { jupiterMidiSendMsg(synth, fd, chan, 126, 12 + v, 1); } static void jupiterTranspose(guiSynth *synth, int fd, int chan, int c, int o, int v) { if (v > 2) v = 2; if (c == 0) { if (jupiterDebug(synth, 2)) printf("lower transpose %i\n", (v - 1) * 12); bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_TRANSPOSE + ((v - 1) * 12)); } else { if (jupiterDebug(synth, 2)) printf("upper transpose %i\n", (v - 1) * 12); bristolMidiSendMsg(global.controlfd, synth->sid2, 127, 0, BRISTOL_TRANSPOSE + ((v - 1) * 12)); } } static void jupiterChord(guiSynth *synth, int fd, int chan, int c, int o, int v) { int sid = synth->sid; if (jupiterDebug(synth, 1)) printf("Chord request: %i\n", v); if (c == 81) sid = synth->sid2; if (synth->mem.param[FUNCTION] != 0) { if (v != 0) { if ((synth->flags & OPERATIONAL) == 0) return; if (synth->flags & MEM_LOADING) return; if (synth->seq1.param == NULL) loadSequence(&synth->seq1, "jupiter8", 0, 0); if (synth->seq2.param == NULL) loadSequence(&synth->seq2, "jupiter8", 0, BRISTOL_SID2); chordLearn = 1; if (jupiterDebug(synth, 0)) printf("Chord learn requested %x\n", synth->flags); if (c == 81) synth->seq2.param[1] = 0; else synth->seq1.param[1] = 0; /* * This is to start a re-seq of the chord. */ bristolMidiSendMsg(global.controlfd, sid, BRISTOL_ARPEGGIATOR, BRISTOL_CHORD_ENABLE, 0); bristolMidiSendMsg(global.controlfd, sid, BRISTOL_ARPEGGIATOR, BRISTOL_CHORD_RESEQ, 1); } else { chordLearn = 0; bristolMidiSendMsg(global.controlfd, sid, BRISTOL_ARPEGGIATOR, BRISTOL_CHORD_RESEQ, 0); } return; } if (chordLearn == 1) { /* * This is a button press during the learning sequence, in which case * it needs to be terminated. */ chordLearn = 0; bristolMidiSendMsg(global.controlfd, sid, BRISTOL_ARPEGGIATOR, BRISTOL_CHORD_RESEQ, 0); } bristolMidiSendMsg(global.controlfd, sid, BRISTOL_ARPEGGIATOR, BRISTOL_CHORD_ENABLE, v); } static void jupiterFilter(guiSynth *synth, int fd, int chan, int c, int o, int v) { int sid; if ((synth->mem.param[PANEL_SELECT] == 0) || (mode == MODE_SINGLE)) sid = synth->sid; else sid = synth->sid2; /* * The preferred filter is the Houvilainen however as of 0.20.8 this only * does LPF. For the HPF and BPF we have to revert back to the previous * chaimberlains */ switch (v) { case 0: /* LP - 24 dB */ bristolMidiSendMsg(global.controlfd, sid, 6, 4, 4); bristolMidiSendMsg(global.controlfd, sid, 6, 6, 0); break; case 1: bristolMidiSendMsg(global.controlfd, sid, 6, 4, 0); bristolMidiSendMsg(global.controlfd, sid, 6, 6, 1); break; case 2: bristolMidiSendMsg(global.controlfd, sid, 6, 4, 0); bristolMidiSendMsg(global.controlfd, sid, 6, 6, 2); break; } } static void jupiterGlobalTune(guiSynth *synth, int fd, int chan, int c, int o, int v) { /* * Configures all the tune settings to zero (ie, 0.5). * * 14 is the fine tune of osc-2. 12 and 13 are also potentials here but * they are more associated with sound than tuning. 74 is global tuning. */ bristolMidiSendMsg(global.controlfd, synth->sid, c, o, v); bristolMidiSendMsg(global.controlfd, synth->sid2, c, o, v); } static void jupiterTune(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; /* * Configures all the tune settings to zero (ie, 0.5). * * 14 is the fine tune of osc-2. 12 and 13 are also potentials here but * they are more associated with sound than tuning. 74 is global tuning. */ event.type = BRIGHTON_FLOAT; event.value = 0.5; brightonParamChange(synth->win, synth->panel, 23, &event); brightonParamChange(synth->win, synth->panel, 103, &event); } /* * Any location initialisation required to run the callbacks. For bristol, this * will connect to the engine, and give it some base parameters. * May need to generate some application specific menus. * Will also then make specific requests to some of the devices to alter their * rendering. */ static int jupiterInit(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); dispatcher *dispatch; int i; if (synth == 0) { synth = findSynth(global.synths, 0); if (synth == 0) { printf("cannot init\n"); return(0); } } synth->win = win; printf("Initialise the jupiter link to bristol: %p\n", synth->win); synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float)); synth->mem.count = DEVICE_COUNT; synth->mem.active = ACTIVE_DEVS; synth->dispatch = (dispatcher *) brightonmalloc(DEVICE_COUNT * sizeof(dispatcher)); dispatch = synth->dispatch; synth->second = brightonmalloc(sizeof(guiSynth)); bcopy(synth, ((guiSynth *) synth->second), sizeof(guiSynth)); ((guiSynth *) synth->second)->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float)); ((guiSynth *) synth->second)->mem.count = DEVICE_COUNT; ((guiSynth *) synth->second)->mem.active = ACTIVE_DEVS; ((guiSynth *) synth->second)->dispatch = synth->dispatch; /* If we have a default voice count then limit it */ if (synth->voices == BRISTOL_VOICECOUNT) { synth->voices = 8; ((guiSynth *) synth->second)->voices = 4; } else ((guiSynth *) synth->second)->voices = synth->voices >> 1; pcache = (float *) brightonmalloc(LAYER_DEVS * sizeof(float)); scache = (float *) brightonmalloc(LAYER_DEVS * sizeof(float)); /* * We really want to have three connection mechanisms. These should be * 1. Unix named sockets. * 2. UDP sockets. * 3. MIDI pipe. */ if (!global.libtest) { int v = synth->voices; bcopy(&global, &manual, sizeof(guimain)); if ((synth->sid = initConnection(&global, synth)) < 0) return(-1); /* * We have to tweak the voicecount as we use the same synth definition * to request the second layer */ synth->voices = synth->voices >> 1; manual.flags |= BRISTOL_CONN_FORCE|BRIGHTON_NOENGINE; manual.port = global.port; manual.host = global.host; if ((synth->sid2 = initConnection(&manual, synth)) < 0) return(-1); global.manualfd = manual.controlfd; global.manual = &manual; manual.manual = &global; synth->voices = v; } for (i = 0; i < DEVICE_COUNT; i++) { /* Default all controllers to send a message that is ignored */ synth->dispatch[i].controller = 126; synth->dispatch[i].operator = 101; synth->dispatch[i].routine = (synthRoutine) jupiterMidiSendMsg; } /* LFO-1 rate and delay */ dispatch[0].controller = 0; dispatch[0].operator = 0; dispatch[1].controller = 2; dispatch[1].operator = 0; dispatch[2].routine = (synthRoutine) jupiterLFOwave; /* Mods */ dispatch[3].controller = 126; dispatch[3].operator = 9; dispatch[4].controller = 126; dispatch[4].operator = 10; dispatch[5].controller = 126; dispatch[5].operator = 11; dispatch[6].controller = 126; dispatch[6].operator = 16; dispatch[7].controller = 126; dispatch[7].operator = 17; /* VCO-1 */ dispatch[8].controller = 126; dispatch[8].operator = 8; dispatch[9].controller = 4; dispatch[9].operator = 3; dispatch[10].controller = 4; dispatch[10].operator = 2; dispatch[11].controller = 4; dispatch[11].operator = 1; dispatch[12].controller = 4; dispatch[12].operator = 0; dispatch[13].controller = 4; dispatch[13].operator = 4; dispatch[14].controller = 4; dispatch[14].operator = 5; dispatch[15].controller = 4; dispatch[15].operator = 6; dispatch[16].controller = 4; dispatch[16].operator = 11; dispatch[17].controller = 126; dispatch[17].operator = 38; /* Sync */ /* VCO-2 */ dispatch[18].controller = 5; dispatch[18].operator = 12; dispatch[19].controller = 5; dispatch[19].operator = 3; dispatch[20].controller = 5; dispatch[20].operator = 2; dispatch[21].controller = 5; dispatch[21].operator = 1; dispatch[22].controller = 5; dispatch[22].operator = 0; dispatch[23].controller = 5; dispatch[23].operator = 9; dispatch[24].controller = 5; dispatch[24].operator = 4; dispatch[25].controller = 5; dispatch[25].operator = 5; dispatch[26].controller = 5; dispatch[26].operator = 6; /* Noise */ dispatch[27].controller = 126; dispatch[27].operator = 5; /* MIX */ dispatch[28].controller = 126; dispatch[28].operator = 6; /* HPF */ dispatch[29].controller = 11; dispatch[29].operator = 0; /* VCF */ dispatch[30].controller = 6; dispatch[30].operator = 0; dispatch[31].controller = 6; dispatch[31].operator = 1; dispatch[32].controller = 6; /* Filter type - make this LP/HP */ dispatch[32].operator = 6; dispatch[32].routine = (synthRoutine) jupiterFilter; dispatch[33].controller = 126; dispatch[33].operator = 18; /* Env amount */ dispatch[34].controller = 126; dispatch[34].operator = 19; /* Env 1/2 */ dispatch[35].controller = 126; dispatch[35].operator = 20; /* LFO amount */ dispatch[36].controller = 6; dispatch[36].operator = 3; /* KBD */ /* Amp */ dispatch[37].controller = 126; dispatch[37].operator = 21; /* Env to amp */ dispatch[38].controller = 126; dispatch[38].operator = 22; /* LFO to AMP */ /* ADSR-1 */ dispatch[39].controller = 7; dispatch[39].operator = 0; dispatch[40].controller = 7; dispatch[40].operator = 1; dispatch[41].controller = 7; dispatch[41].operator = 2; dispatch[42].controller = 7; dispatch[42].operator = 3; dispatch[43].controller = 7; dispatch[43].operator = 5; /* Velocity tracking */ dispatch[44].controller = 126; dispatch[44].operator = 39; /* Env Invert */ /* ADSR-2 */ dispatch[45].controller = 9; dispatch[45].operator = 0; dispatch[46].controller = 9; dispatch[46].operator = 1; dispatch[47].controller = 9; dispatch[47].operator = 2; dispatch[48].controller = 9; dispatch[48].operator = 3; dispatch[49].controller = 9; dispatch[49].operator = 5; /* Velocity tracking */ /* PW Both Osc */ dispatch[50].controller = 9; dispatch[50].operator = 5; /* PW */ dispatch[50].routine = (synthRoutine) jupiterPW; dispatch[51].controller = 126; dispatch[51].operator = 30; /* XMOD env */ /* Pan */ dispatch[52].controller = 126; dispatch[52].operator = 4; /* Layer panning */ dispatch[53].controller = 53; dispatch[53].operator = 0; dispatch[53].routine = (synthRoutine) jupiterArpegRange; dispatch[54].controller = 54; dispatch[54].operator = 1; dispatch[54].routine = (synthRoutine) jupiterArpegRange; dispatch[55].controller = 55; dispatch[55].operator = 2; dispatch[55].routine = (synthRoutine) jupiterArpegRange; dispatch[56].controller = 56; dispatch[56].operator = 3; dispatch[56].routine = (synthRoutine) jupiterArpegRange; dispatch[57].controller = 57; dispatch[57].operator = 2; // 0 is down will be dispatch[57].routine = (synthRoutine) jupiterArpegMode; dispatch[58].controller = 58; dispatch[58].operator = 0; // 1 is up/down dispatch[58].routine = (synthRoutine) jupiterArpegMode; dispatch[59].controller = 59; dispatch[59].operator = 1; // 2 is up dispatch[59].routine = (synthRoutine) jupiterArpegMode; dispatch[60].controller = 60; dispatch[60].operator = 3; dispatch[60].routine = (synthRoutine) jupiterArpegMode; /* Uni, Solo, Poly 1&2 */ dispatch[61].controller = 61; dispatch[61].operator = 0; dispatch[61].routine = (synthRoutine) jupiterUniPoly; dispatch[62].controller = 62; dispatch[62].operator = 1; dispatch[62].routine = (synthRoutine) jupiterUniPoly; dispatch[63].controller = 63; dispatch[63].operator = 2; dispatch[63].routine = (synthRoutine) jupiterUniPoly; dispatch[64].controller = 64; dispatch[64].operator = 3; dispatch[64].routine = (synthRoutine) jupiterUniPoly; /* Layer Devs were 65 - start with Bend to VCO */ dispatch[LAYER_DEVS + 0].controller = 0; dispatch[LAYER_DEVS + 0].operator = 0; dispatch[LAYER_DEVS + 0].routine = (synthRoutine) jupiterBendVCO; dispatch[LAYER_DEVS + 4].controller = 0; dispatch[LAYER_DEVS + 4].operator = 1; dispatch[LAYER_DEVS + 4].routine = (synthRoutine) jupiterBendVCO; dispatch[LAYER_DEVS + 5].controller = 0; dispatch[LAYER_DEVS + 5].operator = 2; dispatch[LAYER_DEVS + 5].routine = (synthRoutine) jupiterBendVCO; /* Bend to VCF */ dispatch[LAYER_DEVS + 1].controller = 0; dispatch[LAYER_DEVS + 1].operator = 0; dispatch[LAYER_DEVS + 1].routine = (synthRoutine) jupiterBendVCF; dispatch[LAYER_DEVS + 6].controller = 0; dispatch[LAYER_DEVS + 6].operator = 0; dispatch[LAYER_DEVS + 6].routine = (synthRoutine) jupiterBendVCF; /* LFO to VC) */ dispatch[LAYER_DEVS + 2].controller = 0; dispatch[LAYER_DEVS + 2].operator = 0; dispatch[LAYER_DEVS + 2].routine = (synthRoutine) jupiterLFOVCO; dispatch[LAYER_DEVS + 7].controller = 0; dispatch[LAYER_DEVS + 7].operator = 0; dispatch[LAYER_DEVS + 7].routine = (synthRoutine) jupiterLFOVCO; /* LFO to VCF */ dispatch[LAYER_DEVS + 3].controller = 0; dispatch[LAYER_DEVS + 3].operator = 0; dispatch[LAYER_DEVS + 3].routine = (synthRoutine) jupiterLFOVCF; dispatch[LAYER_DEVS + 8].controller = 0; dispatch[LAYER_DEVS + 8].operator = 0; dispatch[LAYER_DEVS + 8].routine = (synthRoutine) jupiterLFOVCF; dispatch[LAYER_DEVS + 9].routine = (synthRoutine) jupiterLFODelay; dispatch[LAYER_DEVS + 10].routine = (synthRoutine) jupiterGlide; dispatch[LAYER_DEVS + 11].routine = (synthRoutine) jupiterGlide; dispatch[LAYER_DEVS + 12].controller = 0; dispatch[LAYER_DEVS + 12].routine = (synthRoutine) jupiterTranspose; dispatch[LAYER_DEVS + 13].controller = 1; dispatch[LAYER_DEVS + 13].routine = (synthRoutine) jupiterTranspose; dispatch[LAYER_DEVS + 14].controller = 0; dispatch[LAYER_DEVS + 14].operator = 2; dispatch[LAYER_DEVS + 14].routine = (synthRoutine) jupiterBend; /* Hold/Chord */ dispatch[92].controller = BRISTOL_ARPEGGIATOR; dispatch[92].operator = BRISTOL_CHORD_ENABLE; dispatch[92].routine = (synthRoutine) jupiterChord; dispatch[93].controller = BRISTOL_ARPEGGIATOR; dispatch[93].operator = BRISTOL_CHORD_ENABLE; dispatch[93].routine = (synthRoutine) jupiterChord; dispatch[MOD_ENABLE].controller = 126; dispatch[MOD_ENABLE].operator = 40; dispatch[MOD_ENABLE].routine = (synthRoutine) jupiterUME; dispatch[MOD_ENABLE + 1].controller = 126; dispatch[MOD_ENABLE + 1].operator = 41; dispatch[MOD_ENABLE + 1].routine = (synthRoutine) jupiterUME; /* Dual, split, layer */ dispatch[96].controller = 96; dispatch[96].operator = 0; dispatch[96].routine = (synthRoutine) jupiterKeyMode; dispatch[97].controller = 97; dispatch[97].operator = 1; dispatch[97].routine = (synthRoutine) jupiterKeyMode; dispatch[98].controller = 98; dispatch[98].operator = 2; dispatch[98].routine = (synthRoutine) jupiterKeyMode; /* Volume/Balance */ dispatch[101].controller = 126; dispatch[101].operator = 3; dispatch[101].routine = (synthRoutine) jupiterVolume; dispatch[102].controller = 126; /* This is not pan rather layer balance */ dispatch[102].operator = 4; dispatch[102].routine = (synthRoutine) jupiterVolume; /* Arpeggio rate and clock source (latter not supported) */ dispatch[99].controller = BRISTOL_ARPEGGIATOR; dispatch[99].operator = BRISTOL_ARPEG_RATE; dispatch[99].routine = (synthRoutine) jupiterArpegRate; /* Tuning and Tune */ dispatch[103].controller = 126; dispatch[103].operator = 1; dispatch[103].routine = (synthRoutine) jupiterGlobalTune; dispatch[104].routine = (synthRoutine) jupiterTune; dispatch[SEQ_MODE].routine = (synthRoutine) jupiterSeqMode; /* 105 */ dispatch[PANEL_SELECT].routine = (synthRoutine) jupiterPanelSwitch; /* * Memory management * * Two sets of locations - 8 bank and 8 memory, then a load and a save * button. Save will be doubleclick requirement. the selectors will be * radio buttons. * There are also issues with the dual layering that needs to be included. * This file was copied from the Juno, but the interface is more like the * prophet10 implementation so will have to borrow code from there. */ dispatch[MEM_MGT + 0].operator = 0; dispatch[MEM_MGT + 1].operator = 1; dispatch[MEM_MGT + 2].operator = 2; dispatch[MEM_MGT + 3].operator = 3; dispatch[MEM_MGT + 4].operator = 4; dispatch[MEM_MGT + 5].operator = 5; dispatch[MEM_MGT + 6].operator = 6; dispatch[MEM_MGT + 7].operator = 7; dispatch[MEM_MGT + 0].controller = dispatch[MEM_MGT + 1].controller = dispatch[MEM_MGT + 2].controller = dispatch[MEM_MGT + 3].controller = dispatch[MEM_MGT + 4].controller = dispatch[MEM_MGT + 5].controller = dispatch[MEM_MGT + 6].controller = dispatch[MEM_MGT + 7].controller = 0; /* Load button */ dispatch[MEM_MGT + 8].operator = 0; dispatch[MEM_MGT + 8].controller = 2; dispatch[MEM_MGT + 8].routine = (synthRoutine) jupiterMemory; /* Bank selectors */ dispatch[MEM_MGT + 9].operator = 0; dispatch[MEM_MGT + 10].operator = 1; dispatch[MEM_MGT + 11].operator = 2; dispatch[MEM_MGT + 12].operator = 3; dispatch[MEM_MGT + 13].operator = 4; dispatch[MEM_MGT + 14].operator = 5; dispatch[MEM_MGT + 15].operator = 6; dispatch[MEM_MGT + 16].operator = 7; dispatch[MEM_MGT + 9].controller = dispatch[MEM_MGT + 10].controller = dispatch[MEM_MGT + 11].controller = dispatch[MEM_MGT + 12].controller = dispatch[MEM_MGT + 13].controller = dispatch[MEM_MGT + 14].controller = dispatch[MEM_MGT + 15].controller = dispatch[MEM_MGT + 16].controller = 1; /* Save button */ dispatch[MEM_MGT + 17].operator = 0; dispatch[MEM_MGT + 17].controller = 3; dispatch[MEM_MGT + 17].routine = (synthRoutine) jupiterMemory; dispatch[MEM_MGT].routine = dispatch[MEM_MGT + 1].routine = dispatch[MEM_MGT + 2].routine = dispatch[MEM_MGT + 3].routine = dispatch[MEM_MGT + 4].routine = dispatch[MEM_MGT + 5].routine = dispatch[MEM_MGT + 6].routine = dispatch[MEM_MGT + 7].routine = dispatch[MEM_MGT + 9].routine = dispatch[MEM_MGT + 10].routine = dispatch[MEM_MGT + 11].routine = dispatch[MEM_MGT + 12].routine = dispatch[MEM_MGT + 13].routine = dispatch[MEM_MGT + 14].routine = dispatch[MEM_MGT + 15].routine = dispatch[MEM_MGT + 16].routine = (synthRoutine) jupiterButtonPanel; /* Midi management */ dispatch[MIDI_MGT].controller = 1; dispatch[MIDI_MGT + 1].controller = 2; dispatch[MIDI_MGT].routine = dispatch[MIDI_MGT + 1].routine = (synthRoutine) jupiterMidi; dispatch[MIDI_MGT + 2].routine = (synthRoutine) midiRelease; dispatch[MIDI_MGT + 3].controller = 2; dispatch[MIDI_MGT + 3].routine = (synthRoutine) jupiterFunctionKey; /* Noise gain */ jupiterDualSend(synth, synth->sid, 11, 0, 1024); /* LFO-1 ADSR */ jupiterDualSend(synth, synth->sid, 2, 1, 12000); jupiterDualSend(synth, synth->sid, 2, 2, 16000); jupiterDualSend(synth, synth->sid, 2, 3, 1000); jupiterDualSend(synth, synth->sid, 2, 4, 16000); jupiterDualSend(synth, synth->sid, 2, 5, 0); jupiterDualSend(synth, synth->sid, 2, 9, 0); /* LFO-2 ADSR */ jupiterDualSend(synth, synth->sid, 3, 1, 12000); jupiterDualSend(synth, synth->sid, 3, 2, 16000); jupiterDualSend(synth, synth->sid, 3, 3, 1000); jupiterDualSend(synth, synth->sid, 3, 4, 16000); jupiterDualSend(synth, synth->sid, 3, 5, 0); jupiterDualSend(synth, synth->sid, 3, 8, 0); /* LFO PW */ jupiterDualSend(synth, synth->sid, 4, 7, 8192); jupiterDualSend(synth, synth->sid, 5, 7, 8192); /* ADSR gains */ jupiterDualSend(synth, synth->sid, 7, 4, 16383); jupiterDualSend(synth, synth->sid, 9, 4, 16383); /* Filter Mod */ jupiterDualSend(synth, synth->sid, 6, 2, 16383); jupiterDualSend(synth, synth->sid, 6, 4, 4); /* Fix some default pan and gain */ jupiterDualSend(synth, synth->sid, 126, 3, 16383); jupiterDualSend(synth, synth->sid, 126, 4, 16383); jupiterDualSend(synth, synth->sid, 126, 5, 16383); jupiterDualSend(synth, synth->sid, 126, 6, 16383); /* Configure pink noise filter level */ jupiterDualSend(synth, synth->sid, 10, 2, 4096); /* Configure PWM for both DCO jupiterDualSend(synth, synth->sid, 126, 33, 1); jupiterDualSend(synth, synth->sid, 126, 34, 1); */ dispatch[ARPEG_RANGE].other1 = -1; dispatch[POLY_MODE].other1 = -1; dispatch[KEY_MODE].other1 = -1; return(0); } /* * This will be called to make any routine specific parameters available. */ static int jupiterConfigure(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); brightonEvent event; int offset; if (synth == 0) { printf("problems going operational\n"); return(-1); } if (synth->flags & OPERATIONAL) return(0); printf("going operational\n"); if (synth->location == 0) { synth->bank = 10; synth->location = 1; } else { if ((mw = synth->location / 10) == 0) synth->bank = 10; else { synth->bank = mw % 10; mw -= synth->bank; mw *= 10; synth->bank *= 10; } if ((synth->location = (synth->location % 10)) == 0) synth->location = 1; } if (jupiterDebug(synth, 2)) printf("weight %i, bank %i, mem %i\n", mw, synth->bank,synth->location); configureGlobals(synth); synth->keypanel = KEY_PANEL; synth->keypanel2 = -1; synth->transpose = 12; ((guiSynth *) synth->second)->resources = synth->resources; ((guiSynth *) synth->second)->win = synth->win; ((guiSynth *) synth->second)->bank = 10; ((guiSynth *) synth->second)->location = 2; ((guiSynth *) synth->second)->panel = 0; ((guiSynth *) synth->second)->mem.active = ACTIVE_DEVS; ((guiSynth *) synth->second)->transpose = 12; synth->flags |= OPERATIONAL; event.type = BRIGHTON_FLOAT; event.value = 1.0; /* Push some radio buttons to set their starting point */ event.value = 1.0; brightonParamChange(synth->win, 0, ARPEG_RANGE, &event); brightonParamChange(synth->win, 0, ARPEG_MODE, &event); brightonParamChange(synth->win, 0, POLY_MODE, &event); brightonParamChange(synth->win, 0, KEY_MODE + 2, &event); dc1 = brightonGetDCTimer(win->dcTimeout); /* Set up the load buttons for an initial memory load */ if ((offset = synth->location - 1) > 7) offset = 0; if (offset < 0) offset = 0; brightonParamChange(synth->win, 0, PATCH_BUTTONS + offset, &event); if ((offset = synth->bank - 1) > 7) offset = 0; if (offset < 0) offset = 0; brightonParamChange(synth->win, 0, BANK_BUTTONS + offset, &event); /* And this will appear as a double click */ jupiterMemory(synth, global.controlfd, synth->sid, 2, 0, 1); usleep(100000); jupiterMemory(synth, global.controlfd, synth->sid, 2, 0, 1); if (jupiterDebug(synth, 5)) { int i; for (i = 0; i < LAYER_DEVS; i+= 8) printf("%f %f %f %f %f %f %f %f\n", pcache[i], pcache[i + 1], pcache[i + 2], pcache[i + 3], pcache[i + 4], pcache[i + 5], pcache[i + 6], pcache[i + 7]); printf("\n"); for (i = 0; i < LAYER_DEVS; i+= 8) printf("%f %f %f %f %f %f %f %f\n", scache[i], scache[i + 1], scache[i + 2], scache[i + 3], scache[i + 4], scache[i + 5], scache[i + 6], scache[i + 7]); } /* * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only * occurs on first paint, so we suppress the first paint, and then request * an expose here. */ event.type = BRIGHTON_EXPOSE; event.intvalue = 1; brightonParamChange(synth->win, KEY_PANEL, -1, &event); brightonPut(win, "bitmaps/blueprints/jupitershade.xpm", 0, 0, win->width, win->height); width = win->width; /* Then set some defaults for volume, balance and tuning */ event.type = BRIGHTON_FLOAT; event.value = 0.9; brightonParamChange(synth->win, 0, 101, &event); event.value = 0.5; brightonParamChange(synth->win, 0, 102, &event); brightonParamChange(synth->win, 0, 103, &event); if (jupiterDebug(synth, 3)) printf("dct = %i\n", win->dcTimeout); return(0); } bristol-0.60.11/brighton/brightonKeys.h0000644000175000017500000000450611746476475014745 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* * These need to be redone. Each white key should be placed first, then the * black keys layered on top. That way we can get better graphics with shading * on the white keys for each black key. */ #ifndef BRIGHTONKEYS_H #define BRIGHTONKEYS_H #define KEY_COUNT 61 #define KEY_COUNT_2OCTAVE2 32 #define KEY_COUNT_2OCTAVE 29 #define KEY_COUNT_3OCTAVE 44 #define KEY_COUNT_3_OCTAVE 37 #define KEY_COUNT_4OCTAVE 49 #define KEY_COUNT_PEDAL 24 #define VKEY_COUNT 48 #define KEY_COUNT_5OCTAVE KEY_COUNT #define KEY_COUNT_6_OCTAVE 73 extern guimain global; extern brightonLocations keys[KEY_COUNT_5OCTAVE]; extern brightonLocations keysprofile[KEY_COUNT_5OCTAVE]; extern brightonLocations keysprofile2[KEY_COUNT_5OCTAVE]; extern brightonLocations keys6octave[KEY_COUNT_6_OCTAVE]; extern brightonLocations keys6hammond[KEY_COUNT_6_OCTAVE]; extern brightonLocations keys2octave[KEY_COUNT_2OCTAVE]; extern brightonLocations keys2octave2[KEY_COUNT_2OCTAVE2]; extern brightonLocations keys3_octave[KEY_COUNT_3_OCTAVE]; extern brightonLocations keys3octave[KEY_COUNT_3OCTAVE]; extern brightonLocations keys3octave2[KEY_COUNT_3OCTAVE]; extern brightonLocations keys4octave[KEY_COUNT_4OCTAVE]; extern brightonLocations keys4octave2[KEY_COUNT_4OCTAVE]; extern brightonLocations pedalBoard[KEY_COUNT_PEDAL]; extern brightonLocations vkeys[VKEY_COUNT]; extern brightonLocations mods[2]; extern int bristolMidiControl(int, int, int, int, int); extern int modCallback(brightonWindow *, int, int, float); extern int keyCallback(brightonWindow *, int, int, float); #endif /* BRIGHTONKEYS_H */ bristol-0.60.11/brighton/brightonRealistic.c0000644000175000017500000004571311746476475015751 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . */ #include #include "brighton.h" #include "brightonMini.h" #include "brightoninternals.h" static int realisticInit(); static int realisticConfigure(); static int realisticCallback(brightonWindow *, int, int, float); static int realisticMidiCallback(brightonWindow *, int, int, float); extern guimain global; #include "brightonKeys.h" #define OPTS_PANEL 0 #define MOD_PANEL 1 #define KEY_PANEL 1 #define FIRST_DEV 0 #define MOD_COUNT 31 #define OPTS_START 0 #define ACTIVE_DEVS (MOD_COUNT - 3) #define DEVICE_COUNT (MOD_COUNT) extern int memCallback(brightonWindow * , int, int, float); extern brightonLocations mem[]; /* * This structure is for device definition. The structure is defined in * include/brighton.h, further definitions in brighton/brightonDevtable.h and * include/brightoninternals.h * * typedef int (*brightonCallback)(int, float); * typedef struct BrightonLocations { * int device; 0=rotary, 1=scale, etc. * float relx, rely; relative position with regards to 1000 by 1000 window * float relw, relh; relative height. * int from, to; * brightonCallback callback; specific to this dev * char *image; bitmap. If zero take a device default. * int flags; * } brightonLocations; * * This example is for a realisticBristol type synth interface. */ #define R0 100 #define R1 (R0 + 80) #define R2 (R0 + 180) #define R3 570 #define R4 (R3 + 50) #define R5 (R4 + 50) #define W1 20 #define W2 42 #define W3 170 #define W4 16 #define L1 280 #define L2 55 #define L3 150 #define D1 48 #define D2 12 #define C1 40 #define C2 (C1 + D1) #define C3 (C2 + D1) #define C4 (C3 + D1 + D1) #define C5 (C4 + D1 + D1) #define C6 (C5 + D1) #define C7 (C6 + D1) #define C8 (C7 + D1 + D1) #define C9 (C8 + D1 + D1) #define C10 (C9 + D1) #define C11 (C10 + D1 + 30) #define C12 (C11 + D1) #define C13 (C12 + D1) #define C14 (C13 + D1) #define C15 (C14 + D1) static brightonLocations locations[MOD_COUNT] = { /* Tune 0 */ {"SynthTuning", 0, C1 - 10, R0 + 50, W3, W3, 0, 1, 0, "bitmaps/knobs/knob3.xpm", 0, BRIGHTON_NOTCH}, {"PolyTuning", 0, C3 - 15, R0 + 50, W3, W3, 0, 1, 0, "bitmaps/knobs/knob3.xpm", 0, BRIGHTON_NOTCH}, /* Mods 2 */ {"Mod-Tone", 1, C1, R3, W1, L1, 0, 1, 0, "bitmaps/knobs/knob7.xpm", 0, 0}, {"Mod-Filter", 1, C2, R3, W1, L1, 0, 1, 0, "bitmaps/knobs/knob7.xpm", 0, 0}, {"Mod-Glide", 1, C3, R3, W1, L1, 0, 1, 0, "bitmaps/knobs/knob7.xpm", 0, 0}, {"Mod-LFO-Rate", 1, C4, R3, W1, L1, 0, 1, 0, "bitmaps/knobs/knob7.xpm", 0, 0}, {"Mod-Shape", 2, C4 - D2, R0, W2, L2, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW|BRIGHTON_VERTICAL}, {"Mod-EnvTrig", 2, C4 - D2, R2 + 50, W2, L2, 0, 1, 0, "bitmaps/buttons/sw3.xpm", "bitmaps/buttons/sw5.xpm", BRIGHTON_NOSHADOW|BRIGHTON_VERTICAL}, /* Osc-1 8 */ {"Osc1-Sync", 2, C5, R1, W2, L2, 0, 1, 0, "bitmaps/buttons/sw3.xpm", "bitmaps/buttons/sw5.xpm", BRIGHTON_NOSHADOW|BRIGHTON_VERTICAL}, {"Osc1-Transpose", 2, C6 + 20, R0 + 40, W4, L3, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW}, {"Osc1-Waveform", 2, C7 + 15, R1, W2, L2, 0, 1, 0, "bitmaps/buttons/sw3.xpm", "bitmaps/buttons/sw5.xpm", BRIGHTON_NOSHADOW|BRIGHTON_VERTICAL}, /* Osc-2 11 */ {"Osc2-Detune", 1, C5, R3, W1, L1, 0, 1, 0, "bitmaps/knobs/knob7.xpm", 0, BRIGHTON_NOTCH}, {"Osc2-Transpose", 2, C6 + 20, R4 + 40, W4, L3, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW}, {"Osc2-Waveform", 2, C7 + 15, R5, W2, L2, 0, 1, 0, "bitmaps/buttons/sw3.xpm", "bitmaps/buttons/sw5.xpm", BRIGHTON_NOSHADOW|BRIGHTON_VERTICAL}, /* Contour 14 */ {"Env-AR/ASR", 2, C8 + 6, R0, W2, L2, 0, 2, 0, "bitmaps/buttons/sw3.xpm", "bitmaps/buttons/sw5.xpm", BRIGHTON_NOSHADOW|BRIGHTON_VERTICAL}, {"Env-Trigger", 2, C8 + 6, R2, W2, L2, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW|BRIGHTON_VERTICAL}, {"Env-Attack", 1, C9, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/knob7.xpm", 0, 0}, {"Env-Release", 1, C10, R0, W1, L1, 0, 1, 0, "bitmaps/knobs/knob7.xpm", 0, 0}, /* Filter 18 */ {"VCF-KeyTrack", 2, C8 + 6, R5, W2, L2, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW|BRIGHTON_VERTICAL}, {"VCF-Cutoff", 1, C9 - 25, R3, W1, L1, 0, 1, 0, "bitmaps/knobs/knob7.xpm", 0, 0}, {"VCF-Emphasis", 1, C9 + 25, R3, W1, L1, 0, 1, 0, "bitmaps/knobs/knob7.xpm", 0, 0}, {"VCF-Env", 1, C10 + 20, R3, W1, L1, 0, 1, 0, "bitmaps/knobs/knob7.xpm", 0, 0}, /* Mixer 22 */ {"Mix-Osc1", 1, C11, R3, W1, L1, 0, 1, 0, "bitmaps/knobs/knob7.xpm", 0, 0}, {"Mix-Osc2", 1, C12, R3, W1, L1, 0, 1, 0, "bitmaps/knobs/knob7.xpm", 0, 0}, {"Mix-Noise", 1, C13, R3, W1, L1, 0, 1, 0, "bitmaps/knobs/knob7.xpm", 0, 0}, {"Mix-Bell", 1, C14, R3, W1, L1, 0, 1, 0, "bitmaps/knobs/knob7.xpm", 0, 0}, {"Mix-Poly", 1, C15, R3, W1, L1, 0, 1, 0, "bitmaps/knobs/knob7.xpm", 0, 0}, /* Volume 27 */ {"MasterVolume", 0, C13 - 15, R0 + 50, W3, W3, 0, 1, 0, "bitmaps/knobs/knob3.xpm", 0, 0}, /* Midi Up/Down, save */ {"", 2, C15, R0, W1, 100, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_WITHDRAWN}, {"", 2, C15, R2, W1, 100, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_WITHDRAWN}, {"", 2, C15, R2 + 120, W1, 100, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, }; #define S1 200 /* * This is a set of globals for the main window rendering. Again taken from * include/brighton.h */ brightonApp realisticApp = { "realistic", 0, /* no blueprint on wood background. */ "bitmaps/textures/metal6.xpm", BRIGHTON_STRETCH, realisticInit, realisticConfigure, /* 3 callbacks */ realisticMidiCallback, 0, /* This looks like 32 voices however the synth is single voice in preops */ {32, 100, 2, 2, 5, 520, 0, 0}, 600, 320, 0, 0, 2, /* panel count */ { { "Mods", "bitmaps/blueprints/realistic.xpm", 0, BRIGHTON_STRETCH, 0, 0, realisticCallback, 22, 0, 975, 500, MOD_COUNT, locations }, { "Keyboard", 0, "bitmaps/newkeys/ekbg.xpm", /* flags */ 0x020|BRIGHTON_STRETCH, 0, 0, keyCallback, 100, 570, 810, 430, KEY_COUNT_2OCTAVE2, keys2octave2 }, } }; /*static dispatcher dispatch[DEVICE_COUNT]; */ static int realisticMidiSendMsg(void *synth, int fd, int chan, int c, int o, int v) { /* printf("realisticMidiSendMsg(%i, %i, %i)\n", c, o, v); */ bristolMidiSendMsg(fd, chan, c, o, v); return(0); } /* * For the sake of ease of use, links have been placed here to be called * by any of the devices created. They would be better in some other file, * perhaps with this as a dispatch. * * Param refers to the device index in the locations table given below. */ static int realisticCallback(brightonWindow * win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); int sendvalue; /* printf("realisticCallback(%i, %i, %f): %x\n", panel, index, value, synth); */ if (synth == 0) return(0); if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0)) return(0); if (realisticApp.resources[panel].devlocn[index].to == 1) sendvalue = value * C_RANGE_MIN_1; else sendvalue = value; switch (panel) { case OPTS_PANEL: index += OPTS_START; break; } synth->mem.param[index] = value; if ((!global.libtest) || (index >= ACTIVE_DEVS)) synth->dispatch[index].routine(synth, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #define DEBUG #ifdef DEBUG else printf("dispatch[%p,%i](%i, %i, %i, %i, %i)\n", synth, index, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #endif return(0); } static void realisticOscTransp(guiSynth *synth, int fd, int chan, int cont, int op, int value) { printf("transp %i %i\n", cont, value); if (cont == 0) { switch (value) { case 0: value = 2; break; case 1: value = 1; break; case 2: value = 0; break; } bristolMidiSendMsg(global.controlfd, synth->sid, cont, 1, value); } else { switch (value) { case 0: value = 3; break; case 1: value = 2; break; case 2: value = 1; break; } bristolMidiSendMsg(global.controlfd, synth->sid, cont, 1, value); } } static void realisticGate(guiSynth *synth, int fd, int chan, int cont, int op, int value) { printf("gate %i %i\n", cont, value); /* * Whatever we do we have to send the gate value to the engine */ bristolMidiSendMsg(global.controlfd, synth->sid, cont, op, value); /* * Now, if the value is 0 we have been requested continuous notes. Need to * decide what that means, but it could be interpreted as no note off * events for the mono synth? */ } static void realisticOscWave(guiSynth *synth, int fd, int chan, int cont, int op, int value) { printf("wave %i %i\n", cont, value); if (value == 0) { bristolMidiSendMsg(global.controlfd, synth->sid, cont, 5, 0); bristolMidiSendMsg(global.controlfd, synth->sid, cont, 6, 1); } else { bristolMidiSendMsg(global.controlfd, synth->sid, cont, 5, 1); bristolMidiSendMsg(global.controlfd, synth->sid, cont, 6, 0); } } static void realisticDecay(guiSynth *synth, int fd, int chan, int cont, int op, int value) { int iv = synth->mem.param[17] * C_RANGE_MIN_1; /* Always configure the DR values */ bristolMidiSendMsg(global.controlfd, synth->sid, 4, 1, iv); bristolMidiSendMsg(global.controlfd, synth->sid, 4, 3, iv); if (synth->mem.param[14] == 0) bristolMidiSendMsg(global.controlfd, synth->sid, 4, 2, 16383); else bristolMidiSendMsg(global.controlfd, synth->sid, 4, 2, 0); return; /* * Couple of oddities here. Firstly this is AR or ASR so we need to check * the value of the sustain switch. Also, if we have autotrigger its just * going to set sustain to 0. */ if (synth->mem.param[14] == 0) { /* Sustain is on, see if trigger allows it */ if (synth->mem.param[7] != 0) { printf("1: sustain on, trigger off\n"); bristolMidiSendMsg(global.controlfd, synth->sid, 4, 2, 16383); } else { printf("2: sustain on, trigger on\n"); bristolMidiSendMsg(global.controlfd, synth->sid, 4, 2, 0); } } else { /* Sustain is off, turn it off */ printf("3: sustain off\n"); bristolMidiSendMsg(global.controlfd, synth->sid, 4, 2, 0); } /* And set the trigger if desired */ if (cont == 126) { if (value == 1) { if (synth->mem.param[14] == 0) { printf("4: sustain on, trigger off\n"); bristolMidiSendMsg(global.controlfd, synth->sid, 4, 2, 16383); } else { printf("5: sustain off, trigger off\n"); bristolMidiSendMsg(global.controlfd, synth->sid, 4, 2, 0); } } bristolMidiSendMsg(global.controlfd, synth->sid, 126, 9, value); } } static void realisticFiltKey(guiSynth *synth, int fd, int chan, int cont, int op, int value) { int v; printf("filter key %i\n", value); switch (value) { default: case 0: v = 16383; break; case 1: v = 4096; break; case 2: v = 0; break; } bristolMidiSendMsg(global.controlfd, synth->sid, 3, 3, v); } static void realisticMonoTuning(guiSynth *synth, int fd, int chan, int cont, int op, int value) { bristolMidiSendMsg(global.controlfd, synth->sid, 0, 10, value); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 10, value); } static void realisticMemory(guiSynth *synth, int fd, int chan, int cont, int op, int value) { printf("Memory: %i, %i\n", synth->location, value); if (synth->flags & SUPPRESS) return; saveMemory(synth, "realistic", 0, synth->location, 0); } static int realisticMidiCallback(brightonWindow *win, int command, int value, float v) { guiSynth *synth = findSynth(global.synths, win); printf("midi callback: %x, %i\n", command, value); switch(command) { case MIDI_PROGRAM: printf("midi program: %x, %i\n", command, value); synth->location = value; realisticMemory(synth, global.controlfd, synth->sid, synth->dispatch[OPTS_START].controller, synth->dispatch[OPTS_START].operator, 1.0f); break; case MIDI_BANK_SELECT: printf("midi banksel: %x, %i\n", command, value); synth->bank = value; break; } return(0); } /* * Any location initialisation required to run the callbacks. For bristol, this * will connect to the engine, and give it some base parameters. * May need to generate some application specific menus. * Will also then make specific requests to some of the devices to alter their * rendering. */ static int realisticInit(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); dispatcher *dispatch; int i; if (synth == 0) { synth = findSynth(global.synths, 0); if (synth == 0) { printf("cannot init\n"); return(0); } } synth->win = win; printf("Initialise the Realistic link to bristol: %p\n", synth->win); synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float)); synth->mem.count = DEVICE_COUNT; synth->mem.active = ACTIVE_DEVS; synth->dispatch = (dispatcher *) brightonmalloc(DEVICE_COUNT * sizeof(dispatcher)); dispatch = synth->dispatch; /* * We really want to have three connection mechanisms. These should be * 1. Unix named sockets. * 2. UDP sockets. * 3. MIDI pipe. */ if (!global.libtest) if ((synth->sid = initConnection(&global, synth)) < 0) return(-1); for (i = 0; i < DEVICE_COUNT; i++) synth->dispatch[i].routine = realisticMidiSendMsg; synth->dispatch[MOD_COUNT - 1].routine = (synthRoutine) realisticMemory; /* Mono tuning */ dispatch[0].controller = 7; dispatch[0].operator = 10; dispatch[0].routine = (synthRoutine) realisticMonoTuning; /* Poly tuning */ dispatch[1].controller = 7; dispatch[1].operator = 10; /* Mods */ dispatch[2].controller = 126; dispatch[2].operator = 4; dispatch[3].controller = 126; dispatch[3].operator = 5; /* Glide */ dispatch[4].controller = 126; dispatch[4].operator = 0; /* LFO rate */ dispatch[5].controller = 2; dispatch[5].operator = 0; /* LFO waveform */ dispatch[6].controller = 126; dispatch[6].operator = 6; /* LFO Trigger */ dispatch[7].controller = 126; dispatch[7].operator = 9; /* Osc-1 sync, transpose, waveform */ dispatch[8].controller = 1; dispatch[8].operator = 7; dispatch[9].controller = 0; dispatch[9].operator = 0; dispatch[9].routine = (synthRoutine) realisticOscTransp; dispatch[10].controller = 0; dispatch[10].operator = 0; dispatch[10].routine = (synthRoutine) realisticOscWave; /* Osc-2 detune, transpose, waveform */ dispatch[11].controller = 1; dispatch[11].operator = 2; dispatch[12].controller = 1; dispatch[12].operator = 0; dispatch[12].routine = (synthRoutine) realisticOscTransp; dispatch[13].controller = 1; dispatch[13].operator = 0; dispatch[13].routine = (synthRoutine) realisticOscWave; /* Contour */ dispatch[14].routine = (synthRoutine) realisticDecay; dispatch[15].controller = 126; dispatch[15].operator = 10; dispatch[15].routine = (synthRoutine) realisticGate; dispatch[16].controller = 4; dispatch[16].operator = 0; dispatch[17].routine = (synthRoutine) realisticDecay; /* Filter tracking, freq, emf, contour */ dispatch[18].routine = (synthRoutine) realisticFiltKey; dispatch[19].controller = 3; dispatch[19].operator = 0; dispatch[20].controller = 3; dispatch[20].operator = 1; dispatch[21].controller = 126; dispatch[21].operator = 11; /* Osc-1 Mix */ dispatch[22].controller = 126; dispatch[22].operator = 2; /* Osc-2 Mix */ dispatch[23].controller = 126; dispatch[23].operator = 3; /* Noise Mix */ dispatch[24].controller = 126; dispatch[24].operator = 7; /* Bell Mix */ dispatch[25].controller = 9; dispatch[25].operator = 2; /* Poly Mix */ dispatch[26].controller = 7; dispatch[26].operator = 3; /* Master Volume */ dispatch[27].controller = 126; dispatch[27].operator = 8; /* * We have a few parameters that need to be set here to control the * poly grooming envelope */ bristolMidiSendMsg(global.controlfd, synth->sid, 8, 0, 10); bristolMidiSendMsg(global.controlfd, synth->sid, 8, 1, 10); bristolMidiSendMsg(global.controlfd, synth->sid, 8, 2, 8192); bristolMidiSendMsg(global.controlfd, synth->sid, 8, 3, 10); bristolMidiSendMsg(global.controlfd, synth->sid, 8, 4, 16383); /* Gain of poly osc */ bristolMidiSendMsg(global.controlfd, synth->sid, 7, 0, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 7, 6, 1); /* Global tuning */ bristolMidiSendMsg(global.controlfd, synth->sid, 126, 1, 8192); /* Mono waveform */ bristolMidiSendMsg(global.controlfd, synth->sid, 0, 0, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 0, 3, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 3, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 0, 7, 0); bristolMidiSendMsg(global.controlfd, synth->sid, 1, 0, 8192); /* Ring mod */ bristolMidiSendMsg(global.controlfd, synth->sid, 9, 0, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 9, 1, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 9, 2, 16383); /* Noise gain */ bristolMidiSendMsg(global.controlfd, synth->sid, 6, 0, 16383); /* Mono env */ bristolMidiSendMsg(global.controlfd, synth->sid, 4, 2, 16383); bristolMidiSendMsg(global.controlfd, synth->sid, 4, 4, 16383); /* LFO Sync */ bristolMidiSendMsg(global.controlfd, synth->sid, 2, 1, 1); /* Filter Type */ bristolMidiSendMsg(global.controlfd, synth->sid, 3, 4, 4); return(0); } /* * This will be called to make any routine specific parameters available. */ static int realisticConfigure(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); brightonEvent event; if (synth == 0) { printf("problems going operational\n"); return(-1); } if (synth->flags & OPERATIONAL) return(0); printf("going operational\n"); synth->flags |= OPERATIONAL; synth->keypanel = KEY_PANEL; synth->keypanel2 = -1; synth->transpose = 41; /* loadMemory(synth, "realistic", 0, synth->location, synth->mem.active, */ /* FIRST_DEV, 0); */ loadMemory(synth, "realistic", 0, synth->location, ACTIVE_DEVS, 0, BRISTOL_FORCE); brightonPut(win, "bitmaps/blueprints/realshade.xpm", 0, 0, win->width, win->height); /* * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only * occurs on first paint, so we suppress the first paint, and then request * an expose here. */ event.type = BRIGHTON_EXPOSE; event.intvalue = 1; brightonParamChange(synth->win, KEY_PANEL, -1, &event); /* event.type = BRIGHTON_FLOAT; event.value = 1; brightonParamChange(synth->win, 0, 0, &event); */ configureGlobals(synth); return(0); } bristol-0.60.11/brighton/brightonCLI.c0000644000175000017500000031301011746476475014425 00000000000000 /* * Diverse Bristol midi routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include "brighton.h" #include "brightoninternals.h" #include "brightonMini.h" extern char *getBristolCache(char *); extern void brightonChangeParam(guiSynth *, int, int, float); extern void brightonKeyInput(brightonWindow *, int, int); static fd_set stdioset[32]; static struct timeval timeout; static float lp = -1; struct termios resetattr; #define B_TTY_ACT_COUNT 80 #define B_TTY_LINE_LEN 256 #define B_TTY_RAW 0x00000001 #define B_TTY_RAW_P 0x00000002 #define B_TTY_RAW_P2 0x00000004 #define B_TTY_COOKED 0x00000008 #define B_TTY_RAW_ESC 0x00000010 #define B_TTY_RAW_ESC2 0x00000020 #define B_TTY_SEARCH 0x00000040 #define B_TTY_PLAY 0x00000080 #define B_TTY_MMASK 0x00000fff #define B_TTY_INIT 0x00001000 #define B_TTY_DEBUG 0x00002000 #define B_TTY_AWV 0x00004000 #define B_TTY_AUV 0x00008000 #define B_TTY_ALIASING 0x00010000 #define B_TTY_SAVE_HIST 0x00020000 #define B_TTY_PLAY_LINE 0x00040000 #define B_TTY_CLEAR_KEY 0x00080000 #define B_TTY_SEQ 0x00100000 #define B_TTY_ARGC 32 static char hist[51][B_TTY_LINE_LEN]; static char pbuf[B_TTY_LINE_LEN]; static char cbuf[B_TTY_LINE_LEN]; #define B_SEQ_COUNT 16 static struct { int count, rate, step[B_SEQ_COUNT]; } sequences[B_SEQ_COUNT] = { {8, 30, {52 + 0, 52 + 7, 52 + 3, 52 + 7, 52 + 0, 52 + 5, 52 + 9, 52 + 5}}, {0, 0, {0}}, {0, 0, {0}}, {0, 0, {0}}, {0, 0, {0}}, {0, 0, {0}}, {0, 0, {0}}, {0, 0, {0}}, {0, 0, {0}}, {0, 0, {0}}, {0, 0, {0}}, {0, 0, {0}}, {0, 0, {0}}, {0, 0, {0}}, {0, 0, {0}}, {0, 0, {0}}, }; static char *unknown = "unnamed parameter"; static char *b_blank = " "; #define B_TTY_A_LEFT 0 #define B_TTY_A_RIGHT 1 #define B_TTY_A_INCMIN 2 #define B_TTY_A_INC 3 #define B_TTY_A_INCMAX 4 #define B_TTY_A_DECMIN 5 #define B_TTY_A_DEC 6 #define B_TTY_A_DECMAX 7 #define B_TTY_A_M_UP 8 #define B_TTY_A_M_DOWN 9 #define B_TTY_A_M_READ 10 #define B_TTY_A_M_WRITE 11 #define B_TTY_A_M_TOG 12 #define B_TTY_A_INSERT 13 #define B_TTY_A_INC1 14 #define B_TTY_A_INC4 15 #define B_TTY_A_DEC1 16 #define B_TTY_A_DEC4 17 #define B_TTY_A_UPDATE 18 #define B_TTY_A_FIND 19 #define B_TTY_A_NULL -1 #define RESOURCES global->synths->resources #define SYNTHS global->synths #define paramname(x) RESOURCES->resources[btty.p].devlocn[x].name //#define DEVICE(x) RESOURCES->resources[btty.p].devlocn[x] #define DEVICE(x) global->synths->win->app->resources[btty.p].devlocn[x] #define PDEV(x) ((brightonDevice *) global->synths->win->app->resources[btty.p].devlocn[x].dev) #define unnamed(x) ((paramname(x)[0] == '\0') || (DEVICE(x).flags & BRIGHTON_WITHDRAWN)) // if (RESOURCES->resources[btty.p].devlocn[btty.i].to == 1.0f) // if (DEVICE(btty.i).to == 1.0f) brightonEvent event; extern void printBrightonHelp(int); typedef int (*clicom)(); static int bttyInterpret(guimain *, char *); static int execHelp(guimain *, int, char **); static int execMemory(guimain *, int, char **); static int execLoad(guimain *, int, char **); static int execDebug(guimain *, int, char **); static int execImport(guimain *, int, char **); static int execSet(guimain *, int, char **); static int execBristol(guimain *, int, char **); static int execBrighton(guimain *, int, char **); static int execMidi(guimain *, int, char **); static int execAlias(guimain *, int, char **); static int execCLI(guimain *, int, char **); static int execQuit(guimain *, int, char **); static void bttyMemSave(guimain *); /* Error codes */ #define B_ERR_EXIT -1 #define B_ERR_OK 0 #define B_ERR_NOT_FOUND 1 #define B_ERR_PARAM 2 #define B_ERR_VALUE 3 #define B_ERR_INV_ARG 4 #define B_ERR_EARLY 5 /* global command codes */ #define B_COM_LAST -1 #define B_COM_NOT_USED 0 #define B_COM_FREE 128 /* 'set memory' commands */ #define B_COM_FIND 1 #define B_COM_READ 2 #define B_COM_WRITE 3 #define B_COM_IMPORT 4 #define B_COM_EXPORT 5 #define B_COM_FORCE 6 typedef struct CommSet { char name[12]; int map; char help[B_TTY_LINE_LEN]; clicom exec; struct CommSet *subcom; } comSet; comSet brightoncom[4] = { {"", B_COM_NOT_USED, "", 0, 0}, {"panel", B_COM_FIND, " Set the active emulator parameter panel", 0, 0}, {"device", B_COM_FIND, " send parameter change message", 0, 0}, {"", B_COM_LAST, "", 0, 0}, }; comSet debugcomm[6] = { {"", B_COM_NOT_USED, "", 0, 0}, {"cli", B_COM_FIND, "Command Line Debuging on/off", 0, 0}, {"midi", B_COM_FIND, "debug level midi interface libraries 0..3", 0, 0}, {"frontend", B_COM_FIND, "debug engine interface libraries on/off", 0, 0}, {"engine", B_COM_FIND, "engine debuging level 0..15 (0 = off, >9 = verbose)", 0, 0}, {"", B_COM_LAST, "", 0, 0}, }; comSet bristolcom[4] = { {"", B_COM_NOT_USED, "", 0, 0}, {"register", B_COM_FIND, "send MIDI surface controller registration request", 0, 0}, {"control", B_COM_FIND, " send parameter change message to engine", 0, 0}, {"", B_COM_LAST, "", 0, 0}, }; comSet midicomm[24] = { {"", B_COM_NOT_USED, "", 0, 0}, {"channel", B_COM_FIND, "configure engine midi channel 1..16", 0, 0}, {"sid", B_COM_FIND, "select internal messaging id", 0, 0}, {"debug", B_COM_FIND, "engine debuging level 0..16", 0, 0}, {"lowkey", B_COM_FIND, "lower midi keyboard split point 0..127", 0, 0}, {"highkey", B_COM_FIND, "higher midi keyboard split point 0..127", 0, 0}, {"chanpress", B_COM_FIND, "send a channel pressure event value p=0..127", 0, 0}, {"polypress", B_COM_FIND, "send a key pressure event k=0..127 p=0..127", 0, 0}, {"filter", B_COM_FIND, "engine filters: lwf/nwf/wwf/hwf", 0, 0}, {"notepref", B_COM_FIND, "monophonic note preference logic: hnp/lnp/nnp", 0, 0}, {"velocity", B_COM_FIND, "midi velocity curve 0..1000", 0, 0}, {"detune", B_COM_FIND, "engine 'temperature sensitivity' detuning", 0, 0}, {"glide", B_COM_FIND, "maximum glide rate (5s)", 0, 0}, {"legato", B_COM_FIND, "monophonic legato velocity logic on/off", 0, 0}, {"trigger", B_COM_FIND, "monophonic trig/retrig logic on/off", 0, 0}, {"gain", B_COM_FIND, "emulator global gain control", 0, 0}, {"pwd", B_COM_FIND, "midi pitch wheel depth semitones", 0, 0}, {"nrp", B_COM_FIND, "enable user interface NRP response on/off", 0, 0}, {"enginenrp", B_COM_FIND, "enable engine NRP response on/off", 0, 0}, {"forwarding", B_COM_FIND, "enable engine midi message forwarding on/off", 0, 0}, {"tuning", B_COM_FIND, "coarse/fine: global tuning 0..1.0", 0, 0}, {"controller", B_COM_FIND, "send a value to a continuous controller value", 0, 0}, {"panic", B_COM_FIND, "midi all-notes-off, etc", 0, 0}, {"", B_COM_LAST, "", 0, 0}, }; comSet cliComm[4] = { {"", B_COM_NOT_USED, "", 0, 0}, {"cycle", B_COM_FIND, "CLI cycle response time (ms)", 0, 0}, {"list", B_COM_FIND, "list the CLI ESC command key templates", 0, 0}, {"", B_COM_LAST, "", 0, 0}, }; comSet memcomm[8] = { /* Find/read/write/import/export should move to set memory */ {"", B_COM_NOT_USED, "", 0, 0}, {"find", B_COM_FIND, "'find', 'find free', 'find load' synth memory search", execLoad, 0}, {"read", B_COM_FIND, "[|undo] load synth memory at the configured index", execLoad, 0}, {"write", B_COM_FIND, "[] save current synth settings to memory", execLoad, 0}, {"import", B_COM_FIND, "[path [mem]] read a file and save to memory", execImport, 0}, {"export", B_COM_FIND, "[path [mem]] save memory to external file", execImport, 0}, {"force", B_COM_FIND, "force the loading of an otherwise erroneous memory, on/off", execLoad, 0}, {"", B_COM_LAST, "", 0, 0}, }; /* * Need to build more structures to represent the parameters set of each * command, this is needed for better help and command completion. static struct { char name[12]; int map; char help[B_TTY_LINE_LEN]; clicom exec; comSet *subcom; } tmp; */ /* 'set and top level interpretation */ #define B_COM_SET 1 #define B_COM_MEMORY 2 #define B_COM_MIDI 3 #define B_COM_DEBUG 4 #define B_COM_BRISTOL 5 #define B_COM_BRIGHTON 6 #define B_COM_CLI 7 #define B_COM_ALIAS 8 #define B_COM_SETALIAS 9 #define B_COM_HELP 10 #define B_COM_QUIT 11 #define B_COM_PLAY 12 comSet setcomm[B_TTY_ACT_COUNT + 1] = { {"", B_COM_NOT_USED, "", 0, 0}, /* Find/read/write/import/export should move to set memory */ {"memory", B_COM_MEMORY, "'set memory [find|read|write|import|export]", execMemory, memcomm}, {"midi", B_COM_MIDI, "[channel|debug|help] midi control commands", execMidi, midicomm}, {"debug", B_COM_DEBUG, "[on|off|engine [0..15]] debug settings", execDebug, debugcomm}, {"bristol", B_COM_BRISTOL, "[cont/op/value|register] - operator commands", execBristol, bristolcom}, {"brighton",B_COM_BRIGHTON, "[panel|p/d/v] - GUI management commands", execBrighton, brightoncom}, {"cli", B_COM_CLI, "[list| action|cycle] navigation key management", execCLI, cliComm}, {"alias", B_COM_SETALIAS, "command aliases, %/$ signs will be remapped parameters", execAlias, 0}, {"play", B_COM_PLAY, "set play mode|stop, set play sequence , to test synth patches", execAlias, 0}, {"noalias", B_COM_SETALIAS, "noalias : remove an alias called 'name'", execAlias, 0}, {"line", B_COM_NOT_USED, "command line length", 0, 0}, {"history", B_COM_NOT_USED, "history table size (max 50)", 0, 0}, {"savehistory", B_COM_NOT_USED, "autosave history and parameters on exit", 0, 0}, {"prompt", B_COM_NOT_USED, "CLI Prompt", 0, 0}, {"accelerator", B_COM_NOT_USED, "Default ESC mode Up/Down parameter change value", 0, 0}, {"awv", B_COM_NOT_USED, "access withdrawn variables", 0, 0}, {"", B_COM_LAST, "", 0, 0}, }; comSet commands[B_TTY_ACT_COUNT + 1] = { {"", B_COM_NOT_USED, "", 0, 0}, /* Find/read/write/import/export should move to set memory */ {"set", B_COM_SET, "[line|panel|awv|cli|noalias|hist|prompt]", execSet, setcomm}, {"memory", B_COM_MEMORY, "'set memory [find|read|write|import|export]", execMemory, memcomm}, {"midi", B_COM_MIDI, "[channel|debug|help] midi control commands", execMidi, midicomm}, {"debug", B_COM_DEBUG, "[on|off|engine [0..15]] debug settings", execDebug, debugcomm}, {"bristol", B_COM_BRISTOL, "[cont/op/value|register] - operator commands", execBristol, bristolcom}, {"brighton",B_COM_BRIGHTON, "[panel|p/d/v] - GUI management commands", execBrighton, brightoncom}, {"cli", B_COM_CLI, "[list| action|cycle] navigation key management", execCLI, cliComm}, {"alias", B_COM_SETALIAS, "command aliases, %/$ signs will be remapped parameters", execAlias, 0}, {"help", B_COM_HELP, "'set help', 'help , this screen", execHelp, 0}, {"quit", B_COM_QUIT, "exit application, terminate the emulator", execQuit, NULL}, {"", B_COM_LAST, "", 0, 0}, }; #define B_TTY_A_PREDEF 20 static struct { char opname[12]; int imap; } templates[B_TTY_ACT_COUNT + 1] = { {"left", B_TTY_A_LEFT}, {"right", B_TTY_A_RIGHT}, {"incmin", B_TTY_A_INCMIN}, {"inc", B_TTY_A_INC}, {"incmax", B_TTY_A_INCMAX}, {"decmin", B_TTY_A_DECMIN}, {"dec", B_TTY_A_DEC}, {"decmax", B_TTY_A_DECMAX}, {"memUp", B_TTY_A_M_UP}, {"memDown", B_TTY_A_M_DOWN}, {"read", B_TTY_A_M_READ}, {"write", B_TTY_A_M_WRITE}, {"toggle", B_TTY_A_M_TOG}, {"insert", B_TTY_A_INSERT}, {"fineup", B_TTY_A_INC4}, {"up", B_TTY_A_INC1}, {"finedown",B_TTY_A_DEC4}, {"down", B_TTY_A_DEC1}, {"update", B_TTY_A_UPDATE}, {"search", B_TTY_A_FIND}, {"off", B_TTY_A_NULL}, {"", -1}, }; static struct { char map; int imap; } action[B_TTY_ACT_COUNT + 1] = { {'h', B_TTY_A_LEFT}, {'l', B_TTY_A_RIGHT}, {0x0b, B_TTY_A_INCMIN}, {'k', B_TTY_A_INC}, {'K', B_TTY_A_INCMAX}, {0x0a, B_TTY_A_DECMIN}, {'j', B_TTY_A_DEC}, {'J', B_TTY_A_DECMAX}, {'M', B_TTY_A_M_UP}, {'m', B_TTY_A_M_DOWN}, {'r', B_TTY_A_M_READ}, {'w', B_TTY_A_M_WRITE}, {'x', B_TTY_A_M_TOG}, {'u', B_TTY_A_INC1}, {'d', B_TTY_A_DEC1}, {'f', B_TTY_A_UPDATE}, {'U', B_TTY_A_INC4}, {'D', B_TTY_A_DEC4}, {':', B_TTY_A_INSERT}, {'/', B_TTY_A_FIND}, {'\0', -1}, }; static struct { unsigned int flags; guimain *global; int cycle; int i; int p; char promptText[64]; char prompt[64]; char *hist[51]; int hist_tmp; int hist_c; int edit_p; char b; char delim; int len; int fd[2]; int lastmem; char ichan; char mdbg; char edbg; char lowkey; char highkey; char preference; float accel; int fl; int po; unsigned int key; int pcycle; int acycle; struct { int id; int step; int count; int transpose; unsigned int flags; } sequence; } btty = { B_TTY_INIT|B_TTY_COOKED|B_TTY_PLAY_LINE, NULL, 500, 0, 0, "%algo% (m %memory% ch %channel%): ", "%algo%: ", {hist[0], hist[1], hist[2], hist[3], hist[4], hist[5], hist[6], hist[7], hist[8], hist[9], hist[10], hist[11], hist[12], hist[13], hist[14], hist[15], hist[16], hist[17], hist[18], hist[19], hist[20], hist[21], hist[22], hist[23], hist[24], hist[25], hist[26], hist[27], hist[28], hist[29], hist[30], hist[31], hist[32], hist[33], hist[34], hist[35], hist[36], hist[37], hist[38], hist[39], hist[40], hist[41], hist[42], hist[43], hist[44], hist[45], hist[46], hist[47], hist[48], hist[49], hist[50]}, 0, 50, 0, '\0', ':', 80, {0, 0}, 0, /* These all default to zero, the MIDI options */ 0, 0, 0, 0, 127, 0, /* Default Cursor key accelerator */ 0.05f, 0, 0, /* Keystroke management */ 0, 500, 500 }; static void print(char *str) { int i; char tbuf[B_TTY_LINE_LEN]; if (btty.flags & B_TTY_DEBUG) { snprintf(tbuf, btty.len, "d: %s\r\n", str); i = write(btty.fd[1], tbuf, strlen(tbuf)); } } static void printChar(char ch) { int i; if (btty.flags & B_TTY_DEBUG) { snprintf(pbuf, btty.len, "char 0x%x\r\n", ch); i = write(btty.fd[1], pbuf, strlen(pbuf)); } } static void seqStop(guimain *global) { print("seqStop"); if (btty.flags & B_TTY_SEQ) { bristolMidiSendMsg(global->controlfd, SYNTHS->midichannel, BRISTOL_EVENT_KEYOFF, 0, sequences[btty.sequence.id].step[btty.sequence.step] + btty.sequence.transpose); bristolMidiSendMsg(global->controlfd, SYNTHS->sid, 127, 0, BRISTOL_ALL_NOTES_OFF); } btty.flags &= ~B_TTY_SEQ; btty.sequence.step = 0; } static void bttyManageHistory(char *comm) { if (btty.flags & B_TTY_ALIASING) return; if ((strcmp(comm, btty.hist[1]) != 0) && (comm[0] != '\0')) { int i; char *curr = btty.hist[50]; snprintf(btty.hist[0], btty.len, "%s", comm); /* different history, cycle them and clean current */ for (i = 50; i > 0; i--) btty.hist[i] = btty.hist[i - 1]; btty.hist[0] = curr; memset(btty.hist[0], 0, B_TTY_LINE_LEN); } btty.hist_tmp = 0; } void brightonCLIcleanup() { if (btty.flags & B_TTY_SAVE_HIST) { btty.SYNTHS->location = 9999; bttyMemSave(btty.global); } tcsetattr(btty.fd[0], TCSANOW, &resetattr); } void brightonGetCLIcodes(int fd) { int i, n; snprintf(pbuf, btty.len, "CLI: set history %i\n", btty.hist_c); n = write(fd, pbuf, strlen(pbuf)); snprintf(pbuf, btty.len, "CLI: set line %i\n", btty.len); n = write(fd, pbuf, strlen(pbuf)); snprintf(pbuf, btty.len, "CLI: set accel %f\n", btty.accel); n = write(fd, pbuf, strlen(pbuf)); snprintf(pbuf, btty.len, "CLI: set prompttext \"%s\"\n", btty.promptText); n = write(fd, pbuf, strlen(pbuf)); snprintf(pbuf, btty.len, "CLI: set cli cycle %i\n", btty.cycle); n = write(fd, pbuf, strlen(pbuf)); if (btty.flags & B_TTY_DEBUG) { snprintf(pbuf, btty.len, "CLI: debug on\n"); n = write(fd, pbuf, strlen(pbuf)); } snprintf(pbuf, btty.len, "CLI: set panel %i\n", btty.p); n = write(fd, pbuf, strlen(pbuf)); for (i = 0; commands[i].map != -1; i++) { if (commands[i].map == B_COM_ALIAS) { snprintf(pbuf, btty.len, "CLI: set alias %s %s\n", commands[i].name, commands[i].help); n = write(fd, pbuf, strlen(pbuf)); } } for (i = 0; i < B_TTY_ACT_COUNT; i++) { if ((action[i].imap < 0) || (action[i].map == '\0')) continue; if (action[i].map < 26) { snprintf(pbuf, btty.len, "CLI: set cli ^X %s\n", templates[action[i].imap].opname); pbuf[14] = action[i].map + 96; } else { snprintf(pbuf, btty.len, "CLI: set cli X %s\n", templates[action[i].imap].opname); pbuf[13] = action[i].map; } n = write(fd, pbuf, strlen(pbuf)); } if (btty.flags & B_TTY_SAVE_HIST) { snprintf(pbuf, btty.len, "CLI: set savehistory on\n"); n = write(fd, pbuf, strlen(pbuf)); for (i = 50; i >= 0; i--) { if (btty.hist[i][0] == '\0') continue; snprintf(pbuf, btty.len, "CLI: set history comm %s\n", btty.hist[i]); n = write(fd, pbuf, strlen(pbuf)); } } } void brightonSetCLIcode(char *input) { int map, i, stuff = 0; int act; char c = input[0]; char *comm = &input[2]; if (btty.global == NULL) return; print("SetCLIcode"); if ((input[strlen(input) -1] == '\n') || (input[strlen(input) -1] == '\r')) input[strlen(input) -1] = '\0'; if (strncmp("set", input, 3) == 0) { snprintf(cbuf, btty.len, "%s", input); bttyInterpret(btty.global, cbuf); return; } if (c == '^') { c = input[1] - 96; comm++; } print(comm); for (act = 0; act < B_TTY_ACT_COUNT; act++) { /* return if we cannot find the action */ if (templates[act].imap == -1) break; if (templates[act].opname[0] == '\0') break; if (strcasecmp(comm, templates[act].opname) == 0) { stuff = act; break; } } if ((stuff) || (templates[act].imap == -1)) { int i; /* * Search the ommmand table, add entry to templates */ for (i = 0 ; (commands[i].map != B_COM_LAST) && (i < B_TTY_ACT_COUNT); i++) { if (strcasecmp(comm, commands[i].name) == 0) { /* * Found a command. */ if (templates[act].imap == -1) { templates[act + 1].imap = -1; templates[act + 1].opname[0] = '\0'; } templates[act].imap = act; snprintf(templates[act].opname, 12, "%s", comm); break; } } } print(templates[act].opname); if (act >= B_TTY_ACT_COUNT) return; act = templates[act].imap; for (map = 0; map < B_TTY_ACT_COUNT; map++) { if (action[map].map == '\0') break; if (action[map].map == c) break; } if (map == B_TTY_ACT_COUNT) return; if (action[map].map == '\0') { action[map + 1].map = '\0'; action[map + 1].imap = B_COM_LAST; } action[map].map = c; action[map].imap = act; if (btty.flags & B_TTY_DEBUG) { if (input[0] == '^') { snprintf(pbuf, btty.len, "^X is %s\n\r", templates[act].opname); pbuf[1] = c + 96; } else { snprintf(pbuf, btty.len, "X is %s %i %i\n\r", templates[act].opname, map, action[map].imap); pbuf[0] = action[map].map; } i = write(btty.fd[1], pbuf, strlen(pbuf)); } } static int execHelpCheck(int c, char **v) { int i, j, n; if ((c == 2) && (strncmp("help", v[1], strlen(v[1])) == 0)) { for (i = 0; commands[i].map != B_COM_LAST; i++) { if (strncmp(commands[i].name, v[0], strlen(v[0])) == 0) { if (commands[i].subcom == 0) { snprintf(pbuf, B_TTY_LINE_LEN, "%12s: %s\n\r", commands[i].name, commands[i].help); n = write(btty.fd[1], pbuf, strlen(pbuf)); return(1); } else { for (j = 0; commands[i].subcom[j].map != B_COM_LAST; j++) { if ((commands[i].subcom[j].name[0] == '\0') || (commands[i].subcom[j].help[0] == '\0')) continue; snprintf(pbuf, B_TTY_LINE_LEN, "%13s: %s\n\r", commands[i].subcom[j].name, commands[i].subcom[j].help); n = write(btty.fd[1], pbuf, strlen(pbuf)); } return(1); } } } } return(0); } static int isparam(int set, int comm, char *name) { if (strncmp(commands[set].subcom[comm].name, name, strlen(name)) == 0) return(1); return(0); } static void bttyMemSave(guimain *global) { int i; SYNTHS->cmem = SYNTHS->lmem; if (SYNTHS->saveMemory != NULL) SYNTHS->saveMemory(SYNTHS, RESOURCES->name, 0, SYNTHS->location, 0); else saveMemory(SYNTHS, RESOURCES->name, 0, SYNTHS->location, 0); if (btty.flags & B_TTY_DEBUG) { snprintf(pbuf, btty.len, "write: %i\n\r", SYNTHS->location); i = write(btty.fd[1], pbuf, strlen(pbuf)); } } static void bttyMemLoad(guimain *global) { int i; SYNTHS->lmem = SYNTHS->cmem; if (SYNTHS->loadMemory != NULL) SYNTHS->loadMemory(SYNTHS, RESOURCES->name, 0, SYNTHS->location, SYNTHS->mem.active, 0, btty.fl); else loadMemory(SYNTHS, RESOURCES->name, 0, SYNTHS->location, SYNTHS->mem.active, 0, btty.fl); SYNTHS->cmem = SYNTHS->location; if (SYNTHS->location != 9999) { snprintf(pbuf, btty.len, "read: %i\r\n", SYNTHS->location); i = write(btty.fd[1], pbuf, strlen(pbuf)); } else { snprintf(pbuf, btty.len, "read: unread\r\n"); i = write(btty.fd[1], pbuf, strlen(pbuf)); } } static int execMemory(guimain *global, int c, char **argv) { int n; if (c == 1) return(B_ERR_PARAM); if (execHelpCheck(c, argv)) return(0); if (c == 2) { /* find, read, write */ if (isparam(B_COM_MEMORY, B_COM_FIND, argv[1])) { int location = SYNTHS->location + 1; /* find mem */ while (loadMemory(SYNTHS, RESOURCES->name, 0, location, SYNTHS->mem.active, 0, BRISTOL_STAT) != 0) { if (++location >= 1024) location = 0; if (location == SYNTHS->location) break; } if (location != SYNTHS->location) { SYNTHS->location = location; snprintf(pbuf, btty.len, "mem: %i\r\n", SYNTHS->location); n = write(btty.fd[1], pbuf, strlen(pbuf)); } else { snprintf(pbuf, btty.len, "no memories\r\n"); n = write(btty.fd[1], pbuf, strlen(pbuf)); } return(B_ERR_OK); } if (isparam(B_COM_MEMORY, B_COM_READ, argv[1])) { bttyMemLoad(global); return(B_ERR_OK); } if (isparam(B_COM_MEMORY, B_COM_WRITE, argv[1])) { bttyMemSave(global); return(B_ERR_OK); } if (isdigit(argv[1][0])) { if ((n = atoi(argv[1])) < 0) return(B_ERR_VALUE); if (n > 1023) return(B_ERR_VALUE); SYNTHS->location = n; return(B_ERR_OK); } return(B_ERR_PARAM); } if (c == 3) { /* find free, find read, read undo, read n, write n */ if (isparam(B_COM_MEMORY, B_COM_FIND, argv[1])) { if (strncmp("free", argv[2], strlen(argv[2])) == 0) { int location = SYNTHS->location + 1; /* find mem */ while (loadMemory(SYNTHS, RESOURCES->name, 0, location, SYNTHS->mem.active, 0, BRISTOL_STAT) == 0) { if (++location >= 1024) location = 0; if (location == SYNTHS->location) break; } if (location != SYNTHS->location) { SYNTHS->location = location; snprintf(pbuf, btty.len, "mem: %i\r\n", SYNTHS->location); n = write(btty.fd[1], pbuf, strlen(pbuf)); } else { snprintf(pbuf, btty.len, "no memories\r\n"); n = write(btty.fd[1], pbuf, strlen(pbuf)); return(B_ERR_VALUE); } return(B_ERR_OK); } if ((strncmp("load", argv[2], strlen(argv[2])) == 0) ||(strncmp("read", argv[2], strlen(argv[2])) == 0)) { int location = SYNTHS->location + 1; /* find mem */ while (loadMemory(SYNTHS, RESOURCES->name, 0, location, SYNTHS->mem.active, 0, BRISTOL_STAT) != 0) { if (++location >= 1024) location = 0; if (location == SYNTHS->location) break; } if (location != SYNTHS->location) { SYNTHS->location = location; bttyMemLoad(global); return(B_ERR_OK); } else { snprintf(pbuf, btty.len, "no memories\r\n"); n = write(btty.fd[1], pbuf, strlen(pbuf)); return(B_ERR_VALUE); } } } else if (isparam(B_COM_MEMORY, B_COM_READ, argv[1])) { if (strncmp("undo", argv[2], strlen(argv[2])) == 0) { n = SYNTHS->location; SYNTHS->location = 9999; bttyMemLoad(global); SYNTHS->location = n; return(B_ERR_OK); } if ((n = atoi(argv[2])) < 0) return(B_ERR_VALUE); if (n > 1023) return(B_ERR_VALUE); SYNTHS->location = n; bttyMemLoad(global); return(B_ERR_OK); } else if (isparam(B_COM_MEMORY, B_COM_FORCE, argv[1])) { if (strcmp(argv[2], "on") == 0) { btty.fl = BRISTOL_FORCE; return(B_ERR_OK); } else if (strcmp(argv[2], "off") == 0) { btty.fl = 0; return(B_ERR_OK); } return(B_ERR_PARAM); } else if (isparam(B_COM_MEMORY, B_COM_WRITE, argv[1])) { if ((n = atoi(argv[2])) < 0) return(B_ERR_VALUE); if (n > 1023) return(B_ERR_VALUE); SYNTHS->location = n; bttyMemSave(global); return(B_ERR_OK); } return(B_ERR_PARAM); } if (c == 4) { int loc; /* import, export */ if (isparam(B_COM_MEMORY, B_COM_IMPORT, argv[1])) { loc = atoi(argv[3]); bristolMemoryImport(loc, argv[2], RESOURCES->name); return(B_ERR_OK); } else if (isparam(B_COM_MEMORY, B_COM_EXPORT, argv[1])) { loc = atoi(argv[2]); bristolMemoryExport(loc, argv[1], RESOURCES->name); return(B_ERR_OK); } return(B_ERR_PARAM); } return(B_ERR_PARAM); } static int execCLI(guimain *global, int c, char **argv) { int n; if (c == 1) { int i; snprintf(pbuf, btty.len, "cycle: %i\r\n", btty.cycle); n = write(btty.fd[1], pbuf, strlen(pbuf)); snprintf(pbuf, btty.len, "CLI mode navigation keys:\n\r"); n = write(btty.fd[1], pbuf, strlen(pbuf)); for (i = 0; action[i].imap != -1; i++) { snprintf(pbuf, btty.len, "%2i : %s\n\r", i, templates[action[i].imap].opname); if (action[i].map <= 27) { pbuf[3] = '^'; pbuf[4] = action[i].map + 96; } else pbuf[4] = action[i].map; n = write(btty.fd[1], pbuf, strlen(pbuf)); } return(0); } if (c == 2) { if (strncmp("cycle", argv[1], strlen(argv[1])) == 0) { snprintf(pbuf, btty.len, "cycle: %i\r\n", btty.cycle); n = write(btty.fd[1], pbuf, strlen(pbuf)); return(0); } else if (strncmp("listcommands", argv[1], strlen(argv[1])) == 0) { int i; for (i = 0; templates[i].imap != -1; i++) { snprintf(pbuf, btty.len, " %s\n\r", templates[i].opname); n = write(btty.fd[1], pbuf, strlen(pbuf)); } return(0); } } if (c == 3) { if (strncmp("cycle", argv[1], strlen(argv[1])) == 0) { if ((btty.cycle = atoi(argv[2])) < 50) btty.cycle = 50; else if (btty.cycle > 1000) btty.cycle = 1000; snprintf(pbuf, btty.len, "cycle: %i\r\n", btty.cycle); n = write(btty.fd[1], pbuf, strlen(pbuf)); } else { char comm[B_TTY_LINE_LEN]; snprintf(comm, B_TTY_LINE_LEN, "%s %s\n", argv[1], argv[2]); print(comm); brightonSetCLIcode(comm); } return(0); } return(2); } static int execAlias(guimain *global, int c, char **argv) { char *comm, alias[B_TTY_LINE_LEN]; int i; print("execAlias"); if ((c == 1) && (strncmp(argv[0], "alias", strlen(argv[0])) == 0)) { int n; for (i = 0; commands[i].map != B_COM_LAST; i++) { if (commands[i].map == B_COM_ALIAS) { snprintf(pbuf, B_TTY_LINE_LEN, "%12s: %s\n\r", commands[i].name, commands[i].help); n = write(btty.fd[1], pbuf, strlen(pbuf)); } } return(0); } /* * Two calls, one with the actual 'alias' token, if not we should search * the alias list. */ if (strncmp("alias", argv[0], strlen(argv[0])) == 0) { if (c < 3) return(2); /* * the alias is in our cbuf, we just have to find it. */ if (cbuf[0] == 's') { if ((comm = index(cbuf, ' ')) == NULL) return(3); comm++; if ((comm = index(comm, ' ')) == NULL) return(3); comm++; if ((comm = index(comm, ' ')) == NULL) return(3); comm++; if (comm[0] == '\0') return(3); snprintf(alias, btty.len, "%s", comm); } else if (cbuf[0] == 'a') { if ((comm = index(cbuf, ' ')) == NULL) return(3); comm++; if ((comm = index(comm, ' ')) == NULL) return(3); comm++; if (comm[0] == '\0') return(3); snprintf(alias, btty.len, "%s", comm); } else return(2); comm = argv[1]; if (strncmp(comm, alias, strlen(comm)) == 0) { print("cannot apply alias: recursive"); return(2); } /* Find free command */ for (i = 0; commands[i].map != -1; i++) { if (i == (B_TTY_ACT_COUNT - 1)) { snprintf(pbuf, btty.len, "command table full\r\n"); i = write(btty.fd[1], pbuf, strlen(pbuf)); return(4); } if (strcmp(commands[i].name, comm) == 0) { if (commands[i].map != B_COM_ALIAS) { print("cannot apply alias: name in use"); return(2); } print("remapping alias"); snprintf(commands[i].name, 11, "%s", comm); snprintf(commands[i].help, B_TTY_LINE_LEN, "%s", alias); commands[i].exec = execAlias; return(0); } if (commands[i].map == B_COM_FREE) break; } print(comm); print(alias); /* Flag next entry as last */ if (commands[i].map != B_COM_FREE) { commands[i + 1].name[0] = '\0'; commands[i + 1].map = B_COM_LAST; } snprintf(commands[i].name, 11, "%s", comm); snprintf(commands[i].help, B_TTY_LINE_LEN, "%s", alias); commands[i].map = B_COM_ALIAS; commands[i].exec = execAlias; return(0); } else { int j = 1, k = 0; print("searchAlias"); /* * Build a new command line and exec it. Find the alias, take it's * help line, copy over byte by byte to cbuf, replace each % with * increasing argv (if we have enough) */ for (i = 0; commands[i].map != -1; i++) { if (strncmp(argv[0], commands[i].name, strlen(argv[0])) == 0) break; } if (commands[i].map != B_COM_ALIAS) return(B_ERR_PARAM); comm = commands[i].help; print(comm); btty.flags |= B_TTY_ALIASING; for (i = 0; comm[i] != '\0'; i++) { if (comm[i] == '$') { int l, m; i++; if (((m = atoi(&comm[i])) < 1) || (m >= c)) { print("alias failed: too few arguments"); btty.flags &= ~B_TTY_ALIASING; return(B_ERR_INV_ARG); } for (l = 0; argv[m][l] != '\0'; l++) alias[k++] = argv[m][l]; } if (comm[i] == '%') { int l; if (j == c) { print("alias failed: too few arguments"); btty.flags &= ~B_TTY_ALIASING; return(B_ERR_INV_ARG); } for (l = 0; argv[j][l] != '\0'; l++) alias[k++] = argv[j][l]; if (comm[i] == '%') j++; i++; } if (comm[i] == ';') { alias[k] = '\0'; print(alias); bttyInterpret(global, alias); memset(alias, 0, B_TTY_LINE_LEN); k = 0; } else alias[k++] = comm[i]; } alias[k++] = '\0'; print(alias); bttyInterpret(global, alias); btty.flags &= ~B_TTY_ALIASING; return(0); } return(2); } /* * controller c o v - very expert usage. */ static int execBristol(guimain *global, int c, char **argv) { int o, p; float v; print("execBristol"); if (execHelpCheck(c, argv)) return(0); if (c == 2) { if (strncmp(bristolcom[1].name, argv[1], strlen(argv[1])) == 0) { snprintf(pbuf, btty.len, "register request %i %p\n\r", btty.i, DEVICE(btty.i).dev); o = write(btty.fd[1], pbuf, strlen(pbuf)); brightonRegisterController((brightonDevice *) DEVICE(btty.i).dev); return(0); } } if (c == 5) { if (strncmp(bristolcom[2].name, argv[1], strlen(argv[1])) == 0) { int sid; if ((o = atoi(argv[2])) < 0) return(3); if (o > 127) return(3); if ((p = atoi(argv[3])) < 0) return(3); if (p > 127) return(3); if ((v = atof(argv[4])) < 0.0f) return(3); if (v > 1.0f) return(3); if (btty.ichan == 0) sid = SYNTHS->sid; else sid = SYNTHS->sid2; bristolMidiSendMsg(global->controlfd, btty.ichan, o, p, (int) (v * C_RANGE_MIN_1)); return(0); } } return(B_ERR_PARAM); } extern int bristolPressureEvent(int, int, int, int); extern int bristolPolyPressureEvent(int, int, int, int, int); /* * This is probably going to become a large part of the interface, it can give * access to loads of stuff that many of the GUI may not use because there was * no other way to control them. * * midi channel 1..16 * midi debug 0..3 * midi lowkey|highkey 0..127 * midi filters lwf|nwf|wwf|hwf * midi notepref hnp|lnp|nnp * midi velocity 1..1000 * midi chanpressure 0..127 * midi polypressure 0..127 0..127 * midi detune 0..500 * midi glide 0..30 * midi legato on/off * midi trig on/off * midi gain 1.. * midi pwd 0.. * midi nrp on/off * midi forwarding on/off * midi tuning fine 0..1.0 * midi tuning coarse 0..1.0 * midi panic */ static int execMidi(guimain *global, int c, char **v) { int i, n, k; if (execHelpCheck(c, v)) return(0); //if (midiHelpCheck(c, v)) return(0); for (i = 0; i < c; i++) print(v[i]); if (c == 1) { snprintf(pbuf, btty.len, "MIDI channel: %i\r\n", SYNTHS->midichannel+1); i = write(btty.fd[1], pbuf, strlen(pbuf)); snprintf(pbuf, btty.len, "SID channel: %i\r\n", btty.ichan); i = write(btty.fd[1], pbuf, strlen(pbuf)); snprintf(pbuf, btty.len, "MIDI debug: %i\r\n", btty.mdbg); i = write(btty.fd[1], pbuf, strlen(pbuf)); snprintf(pbuf, btty.len, "MIDI lowkey %i\r\n", btty.lowkey); i = write(btty.fd[1], pbuf, strlen(pbuf)); snprintf(pbuf, btty.len, "MIDI highkey: %i\r\n", btty.highkey); i = write(btty.fd[1], pbuf, strlen(pbuf)); return(B_ERR_OK); } if (c == 4) { if (strncmp("tuning", v[1], strlen(v[1])) == 0) { float tune = 0.5; if (strncmp("fine", v[2], strlen(v[2])) == 0) { i = MIDI_RP_FINETUNE; if ((tune = atof(v[3])) < 0.0f) return(3); if (tune > 1.0f) return(3); } else if (strncmp("coarse", v[2], strlen(v[3])) == 0) { i = MIDI_RP_COARSETUNE; if ((tune = atof(v[3])) < 0.0f) return(3); if (tune > 1.0f) return(3); } tune *= C_RANGE_MIN_1; bristolMidiSendNRP(global->controlfd, SYNTHS->midichannel, i, tune); return(B_ERR_OK); } if (strncmp("polypressure", v[1], strlen(v[1])) == 0) { int k, p; if ((k = atoi(v[2])) < 0) return(3); if (k > 127) return(3); if ((p = atoi(v[3])) < 0) return(3); if (p > 127) return(3); bristolPolyPressureEvent(global->controlfd, 0, SYNTHS->midichannel, k, p); return(B_ERR_OK); } if (strncmp("controller", v[1], strlen(v[1])) == 0) { int id, value; if ((id = atoi(v[2])) < 0) return(B_ERR_VALUE); if (id > 127) return(B_ERR_VALUE); if ((value = atoi(v[3])) < 0) return(B_ERR_VALUE); if (value > 127) return(B_ERR_VALUE); bristolMidiSendControlMsg(global->controlfd, SYNTHS->midichannel, id, value); return(B_ERR_OK); } return(B_ERR_PARAM); } if (c == 2) { if (strncmp(v[1], "panic", strlen(v[1])) == 0) { bristolMidiSendMsg(global->controlfd, SYNTHS->sid2, 127, 0, BRISTOL_ALL_NOTES_OFF); bristolMidiSendMsg(global->controlfd, SYNTHS->sid, 127, 0, BRISTOL_ALL_NOTES_OFF); return(B_ERR_OK); } else if (strncmp(v[1], "sid", strlen(v[1])) == 0) { snprintf(pbuf, btty.len, "SID channel : %i\r\n", btty.ichan); i = write(btty.fd[1], pbuf, strlen(pbuf)); return(B_ERR_OK); } else if (strncmp(v[1], "channel", strlen(v[1])) == 0) { snprintf(pbuf, btty.len, "MIDI channel: %i\r\n", SYNTHS->midichannel+1); i = write(btty.fd[1], pbuf, strlen(pbuf)); return(B_ERR_OK); } else if (strncmp(v[1], "debug", strlen(v[1])) == 0) { snprintf(pbuf, btty.len, "MIDI debug: %i\r\n", btty.mdbg); i = write(btty.fd[1], pbuf, strlen(pbuf)); return(B_ERR_OK); } return(B_ERR_PARAM); } if (c == 3) { if (strncmp(v[1], "sid", strlen(v[1])) == 0) { if ((n = atoi(v[2])) < 1) n = 0; else n = 1; btty.ichan = n; snprintf(pbuf, btty.len, "SID channel: %i\r\n", btty.ichan); i = write(btty.fd[1], pbuf, strlen(pbuf)); return(B_ERR_OK); } else if (strncmp(v[1], "charpressure", strlen(v[1])) == 0) { if ((n = atoi(v[2])) < 0) return(B_ERR_VALUE); if (n > 127) return(B_ERR_VALUE); bristolPressureEvent(global->controlfd, 0, SYNTHS->midichannel, n); return(B_ERR_OK); } else if (strncmp(v[1], "channel", strlen(v[1])) == 0) { if ((n = atoi(v[2])) < 1) return(3); else if (n > 16) return(3); SYNTHS->midichannel = n - 1; snprintf(pbuf, btty.len, "MIDI channel: %i\r\n", SYNTHS->midichannel+1); i = write(btty.fd[1], pbuf, strlen(pbuf)); SYNTHS->midichannel = SYNTHS->midichannel; if (global->libtest == 0) bristolMidiSendMsg(global->controlfd, SYNTHS->sid, 127, 0, BRISTOL_MIDICHANNEL|SYNTHS->midichannel); if ((k = atoi(v[2])) < 0) return(3); if (k > 127) return(3); SYNTHS->highkey = btty.highkey = k; bristolMidiSendMsg(global->controlfd, SYNTHS->sid, 127, 0, BRISTOL_HIGHKEY|SYNTHS->highkey); return(B_ERR_OK); } else if (strncmp(v[1], "lowkey", strlen(v[1])) == 0) { if ((k = atoi(v[2])) < 0) return(3); if (k > 127) return(3); SYNTHS->lowkey = btty.lowkey = k; bristolMidiSendMsg(global->controlfd, SYNTHS->sid, 127, 0, BRISTOL_LOWKEY|SYNTHS->lowkey); return(B_ERR_OK); } else if (strncmp(v[1], "filter", strlen(v[1])) == 0) { k = 0; if (strcmp(v[2], "lwf") == 0) k = 1; else if (strcmp(v[2], "nwf") == 0) k = 0; else if (strcmp(v[2], "wwf") == 0) k = 2; else if (strcmp(v[2], "hwf") == 0) k = 3; else return(B_ERR_INV_ARG); bristolMidiSendNRP(global->controlfd, SYNTHS->midichannel, BRISTOL_NRP_LWF, k); return(B_ERR_OK); } else if (strncmp(v[1], "detune", strlen(v[1])) == 0) { if ((k = atoi(v[2])) < 0) return(3); if (k > 16383) return(3); bristolMidiSendNRP(global->controlfd, SYNTHS->midichannel, BRISTOL_NRP_DETUNE, k); return(B_ERR_OK); } else if (strncmp(v[1], "velocity", strlen(v[1])) == 0) { if ((k = atoi(v[2])) < 0) return(3); if (k > 16383) return(3); bristolMidiSendNRP(global->controlfd, SYNTHS->midichannel, BRISTOL_NRP_VELOCITY, k); return(B_ERR_OK); } else if (strncmp(v[1], "glide", strlen(v[1])) == 0) { if ((k = atoi(v[2])) < 0) return(3); if (k > 16383) return(3); bristolMidiSendNRP(global->controlfd, SYNTHS->midichannel, BRISTOL_NRP_GLIDE, k); return(B_ERR_OK); } else if (strncmp(v[1], "pwd", strlen(v[1])) == 0) { if ((k = atoi(v[2])) < 0) return(3); if (k > 16383) return(3); bristolMidiSendNRP(global->controlfd, SYNTHS->midichannel, MIDI_RP_PW, k); return(B_ERR_OK); } else if (strncmp(v[1], "gain", strlen(v[1])) == 0) { if ((k = atoi(v[2])) < 0) return(3); if (k > 16383) return(3); bristolMidiSendNRP(global->controlfd, SYNTHS->midichannel, BRISTOL_NRP_GAIN, k); return(B_ERR_OK); } else if (strncmp(v[1], "forwarding", strlen(v[1])) == 0) { k = 1; if (strcmp(v[2], "on") == 0) k = 1; if (strcmp(v[2], "off") == 0) k = 0; bristolMidiSendNRP(global->controlfd, SYNTHS->midichannel, BRISTOL_NRP_FORWARD, k); return(B_ERR_OK); } else if (strncmp(v[1], "nrp", strlen(v[1])) == 0) { if (strcmp(v[2], "on") == 0) SYNTHS->flags |= GUI_NRP; else if (strcmp(v[2], "off") == 0) SYNTHS->flags &= ~GUI_NRP; return(B_ERR_OK); } else if (strncmp(v[1], "enginenrp", strlen(v[1])) == 0) { k = 0; if (strcmp(v[2], "on") == 0) k = 1; if (strcmp(v[2], "off") == 0) k = 0; bristolMidiSendNRP(global->controlfd, SYNTHS->midichannel, BRISTOL_NRP_ENABLE_NRP, k); return(B_ERR_OK); } else if (strncmp(v[1], "legato", strlen(v[1])) == 0) { k = 1; if (strcmp(v[2], "on") == 0) k = 1; if (strcmp(v[2], "off") == 0) k = 0; bristolMidiSendNRP(global->controlfd, SYNTHS->midichannel, BRISTOL_NRP_MNL_VELOC, k); return(B_ERR_OK); } else if (strncmp(v[1], "trigger", strlen(v[1])) == 0) { k = 1; if (strcmp(v[2], "on") == 0) k = 1; if (strcmp(v[2], "off") == 0) k = 0; bristolMidiSendNRP(global->controlfd, SYNTHS->midichannel, BRISTOL_NRP_MNL_TRIG, k); return(B_ERR_OK); } else if (strncmp(v[1], "precedence", strlen(v[1])) == 0) { k = BRIGHTON_LNP; if (strcmp(v[2], "hnp") == 0) k = BRIGHTON_HNP; if (strcmp(v[2], "lnp") == 0) k = BRIGHTON_LNP; if (strcmp(v[2], "nnp") == 0) k = BRIGHTON_POLYPHONIC; bristolMidiSendNRP(global->controlfd, SYNTHS->midichannel, BRISTOL_NRP_MNL_PREF, k); return(B_ERR_OK); } else if (strncmp(v[1], "debug", strlen(v[1])) == 0) { n = atoi(v[2]); switch (n) { default: case 0: n = 0; break; case 1: break; case 2: break; case 3: break; } btty.mdbg = n; if (global->libtest == 0) bristolMidiSendNRP(global->controlfd, SYNTHS->midichannel, BRISTOL_NRP_DEBUG, n); snprintf(pbuf, btty.len, "MIDI debug: %i\r\n", btty.mdbg); i = write(btty.fd[1], pbuf, strlen(pbuf)); return(B_ERR_OK); } return(B_ERR_PARAM); } return(B_ERR_PARAM); } /* * Set line width. Set debug on/off. */ static int execSet(guimain *global, int c, char **v) { int i, n; if (execHelpCheck(c, v)) return(0); for (i = 0; i < c; i++) print(v[i]); if (c > 1) { if (strncmp("memory", v[1], strlen(v[1])) == 0) return(execMemory(global, c - 1, v += 1)); if (strncmp("midi", v[1], strlen(v[1])) == 0) return(execMidi(global, c - 1, v += 1)); if (strncmp("debug", v[1], strlen(v[1])) == 0) return(execDebug(global, c - 1, v += 1)); if (strncmp("bristol", v[1], strlen(v[1])) == 0) return(execBristol(global, c - 1, v += 1)); if (strncmp("control", v[1], strlen(v[1])) == 0) return(execBristol(global, c - 1, v += 1)); if (strncmp("brighton", v[1], strlen(v[1])) == 0) return(execBrighton(global, c - 1, v += 1)); if (strncmp("alias", v[1], strlen(v[1])) == 0) return(execAlias(global, c - 1, v += 1)); if (strncmp("cli", v[1], strlen(v[1])) == 0) return(execCLI(global, c - 1, v += 1)); } if (c == 1) { snprintf(pbuf, btty.len, "line width: %i\r\n", btty.len); i = write(btty.fd[1], pbuf, strlen(pbuf)); snprintf(pbuf, btty.len, "history: %i\r\n", btty.hist_c); i = write(btty.fd[1], pbuf, strlen(pbuf)); if (btty.flags & B_TTY_SAVE_HIST) snprintf(pbuf, btty.len, "savehistory: on\r\n"); else snprintf(pbuf, btty.len, "savehistory: off\r\n"); i = write(btty.fd[1], pbuf, strlen(pbuf)); snprintf(pbuf, btty.len, "prompt: %s\r\n", btty.prompt); i = write(btty.fd[1], pbuf, strlen(pbuf)); snprintf(pbuf, btty.len, "prompttext: %s\r\n", btty.promptText); i = write(btty.fd[1], pbuf, strlen(pbuf)); snprintf(pbuf, btty.len, "accelerator: %0.3f\r\n", btty.accel); i = write(btty.fd[1], pbuf, strlen(pbuf)); snprintf(pbuf, btty.len, "active panel: %i\r\n", btty.p); i = write(btty.fd[1], pbuf, strlen(pbuf)); if (btty.flags & B_TTY_DEBUG) snprintf(pbuf, btty.len, "debug (cli): on\r\n"); else snprintf(pbuf, btty.len, "debug (cli): off\r\n"); i = write(btty.fd[1], pbuf, strlen(pbuf)); if (btty.flags & B_TTY_AWV) snprintf(pbuf, btty.len, "access withdrawn var on\r\n"); else snprintf(pbuf, btty.len, "access withdrawn var off\r\n"); i = write(btty.fd[1], pbuf, strlen(pbuf)); if (btty.flags & B_TTY_AUV) snprintf(pbuf, btty.len, "access unnamed var on\r\n"); else snprintf(pbuf, btty.len, "access unnamed var off\r\n"); i = write(btty.fd[1], pbuf, strlen(pbuf)); return(B_ERR_OK); } if (c == 2) { if (strncmp(v[1], "line", strlen(v[1])) == 0) { snprintf(pbuf, btty.len, "line width: %i\r\n", btty.len); i = write(btty.fd[1], pbuf, strlen(pbuf)); return(B_ERR_OK); } else if (strncmp(v[1], "prompt", strlen(v[1])) == 0) { snprintf(pbuf, btty.len, "prompt: %s\r\n", btty.prompt); i = write(btty.fd[1], pbuf, strlen(pbuf)); return(B_ERR_OK); } else if (strncmp(v[1], "prompttext", strlen(v[1])) == 0) { snprintf(pbuf, btty.len, "prompttext: %s\r\n", btty.promptText); i = write(btty.fd[1], pbuf, strlen(pbuf)); return(B_ERR_OK); } else if (strncmp(v[1], "panel", strlen(v[1])) == 0) { snprintf(pbuf, btty.len, "active panel: %i\r\n", btty.p); i = write(btty.fd[1], pbuf, strlen(pbuf)); return(B_ERR_OK); } else if (strncmp(v[1], "accelerator", strlen(v[1])) == 0) { snprintf(pbuf, btty.len, "accelerator: %0.3f\r\n", btty.accel); i = write(btty.fd[1], pbuf, strlen(pbuf)); return(B_ERR_OK); } else if (strncmp(v[1], "awv", strlen(v[1])) == 0) { if (btty.flags & B_TTY_AWV) snprintf(pbuf, btty.len, "access withdrawn var on\r\n"); else snprintf(pbuf, btty.len, "access withdrawn var off\r\n"); return(B_ERR_OK); } else if (strncmp(v[1], "prompt", strlen(v[1])) == 0) { snprintf(pbuf, btty.len, "prompt: %s\r\n", btty.prompt); i = write(btty.fd[1], pbuf, strlen(pbuf)); return(B_ERR_OK); } else if (strncmp(v[1], "prompttext", strlen(v[1])) == 0) { snprintf(pbuf, btty.len, "prompttext: %s\r\n", btty.promptText); i = write(btty.fd[1], pbuf, strlen(pbuf)); return(B_ERR_OK); } else if (strncmp(v[1], "panel", strlen(v[1])) == 0) { snprintf(pbuf, btty.len, "active panel: %i\r\n", btty.p); i = write(btty.fd[1], pbuf, strlen(pbuf)); return(B_ERR_OK); } else if (strncmp(v[1], "accelerator", strlen(v[1])) == 0) { snprintf(pbuf, btty.len, "accelerator: %0.3f\r\n", btty.accel); i = write(btty.fd[1], pbuf, strlen(pbuf)); return(B_ERR_OK); } else if (strncmp(v[1], "awv", strlen(v[1])) == 0) { if (btty.flags & B_TTY_AWV) snprintf(pbuf, btty.len, "access withdrawn var on\r\n"); else snprintf(pbuf, btty.len, "access withdrawn var off\r\n"); i = write(btty.fd[1], pbuf, strlen(pbuf)); return(B_ERR_OK); } else if (strncmp(v[1], "debug", strlen(v[1])) == 0) { if (btty.flags & B_TTY_DEBUG) snprintf(pbuf, btty.len, "debug (cli): on\r\n"); else snprintf(pbuf, btty.len, "debug (cli): off\r\n"); i = write(btty.fd[1], pbuf, strlen(pbuf)); return(B_ERR_OK); } else if (strncmp(v[1], "save", strlen(v[1])) == 0) { snprintf(pbuf, btty.len, "save set not implemented\r\n"); i = write(btty.fd[1], pbuf, strlen(pbuf)); return(B_ERR_OK); } else if (strncmp(v[1], "savehistory", strlen(v[1])) == 0) { if (btty.flags & B_TTY_SAVE_HIST) snprintf(pbuf, btty.len, "savehistory: on\r\n"); else snprintf(pbuf, btty.len, "savehistory: off\r\n"); i = write(btty.fd[1], pbuf, strlen(pbuf)); return(B_ERR_OK); } else if (strncmp(v[1], "history", strlen(v[1])) == 0) { for (i = btty.hist_c; i > 0; i--) { if (btty.hist[i][0] != '\0') { snprintf(pbuf, btty.len, "%i %s\r\n", i, btty.hist[i]); n = write(btty.fd[1], pbuf, strlen(pbuf)); } } return(B_ERR_OK); } return(2); } if (c == 3) { if (strncmp(v[1], "line", strlen(v[1])) == 0) { if ((n = atoi(v[2])) < 0) return(3); else if (n > B_TTY_LINE_LEN) return(3); else btty.len = n; snprintf(pbuf, btty.len, "line width: %i\r\n", btty.len); i = write(btty.fd[1], pbuf, strlen(pbuf)); return(B_ERR_OK); } else if (strncmp(v[1], "prompttext", strlen(v[1])) == 0) { snprintf(btty.promptText, 64, "%s", v[2]); snprintf(pbuf, btty.len, "prompttext: %s\r\n", btty.promptText); i = write(btty.fd[1], pbuf, strlen(pbuf)); return(B_ERR_OK); } else if (strncmp(v[1], "play", strlen(v[1])) == 0) { if (strncmp(v[2], "mode", strlen(v[2])) == 0) { btty.flags &= ~B_TTY_MMASK; btty.flags |= B_TTY_PLAY; snprintf(pbuf, btty.len, "Play mode: type ':' or to exit\n\r"); i = write(btty.fd[1], pbuf, strlen(pbuf)); return(B_ERR_EARLY); } } else if (strncmp(v[1], "accelerator", strlen(v[1])) == 0) { btty.accel = atof(v[2]); snprintf(pbuf, btty.len, "accelerator: %0.3f\r\n", btty.accel); i = write(btty.fd[1], pbuf, strlen(pbuf)); return(B_ERR_OK); } else if (strncmp(v[1], "panel", strlen(v[1])) == 0) { int x = -1; if ((x = atoi(v[2])) < 0) x = -1; if (x >= SYNTHS->win->app->nresources) x = -1; if (SYNTHS->win->app->resources[x].ndevices == 0) x = -1; if (SYNTHS->win->app->resources[x].devlocn == NULL) x = -1; if (x >= 0) { btty.p = x; if (btty.i >= SYNTHS->win->app->resources[x].ndevices) btty.i = SYNTHS->win->app->resources[x].ndevices - 1; } else return(3); snprintf(pbuf, btty.len, "active panel: %i\r\n", btty.p); i = write(btty.fd[1], pbuf, strlen(pbuf)); return(B_ERR_OK); } else if (strncmp(v[1], "auv", strlen(v[1])) == 0) { btty.flags &= ~B_TTY_AUV; if (strcmp("on", v[2]) == 0) btty.flags |= B_TTY_AWV; if (btty.flags & B_TTY_AWV) snprintf(pbuf, btty.len, "access unnamed var on\r\n"); else snprintf(pbuf, btty.len, "access unnamed var off\r\n"); i = write(btty.fd[1], pbuf, strlen(pbuf)); return(B_ERR_OK); } else if (strncmp(v[1], "awv", strlen(v[1])) == 0) { btty.flags &= ~B_TTY_AWV; if (strcmp("on", v[2]) == 0) btty.flags |= B_TTY_AWV; if (btty.flags & B_TTY_AWV) snprintf(pbuf, btty.len, "access withdrawn var on\r\n"); else snprintf(pbuf, btty.len, "access withdrawn var off\r\n"); i = write(btty.fd[1], pbuf, strlen(pbuf)); return(B_ERR_OK); } else if (strncmp(v[1], "savehistory", strlen(v[1])) == 0) { if (strcmp(v[2], "on") == 0) btty.flags |= B_TTY_SAVE_HIST; else if (strcmp(v[2], "off") == 0) btty.flags &= ~B_TTY_SAVE_HIST; if (btty.flags & B_TTY_SAVE_HIST) snprintf(pbuf, btty.len, "savehistory: on\r\n"); else snprintf(pbuf, btty.len, "savehistory: off\r\n"); i = write(btty.fd[1], pbuf, strlen(pbuf)); return(B_ERR_OK); } else if (strncmp(v[1], "history", strlen(v[1])) == 0) { if ((btty.hist_c = atoi(v[2])) <= 0) btty.hist_c = 50; else if (btty.hist_c > 50) btty.hist_c = 50; return(B_ERR_OK); } else if (strncmp(v[1], "noalias", strlen(v[1])) == 0) { for (i = 0; commands[i].map != -1; i++) { if (commands[i].map != B_COM_ALIAS) continue; if (strcmp(commands[i].name, v[2]) == 0) { commands[i].name[0] = '\0'; commands[i].help[0] = '\0'; commands[i].map = B_COM_FREE; commands[i].exec = NULL; break; } } return(B_ERR_OK); } else if (strncmp(v[1], "debug", strlen(v[1])) == 0) { btty.flags &= ~B_TTY_DEBUG; if (strcmp(v[2], "on") == 0) btty.flags |= B_TTY_DEBUG; if (btty.flags & B_TTY_DEBUG) snprintf(pbuf, btty.len, "debug (cli): on\r\n"); else snprintf(pbuf, btty.len, "debug (cli): off\r\n"); i = write(btty.fd[1], pbuf, strlen(pbuf)); return(B_ERR_OK); } } if (c > 3) { if (strncmp(v[1], "play", strlen(v[1])) == 0) { print("set play"); if (c != 4) return(B_ERR_PARAM); if (strncmp(v[2], "rate", strlen(v[2])) == 0) { int rate; if ((rate = atoi(v[3])) < 0) return(B_ERR_VALUE); sequences[btty.sequence.id].rate = rate; return(B_ERR_OK); } if (strncmp(v[2], "transpose", strlen(v[2])) == 0) { int transpose; transpose = atoi(v[3]); btty.sequence.transpose = transpose; return(B_ERR_OK); } if (strncmp(v[2], "sequence", strlen(v[2])) == 0) { int seq; print("sequence"); if ((seq = atoi(v[3])) < 0) return(B_ERR_VALUE); if (seq >= B_SEQ_COUNT) return(B_ERR_VALUE); if (sequences[seq].count <= 0) return(B_ERR_VALUE); btty.sequence.step = -1; btty.sequence.count = 250 * 60 / sequences[btty.sequence.id].rate; btty.flags &= ~B_TTY_MMASK; btty.flags |= B_TTY_SEQ|B_TTY_RAW; return(B_ERR_EARLY); } } else if ((strncmp(v[1], "history", strlen(v[1])) == 0) && (strncmp(v[2], "comm", strlen(v[2])) == 0)) { char *comm; /* rotate history, add this one */ if ((comm = strstr(cbuf, "comm")) == NULL) return(2); comm += 5; snprintf(btty.hist[1], B_TTY_LINE_LEN, "%s", comm); return(B_ERR_OK); } } return(2); } static int execImport(guimain *global, int c, char **v) { int loc; if (execHelpCheck(c, v)) return(0); loc = SYNTHS->location; if (c == 1) return(2); if (c == 2) { loc = SYNTHS->location; if ((v[1] == NULL) || (v[1][0] == '\0')) return(3); } print(v[1]); if (strncmp("import", v[0], strlen(v[0])) == 0) { if (c == 3) loc = atoi(v[2]); bristolMemoryImport(loc, v[1], RESOURCES->name); return(0); } else if (strncmp("export", v[0], strlen(v[0])) == 0) { if (c == 3) loc = atoi(v[2]); bristolMemoryExport(loc, v[1], RESOURCES->name); return(0); } return(0); } static void execParamChange(guimain *global, float v) { int i; char *name; if ((paramname(btty.i) == NULL) || (paramname(btty.i)[0] == '\0')) name = unknown; else name = paramname(btty.i); /* if ((SYNTHS->win->app->resources[btty.p].devlocn[btty.i].type == 1) || (SYNTHS->win->app->resources[btty.p].devlocn[btty.i].type == 7)) brightonChangeParam(SYNTHS, btty.p, btty.i, v); else brightonChangeParam(SYNTHS, btty.p, btty.i, v * RESOURCES->resources[btty.p].devlocn[btty.i].to); */ brightonChangeParam(SYNTHS, btty.p, btty.i, v * DEVICE(btty.i).to); if (DEVICE(btty.i).to == 1.0f) { if (DEVICE(btty.i).type == 1) snprintf(pbuf, btty.len, "%02i %-25s: %4.0f\r\n", btty.i, name, (1.0 - PDEV(btty.i)->value) * 1000.0f); else if (DEVICE(btty.i).type == 2) snprintf(pbuf, btty.len, "%02i %-25s: %1.0f\r\n", btty.i, name, PDEV(btty.i)->value); else snprintf(pbuf, btty.len, "%02i %-25s: %4.0f\r\n", btty.i, name, PDEV(btty.i)->value * 1000.0f); } else { if (DEVICE(btty.i).type == 1) { if (DEVICE(btty.i).flags & BRIGHTON_REVERSE) snprintf(pbuf, btty.len, "%02i %-25s: %4.0f\r\n", btty.i, name, PDEV(btty.i)->value * DEVICE(btty.i).to); else snprintf(pbuf, btty.len, "%02i %-25s: %4.0f\r\n", btty.i, name, (1.0 - PDEV(btty.i)->value) * DEVICE(btty.i).to); } else if (DEVICE(btty.i).type == 2) { snprintf(pbuf, btty.len, "%02i %-25s: %4.0f\r\n", btty.i, name, PDEV(btty.i)->value); } else snprintf(pbuf, btty.len, "%02i %-25s: %4.0f\r\n", btty.i, name, PDEV(btty.i)->value * DEVICE(btty.i).to); // snprintf(pbuf, btty.len, "%02i %-25s: %3.0f\n\r", btty.i, // name, ((brightonDevice *) DEVICE(btty.i).dev)->value); } i = write(btty.fd[1], pbuf, strlen(pbuf)); } static int execBrighton(guimain *global, int c, char **argv) { int p, d, tp, ti; float v; print("execBrighton"); if (execHelpCheck(c, argv)) return(0); if (c == 2) { if (strncmp(brightoncom[1].name, argv[1], strlen(argv[1])) == 0) { snprintf(pbuf, btty.len, "active panel: %i\r\n", btty.p); p = write(btty.fd[1], pbuf, strlen(pbuf)); return(0); } return(1); } if (c == 3) { if (strncmp(brightoncom[1].name, argv[1], strlen(argv[1])) == 0) { int x; if ((x = atoi(argv[2])) < 0) return(3); if (btty.p > SYNTHS->win->app->nresources) return(3); if (SYNTHS->win->app->resources[x].ndevices == 0) return(3); btty.p = x; snprintf(pbuf, btty.len, "active panel: %i\r\n", btty.p); p = write(btty.fd[1], pbuf, strlen(pbuf)); return(0); } return(2); } if (c == 5) { if (strncmp(brightoncom[2].name, argv[1], strlen(argv[1])) == 0) { /* Device settings */ if ((p = atoi(argv[2])) < 0) return(B_ERR_PARAM); if (p >= SYNTHS->win->app->nresources) return(B_ERR_PARAM); if (SYNTHS->win->app->resources[p].ndevices <= 0) return(B_ERR_PARAM); if ((d = atoi(argv[3])) < 0) return(B_ERR_PARAM); if (d >= SYNTHS->win->app->resources[p].ndevices) return(B_ERR_PARAM); tp = btty.p; ti = btty.i; btty.p = p; btty.i = d; if (argv[4][1] == '=') { if (argv[4][0] == '+') v = atof(&argv[4][2]) + PDEV(d)->value; else if (argv[4][0] == '-') v = PDEV(d)->value - atof(&argv[4][2]); else return(B_ERR_VALUE); } else if ((v = atof(argv[4])) < 0.0f) return(B_ERR_VALUE); if (v < 0) v = 0.0f; execParamChange(global, v); btty.p = tp; btty.i = ti; return(B_ERR_OK); } } return(B_ERR_PARAM); } static void cliParamChange(guimain *global, float v) { int i; char *name, crlf[4] = "\r\n", *c1 = crlf, *c2 = ""; if ((paramname(btty.i) == NULL) || (paramname(btty.i)[0] == '\0')) name = unknown; else name = paramname(btty.i); if (v != 0) { //if (RESOURCES->resources[btty.p].devlocn[btty.i].to != 1.0f) if (DEVICE(btty.i).to != 1.0f) { if (DEVICE(btty.i).type == 1) { if (DEVICE(btty.i).flags & BRIGHTON_VERTICAL) { if (v > 0) brightonChangeParam(SYNTHS, btty.p, btty.i, PDEV(btty.i)->value * DEVICE(btty.i).to + 1); else brightonChangeParam(SYNTHS, btty.p, btty.i, PDEV(btty.i)->value * DEVICE(btty.i).to - 1); } else if (DEVICE(btty.i).flags & BRIGHTON_REVERSE) { if (v > 0) brightonChangeParam(SYNTHS, btty.p, btty.i, PDEV(btty.i)->value * DEVICE(btty.i).to - 1); else brightonChangeParam(SYNTHS, btty.p, btty.i, PDEV(btty.i)->value * DEVICE(btty.i).to + 1); } else { if (v > 0) brightonChangeParam(SYNTHS, btty.p, btty.i, (1.0 - PDEV(btty.i)->value) * DEVICE(btty.i).to + 1); else brightonChangeParam(SYNTHS, btty.p, btty.i, (1.0 - PDEV(btty.i)->value) * DEVICE(btty.i).to - 1); } } else if (DEVICE(btty.i).type == 7) { if (v > 0) brightonChangeParam(SYNTHS, btty.p, btty.i, PDEV(btty.i)->value * DEVICE(btty.i).to + 1); else brightonChangeParam(SYNTHS, btty.p, btty.i, PDEV(btty.i)->value * DEVICE(btty.i).to - 1); } else if (DEVICE(btty.i).type == 2) { if (v > 0) brightonChangeParam(SYNTHS, btty.p, btty.i, PDEV(btty.i)->value + 1); else brightonChangeParam(SYNTHS, btty.p, btty.i, PDEV(btty.i)->value - 1); } else { if (v > 0) brightonChangeParam(SYNTHS, btty.p, btty.i, PDEV(btty.i)->value * DEVICE(btty.i).to + 1); else brightonChangeParam(SYNTHS, btty.p, btty.i, PDEV(btty.i)->value * DEVICE(btty.i).to - 1); } } else { if (DEVICE(btty.i).type == 1) { if (DEVICE(btty.i).flags & BRIGHTON_VERTICAL) brightonChangeParam(SYNTHS, btty.p, btty.i, PDEV(btty.i)->value + v); else if (DEVICE(btty.i).flags & BRIGHTON_REVERSE) brightonChangeParam(SYNTHS, btty.p, btty.i, PDEV(btty.i)->value - v); else brightonChangeParam(SYNTHS, btty.p, btty.i, (1.0 - PDEV(btty.i)->value) + v); } else brightonChangeParam(SYNTHS, btty.p, btty.i, PDEV(btty.i)->value + v); } } if (btty.flags & B_TTY_COOKED) { print("post return"); c1 = c2; c2 = crlf; } else print("pre return"); if (DEVICE(btty.i).to == 1.0f) { if (DEVICE(btty.i).type == 1) { if (DEVICE(btty.i).flags & BRIGHTON_VERTICAL) snprintf(pbuf, btty.len, "%s%02i %-25s: %4.0f%s", c1, btty.i, name, PDEV(btty.i)->value * 1000.0f, c2); else snprintf(pbuf, btty.len, "%s%02i %-25s: %4.0f%s", c1, btty.i, name, (1.0 - PDEV(btty.i)->value) * 1000.0f, c2); } else if (DEVICE(btty.i).type == 2) snprintf(pbuf, btty.len, "%s%02i %-25s: %4.0f%s", c1, btty.i, name, PDEV(btty.i)->value, c2); else snprintf(pbuf, btty.len, "%s%02i %-25s: %4.0f%s", c1, btty.i, name, PDEV(btty.i)->value * 1000.0f, c2); } else { if (DEVICE(btty.i).type == 1) { if (DEVICE(btty.i).flags & BRIGHTON_REVERSE) snprintf(pbuf, btty.len, "%s%02i %-25s: %4.0f%s", c1, btty.i, name, PDEV(btty.i)->value * DEVICE(btty.i).to, c2); else snprintf(pbuf, btty.len, "%s%02i %-25s: %4.0f%s", c1, btty.i, name, (1.0 - PDEV(btty.i)->value) * DEVICE(btty.i).to, c2); } else if (DEVICE(btty.i).type == 2) { snprintf(pbuf, btty.len, "%s%02i %-25s: %4.0f%s", c1, btty.i, name, PDEV(btty.i)->value, c2); } else snprintf(pbuf, btty.len, "%s%02i %-25s: %4.0f%s", c1, btty.i, name, PDEV(btty.i)->value * DEVICE(btty.i).to, c2); // snprintf(pbuf, btty.len, "%02i %-25s: %3.0f\n\r", btty.i, // name, ((brightonDevice *) DEVICE(btty.i).dev)->value); } lp = PDEV(btty.i)->value; i = write(btty.fd[1], pbuf, strlen(pbuf)); } void brightonCLIinit(guimain *global, int fd[]) { btty.fd[0] = fd[0]; btty.fd[1] = fd[1]; btty.cycle = 500; snprintf(btty.prompt, 64, "nicky"); btty.global = global; btty.flags |= B_TTY_COOKED|B_TTY_INIT; } #define B_MATCHES 64 /* * Take input line, extract word up to first space and attempt completion. * If we get a completion see if there are more words and complete them with * the new comset */ int bttyCookedCompletion(char *line, comSet *coms) { int i, v, count = 0, t, c, first = -1; char src[B_TTY_LINE_LEN], dst[B_TTY_LINE_LEN]; char *matches[B_MATCHES]; print("Complete"); if (coms == NULL) return(0); print(line); memset(matches, 0, sizeof(matches)); memset(src, 0, B_TTY_LINE_LEN); memset(dst, 0, B_TTY_LINE_LEN); for (i = 0; 1 ; i++) { if (((src[i] = line[i]) == ' ') || (src[i] == '\0')) { src[i] = '\0'; break; } } for (v = 0; coms[v].map != B_COM_LAST; v++) { if (strncasecmp(coms[v].name, src, strlen(src)) == 0) { print(coms[v].name); matches[count] = brightonmalloc(64); snprintf(matches[count], 64, "%s", coms[v].name); if (first < 0) first = v; if (++count >= B_MATCHES) break; } } if (count == 1) { /* * We now have one word filled out, see if we can continue */ snprintf(src, B_TTY_LINE_LEN, "%s", coms[first].name); if (line[i] != '\0') { snprintf(dst, B_TTY_LINE_LEN, "%s", &line[i + 1]); print("subsearch"); print(dst); if (bttyCookedCompletion(dst, coms[first].subcom) >= 1) snprintf(line, B_TTY_LINE_LEN, "%s %s", src, dst); else snprintf(line, B_TTY_LINE_LEN, "%s %s", src, &line[i + 1]); } else snprintf(line, B_TTY_LINE_LEN, "%s ", src); //btty.edit_p = strlen(src); } else if (count != 0) { int y, x, ch, cont = 1; /* Many hits - see how we can match them, display the result */ for (x = 0; cont; x++) { ch = matches[0][x]; for (y = 1; y < count; y++) { if (matches[y][x] == '\0') cont = 0; if (matches[y][x] != ch) cont = 0; } } if (x > 0) { c = 0; ch = ' '; /* Show the list of commands we have matched */ for (y = 0; y < count; y++) { t = write(btty.fd[1], matches[y], strlen(matches[y])); t = write(btty.fd[1], &ch, 1); if ((c += strlen(matches[y]) + 1) > btty.len - 16) { snprintf(pbuf, 4, "\n\r"); t = write(btty.fd[1], pbuf, 2); c = 0; } } /* And an extra return if we need it */ if (c != 0) { snprintf(pbuf, 4, "\n\r"); t = write(btty.fd[1], pbuf, 2); } /* Then see if we can move the display forward */ if (x > strlen(line)) { snprintf(line, x, "%s", matches[0]); btty.edit_p = strlen(line); } // snprintf(pbuf, B_TTY_LINE_LEN, "%i %s\r\n", x, line); // t = write(btty.fd[1], pbuf, strlen(pbuf)); } } btty.edit_p = strlen(line); for (i = 0; matches[i] != NULL; i++) brightonfree(matches[i]); return(count); } /* * Search only through the CLI command set */ static int bttyComplete(guimain *global) { int v, first = -1, count = 0, c, t;//, mi = 0; char *matches[B_MATCHES]; memset(matches, 0, sizeof(matches)); if (btty.flags & B_TTY_DEBUG) { snprintf(pbuf, btty.len, "\n\rcomplete %s\r", cbuf); t = write(btty.fd[1], pbuf, strlen(pbuf)); } if (btty.flags & B_TTY_COOKED) { /* Complete then edit */ if (isdigit(cbuf[0])) { switch (strlen(cbuf)) { case 1: case 2: v = atoi(cbuf); if (btty.hist[v][0] == '\0') break; snprintf(cbuf, btty.len, "%s", btty.hist[v]); btty.edit_p = strlen(cbuf); return(1); default: break; } } /* Complete then edit */ if ((cbuf[0] == '!') && (isdigit(cbuf[1]))) { switch (strlen(&cbuf[1])) { case 1: case 2: v = atoi(&cbuf[1]); if (btty.hist[v][0] == '\0') break; snprintf(cbuf, btty.len, "%s", btty.hist[v]); btty.edit_p = strlen(cbuf); return(1); default: break; } } count = bttyCookedCompletion(cbuf, commands); btty.edit_p = strlen(cbuf); } for (v = 0; ((matches[v] != NULL) && (v < B_MATCHES)); v++) brightonfree(matches[v]); memset(matches, 0, sizeof(matches)); if (count != 0) return(0); c = SYNTHS->win->app->resources[btty.p].ndevices; for (v = 0; v != c; v++) { if (cbuf[0] == '^') { if (strncasecmp(paramname(v), &cbuf[1], strlen(cbuf) - 1) == 0) { if (first < 0) first = v; matches[count] = brightonmalloc(64); snprintf(matches[count], 64, "%s", paramname(v)); if (++count >= B_MATCHES) break; } } else if (strcasestr(paramname(v), cbuf) != NULL) { if (first < 0) first = v; matches[count] = brightonmalloc(64); snprintf(matches[count], 64, "%s", paramname(v)); if (++count >= B_MATCHES) break; } } if (count == 1) { snprintf(cbuf, btty.len, "%s", paramname(first)); btty.i = first; btty.edit_p = strlen(cbuf); } else if (count != 0) { int y, x, ch, cont = 1; /* Many hits - see how far we can match them, display the result */ for (x = 0; cont; x++) { ch = matches[0][x]; for (y = 1; y < count; y++) { if (matches[y][x] == '\0') cont = 0; if (matches[y][x] != ch) cont = 0; } } if (x > 0) { c = 0; ch = ' '; for (y = 0; y < count; y++) { t = write(btty.fd[1], matches[y], strlen(matches[y])); t = write(btty.fd[1], &ch, 1); if ((c += strlen(matches[y]) + 1) > btty.len - 16) { snprintf(pbuf, 4, "\n\r"); t = write(btty.fd[1], pbuf, 2); c = 0; } } if (c != 0) { snprintf(pbuf, 4, "\n\r"); t = write(btty.fd[1], pbuf, 2); } if (x > strlen(cbuf)) { snprintf(cbuf, x, "%s", matches[0]); btty.edit_p = strlen(cbuf); } } } for (v = 0; ((matches[v] != NULL) && (v < B_MATCHES)); v++) brightonfree(matches[v]); return(count); } /* * Search only through the synth parameters. */ static int bttySearch(guimain *global) { int v, first = -1, count = 0; // snprintf(pbuf, btty.len, "bttySearch\n\r"); // t = write(btty.fd[1], pbuf, strlen(pbuf)); if (cbuf[0] == '\0') return(1); if (btty.flags & B_TTY_DEBUG) { snprintf(pbuf, btty.len, "\n\rsearch %s\r", cbuf); v = write(btty.fd[1], pbuf, strlen(pbuf)); } /* * Search through the internal commands and the synth parameters. If only * one match then commplete it, otherwise list them. */ if (btty.i >= SYNTHS->win->app->resources[btty.p].ndevices) { btty.i = SYNTHS->win->app->resources[btty.p].ndevices - 1; v = 0; } else v = btty.i + 1; for (; v != btty.i; v++) { if (v >= SYNTHS->win->app->resources[btty.p].ndevices) v = -1; //snprintf(pbuf, btty.len, "%s %s %i %i\n\r", paramname(v), cbuf, btty.i, v); //t = write(btty.fd[1], pbuf, strlen(pbuf)); if (paramname(v) == NULL) continue; if (unnamed(v)) continue; if (cbuf[0] == '^') { if (strncasecmp(paramname(v), &cbuf[1], strlen(cbuf) - 1) == 0) { if (first == -1) first = v; count++; break; } } else if (strcasestr(paramname(v), cbuf) != NULL) { if (first == -1) first = v; count++; break; } } if (first >= 0) btty.i = first; cliParamChange(global, 0.0f); btty.flags &= ~B_TTY_MMASK; btty.flags |= B_TTY_RAW; btty.edit_p = 0; btty.hist_tmp = 0; memset(cbuf, 0, B_TTY_LINE_LEN); return(count); } static int execDebug(guimain *global, int c, char **v) { int i; if (execHelpCheck(c, v)) return(0); if (c == 2) { if (strncmp("off", v[1], strlen(v[1])) == 0) btty.flags &= ~B_TTY_DEBUG; else if (strncmp("on", v[1], strlen(v[1])) == 0) btty.flags |= B_TTY_DEBUG; else btty.flags &= ~B_TTY_DEBUG; return(0); } if (c == 3) { if (strncmp("cli", v[1], strlen(v[1])) == 0) { if (strncmp("off", v[2], strlen(v[2])) == 0) btty.flags &= ~B_TTY_DEBUG; else if (strncmp("on", v[2], strlen(v[2])) == 0) btty.flags |= B_TTY_DEBUG; else btty.flags &= ~B_TTY_DEBUG; return(0); } if (strncmp(debugcomm[2].name, v[1], strlen(v[1])) == 0) { if (strncmp("off", v[2], strlen(v[2])) == 0) { SYNTHS->flags &= ~REQ_DEBUG_MASK; SYNTHS->win->flags &= ~BRIGHTON_DEBUG; } else if (strncmp("on", v[2], strlen(v[2])) == 0) { SYNTHS->flags |= REQ_DEBUG_MASK; SYNTHS->win->flags |= BRIGHTON_DEBUG; } } if (strncmp("engine", v[1], strlen(v[1])) == 0) { if ((btty.edbg = atoi(v[2])) <= 0) btty.edbg = 0; if (btty.edbg > 15) btty.edbg = 15; bristolMidiSendMsg(global->controlfd, SYNTHS->sid, BRISTOL_SYSTEM, 0, BRISTOL_REQ_DEBUG|btty.edbg); snprintf(pbuf, btty.len, "debug (engine): %i\r\n", btty.edbg); i = write(btty.fd[1], pbuf, strlen(pbuf)); return(0); } if (strncmp("midi", v[1], strlen(v[1])) == 0) { int n = atoi(v[2]); switch (n) { default: case 0: n = 0; break; case 1: break; case 2: break; case 3: break; } btty.mdbg = n; if (global->libtest == 0) bristolMidiSendNRP(global->controlfd, SYNTHS->midichannel, BRISTOL_NRP_DEBUG, n); snprintf(pbuf, btty.len, "MIDI debug: %i\r\n", btty.mdbg); i = write(btty.fd[1], pbuf, strlen(pbuf)); return(B_ERR_OK); } } if (c == 1) { if (btty.flags & B_TTY_DEBUG) snprintf(pbuf, btty.len, "debug (cli): on\r\n"); else snprintf(pbuf, btty.len, "debug (cli): off\r\n"); i = write(btty.fd[1], pbuf, strlen(pbuf)); snprintf(pbuf, btty.len, "debug (engine): %i\r\n", btty.edbg); i = write(btty.fd[1], pbuf, strlen(pbuf)); return(0); } return(0); } static int execLoad(guimain *global, int c, char **v) { int n = 0, undo = 0; if (execHelpCheck(c, v)) return(0); print(v[0]); if (c >= 2) { if (strncmp("undo", v[1], strlen(v[1])) == 0) undo = 1; else if ((n = atoi(v[1])) < 0) return(0); } if ((strncmp(v[0], "load", strlen(v[0])) == 0) || (strncmp(v[0], "read", strlen(v[0])) == 0)) { if (undo) { SYNTHS->location = 9999; bttyMemLoad(global); SYNTHS->location = btty.lastmem; } else if (c == 1) { /* load current mem */ btty.lastmem = SYNTHS->location; bttyMemLoad(global); SYNTHS->location = btty.lastmem; return(0); } else { /* load named memory */ btty.lastmem = SYNTHS->location; SYNTHS->location = n; bttyMemLoad(global); } } if ((strncmp(v[0], "save", strlen(v[0])) == 0) || (strncmp(v[0], "write", strlen(v[0])) == 0)) { if (c == 1) { /* save current mem */ bttyMemSave(global); return(0); } else { SYNTHS->location = n; bttyMemSave(global); } } if (strncmp(v[0], "find", strlen(v[0])) == 0) { int location = SYNTHS->location + 1; if (location > 1023) location = 0; if ((c == 2) && (strncmp(v[1], "free", strlen(v[1])) == 0)) { /* find free mem */ while (loadMemory(SYNTHS, RESOURCES->name, 0, location, SYNTHS->mem.active, 0, BRISTOL_STAT) == 0) { if (++location > 1024) location = 0; if (location == SYNTHS->location) break; } if (location != SYNTHS->location) { SYNTHS->location = location; snprintf(pbuf, btty.len, "free: %i\r\n", SYNTHS->location); n = write(btty.fd[1], pbuf, strlen(pbuf)); } else { snprintf(pbuf, btty.len, "no free memories\r\n"); n = write(btty.fd[1], pbuf, strlen(pbuf)); } } if ((c == 2) && ((strncmp(v[1], "load", strlen(v[1])) == 0) || (strncmp(v[1], "read", strlen(v[1])) == 0))) { /* find mem */ while (loadMemory(SYNTHS, RESOURCES->name, 0, location, SYNTHS->mem.active, 0, BRISTOL_STAT) != 0) { if (++location > 1024) location = 0; if (location == SYNTHS->location) break; } SYNTHS->location = location; bttyMemLoad(global); } if (c == 1) { /* find mem */ while (loadMemory(SYNTHS, RESOURCES->name, 0, location, SYNTHS->mem.active, 0, BRISTOL_STAT) != 0) { if (++location > 1024) location = 0; if (location == SYNTHS->location) break; } if (location != SYNTHS->location) { SYNTHS->location = location; snprintf(pbuf, btty.len, "mem: %i\r\n", SYNTHS->location); n = write(btty.fd[1], pbuf, strlen(pbuf)); } else { snprintf(pbuf, btty.len, "no memories\r\n"); n = write(btty.fd[1], pbuf, strlen(pbuf)); } return(0); } } return(0); } static int execHelp(guimain *global, int c, char **v) { int i, n; if (execHelpCheck(c, v)) return(0); print(v[0]); if (c == 1) { snprintf(pbuf, B_TTY_LINE_LEN, "CLI ':insert' mode command list:\r\n"); n = write(btty.fd[1], pbuf, strlen(pbuf)); for (i = 0; commands[i].map != -1; i++) { if (commands[i].map == B_COM_NOT_USED) continue; snprintf(pbuf, B_TTY_LINE_LEN, "%12s (:) %s\n\r", commands[i].name, commands[i].help); if (commands[i].map == B_COM_ALIAS) pbuf[14] = 'a'; else pbuf[14] = 'c'; n = write(btty.fd[1], pbuf, strlen(pbuf)); } return(0); } for (i = 0; commands[i].map != B_COM_LAST; i++) { if (commands[i].map == B_COM_NOT_USED) continue; if (strncmp(commands[i].name, v[1], strlen(v[1])) == 0) { snprintf(pbuf, B_TTY_LINE_LEN, "%12s: %s\n\r", commands[i].name, commands[i].help); n = write(btty.fd[1], pbuf, strlen(pbuf)); break; } } if (commands[i].map == B_COM_LAST) { snprintf(pbuf, btty.len, "help '%s' not found\n\r", v[1]); n = write(btty.fd[1], pbuf, strlen(pbuf)); } return(0); } static int execQuit(guimain *global, int c, char **v) { if ((c == 1) && (strlen(v[0]) == 4) && (strcmp(v[0], "quit") == 0)) return(B_ERR_EXIT); return(B_ERR_PARAM); } static int bttyExecute(guimain *global, int c, char **v) { int i, j, k, n; char var[B_TTY_LINE_LEN]; float value = 0.0f; if (btty.flags & B_TTY_DEBUG) { for (i = 0; i < c; i++) { snprintf(pbuf, btty.len, "%i: %i: %s\n\r", i, (int) strlen(v[i]), v[i]); n = write(btty.fd[1], pbuf, strlen(pbuf)); } } for (i = 0; commands[i].map != B_COM_LAST; i++) { if (commands[i].map == B_COM_NOT_USED) continue; if (commands[i].map == B_COM_FREE) continue; if ((strncmp(v[0], commands[i].name, strlen(v[0])) == 0) && (commands[i].exec != NULL)) { n = commands[i].exec(global, c, v); if (btty.flags & B_TTY_ALIASING) return(n); memset(pbuf, 0, B_TTY_LINE_LEN); return(n); } } /* * Search for the command in the synth parameters. */ for (i = 0, j = 0, k = 0, n = -1; j < c; i++) { switch (v[j][i]) { case '\0': i = -1; if (++j < c) var[k++] = ' '; else var[k++] = '\0'; break; case '=': var[k] = '\0'; print(var); value = atof(&v[j][++i]); n = 1; break; case '+': if (v[j][i+1] == '+') { n = 3; } else if (v[j][i+1] == '=') { n = 4; ++i; value = atof(&v[j][++i]); } else { n = 2; } var[k] = '\0'; print("found"); break; case '-': if (v[j][i+1] == '-') { n = 6; } else if (v[j][i+1] == '=') { n = 7; ++i; value = atof(&v[j][++i]); } else { n = 5; } var[k] = '\0'; print("found"); break; default: var[k++] = v[j][i]; break; } if (n != -1) break; } for (i = 0; i < SYNTHS->win->app->resources[btty.p].ndevices; i++) { if ((paramname(i) == NULL) || (paramname(i)[0] == '\0')) continue; if (strcmp(var, paramname(i)) == 0) { print(paramname(i)); btty.i = i; switch (n) { case 1: /* Value was set explicity */ break; case 2: /* + */ value = PDEV(btty.i)->value + 0.01; break; case 3: /* ++ */ value = PDEV(btty.i)->value + btty.accel; break; case 4: /* += */ value += PDEV(btty.i)->value; break; case 5: /* - */ if ((value = PDEV(btty.i)->value - 0.01) < 0.0f) value = 0.0f; break; case 6: /* -- */ if ((value = PDEV(btty.i)->value - btty.accel) < 0.0f) value = 0.0f; break; case 7: /* -= */ if ((value = PDEV(btty.i)->value - value) < 0.0f) value = 0.0f; break; } if (n > 0) execParamChange(global, value); else cliParamChange(global, 0.0f); n = 0; return(0); } } memset(pbuf, 0, B_TTY_LINE_LEN); return(1); } static char resvar[64]; char * getprintvar(guimain *global, char *var) { int i; if (strcmp(var, "panelid") == 0) { snprintf(resvar, 64, "%s", RESOURCES->resources[btty.p].name); return(resvar); } if (strcmp(var, "algo") == 0) { snprintf(resvar, 64, "%s", RESOURCES->name); return(resvar); } if (strcmp(var, "channel") == 0) { snprintf(resvar, 64, "%i", SYNTHS->midichannel + 1); return(resvar); } if (strcmp(var, "memory") == 0) { snprintf(resvar, 64, "%i", SYNTHS->location); return(resvar); } for (i = 0 ; i < SYNTHS->win->app->resources[btty.p].ndevices; i++) { if (strcasecmp(paramname(i), var) == 0) break; } if (i >= SYNTHS->win->app->resources[btty.p].ndevices) { snprintf(resvar, 64, "%s", var); return(resvar); } /* * Found var, take value. */ if (DEVICE(i).to == 1.0f) { if (DEVICE(i).type == 2) snprintf(resvar, 64, "%1.0f", PDEV(i)->value); else snprintf(resvar, 64, "%-3.0f", PDEV(i)->value*1000.0f); } else snprintf(resvar, 64, "%1.0f", PDEV(btty.i)->value); return(resvar); } /* * So how much work to accept a single string: * promt='mem %memory% chan %channel%' */ char * printprompt(guimain *global) { int i = 0, j = 0, aliasing = 0;; char var[64], *s = btty.promptText, *d = btty.prompt, *alias; /* * Format is "text", or "text " where var is searched in the * synth table. * * We are looking for 'mem %something% chan %something%: ' */ for (i = 0; i < 64; i++) { if (*s == '\0') { *d = '\0'; break; } if (*s == '%') { if (aliasing) { var[j] = '\0'; alias = getprintvar(global, var); for (; *alias != 0;) *d++ = *alias++; aliasing = 0; } else { aliasing = 1; memset(var, 0, 64); j = 0; } s++; } else if (aliasing) var[j++] = *s++; else *d++ = *s++; } if (btty.prompt[0] == '\0') { btty.prompt[0] = ':'; btty.prompt[1] = '\0'; } return(btty.prompt); } static int bttyInterpret(guimain *global, char *tbuf) { int v, i = 0, j = 0, k, quoted = 0; char *comm = tbuf, **vargs, zbuf[B_TTY_LINE_LEN]; while (isspace(*comm)) comm++; /* * This is to 'overlook' cooked commands that start with a colon, they * typicaly come from retyping ':' due to a damaged output stream from * debuging output. */ if ((*comm == ':') && (btty.flags & B_TTY_COOKED)) comm++; if (comm[0] == '!') { if (((i = atoi(&comm[1])) < 0) || (i >= 49)) { btty.hist_tmp = 0; btty.edit_p = 0; memset(tbuf, 0, B_TTY_LINE_LEN); return(0); } memset(zbuf, 0, B_TTY_LINE_LEN); snprintf(zbuf, B_TTY_LINE_LEN, "%s", btty.hist[i]); comm = zbuf; } if ((comm[0] == '\0') || (isalpha(comm[0]) == 0)) { v = write(btty.fd[1], btty.hist[0], strlen(btty.hist[0])); snprintf(pbuf, btty.len, "\r:"); v = write(btty.fd[1], pbuf, strlen(pbuf)); btty.edit_p = 0; memset(cbuf, 0, B_TTY_LINE_LEN); memset(btty.hist[0], 0, B_TTY_LINE_LEN); return(1); } if (strncmp("history", comm, strlen(comm)) == 0) { for (i = btty.hist_c; i > 0; i--) { if (btty.hist[i][0] == '\0') continue; snprintf(pbuf, B_TTY_LINE_LEN, "%i %s\n\r", i, btty.hist[i]); v = write(btty.fd[1], pbuf, strlen(pbuf)); } snprintf(pbuf, B_TTY_LINE_LEN, ":"); v = write(btty.fd[1], pbuf, strlen(pbuf)); btty.edit_p = 0; memset(cbuf, 0, B_TTY_LINE_LEN); return(0); } if (((strncmp("quit", comm, 4) == 0) || (strncmp("exit", comm, 4) == 0)) && (strlen(comm) == 4)) { memset(pbuf, 0, B_TTY_LINE_LEN); snprintf(pbuf, btty.len, "quiting\n\r"); v = write(btty.fd[1], pbuf, strlen(pbuf)); brightonCLIcleanup(); return(-1); } if (strlen(comm) == 0) { snprintf(pbuf, B_TTY_LINE_LEN, "\r%s", btty.prompt); v = write(btty.fd[1], pbuf, strlen(pbuf)); btty.edit_p = 0; memset(cbuf, 0, B_TTY_LINE_LEN); return(1); } if (~btty.flags & B_TTY_RAW) bttyManageHistory(comm); vargs = brightonmalloc(sizeof(size_t) * B_TTY_ARGC); memset(vargs, 0, sizeof(size_t) * B_TTY_ARGC); for (k = 0, i = 0, j = 0; k < btty.len; k++) { /* Get an arg pointer */ if (vargs[i] == NULL) { vargs[i] = brightonmalloc(B_TTY_LINE_LEN); memset(vargs[i], 0, B_TTY_LINE_LEN); } /* See if it is the end of the line */ if (comm[k] == '\0') { if ((quoted) & (j != 0)) vargs[i][j - 1] = '"'; vargs[i][j] = '\0'; if (j != 0) i++; break; } if ((comm[k] == '\'') || (comm[k] == '"')) { //vargs[i][j++] = comm[k]; if (quoted) { quoted = 0; vargs[i][j] = '\0'; if (j == 0) break; if (++i >= B_TTY_ARGC) break; j = 0; } else quoted = 1; } else if ((comm[k] == ' ') & (quoted == 0)) { vargs[i][j] = '\0'; if (j == 0) break; if (++i >= B_TTY_ARGC) break; j = 0; } else vargs[i][j++] = comm[k]; } k = bttyExecute(global, i, vargs); switch (k) { case 0: if (btty.flags & B_TTY_DEBUG) { snprintf(pbuf, btty.len, "success: command executed\n\r"); v = write(btty.fd[1], pbuf, strlen(pbuf)); } break; case B_ERR_NOT_FOUND: snprintf(pbuf, btty.len, "failed: command not found\n\r"); v = write(btty.fd[1], pbuf, strlen(pbuf)); break; case B_ERR_PARAM: snprintf(pbuf, btty.len, "failed: parameter error\n\r"); v = write(btty.fd[1], pbuf, strlen(pbuf)); break; case B_ERR_VALUE: snprintf(pbuf, btty.len, "failed: parameter out of range\n\r"); v = write(btty.fd[1], pbuf, strlen(pbuf)); break; case B_ERR_INV_ARG: snprintf(pbuf, btty.len, "failed: invalid argument\n\r"); v = write(btty.fd[1], pbuf, strlen(pbuf)); break; case B_ERR_EXIT: snprintf(pbuf, btty.len, "requested to exit\n\r"); v = write(btty.fd[1], pbuf, strlen(pbuf)); break; case B_ERR_EARLY: break; default: snprintf(pbuf, btty.len, "failed: unknown error\n\r"); v = write(btty.fd[1], pbuf, strlen(pbuf)); break; } for (i = 0; vargs[i] != NULL; i++) brightonfree(vargs[i]); brightonfree(vargs); snprintf(btty.hist[0], btty.len, "%s", b_blank); if (~btty.flags & B_TTY_RAW) { snprintf(pbuf, btty.len, "\r%s\r", b_blank); //snprintf(pbuf, btty.len, "\r:"); v = write(btty.fd[1], pbuf, strlen(pbuf)); } btty.edit_p = 0; memset(cbuf, 0, B_TTY_LINE_LEN); memset(btty.hist[0], 0, B_TTY_LINE_LEN); return(k); } static int bttyPlayMode(guimain *global, char ch) { int v; if (btty.flags & B_TTY_DEBUG) { snprintf(pbuf, btty.len, "%x\r\n", ch); v = write(btty.fd[1], pbuf, strlen(pbuf)); } btty.acycle = btty.pcycle; if (ch == 0x1b) { btty.flags &= ~B_TTY_MMASK; btty.flags |= B_TTY_RAW; brightonKeyInput(SYNTHS->win, btty.key, 0); cliParamChange(global, 0.0f); btty.acycle = btty.cycle; return(B_ERR_OK); } else if (ch == ':') { btty.flags &= ~B_TTY_MMASK; btty.flags |= B_TTY_COOKED; brightonKeyInput(SYNTHS->win, btty.key, 0); snprintf(pbuf, btty.len, "%s", btty.prompt); v = write(btty.fd[1], pbuf, strlen(pbuf)); btty.acycle = btty.cycle; return(B_ERR_OK); } /* They were the two escape codes, now we have to play keys */ if (ch != btty.key) { brightonKeyInput(SYNTHS->win, btty.key, 0); brightonKeyInput(SYNTHS->win, ch, 1); btty.key = ch; btty.flags &= ~B_TTY_CLEAR_KEY; } return(B_ERR_OK); } static int bttyCookedMode(guimain *global, char ch) { int v, i; snprintf(pbuf, btty.len, "\r%s", b_blank); v = write(btty.fd[1], pbuf, strlen(pbuf)); snprintf(pbuf, btty.len, "\r"); v = write(btty.fd[1], pbuf, strlen(pbuf)); btty.acycle = btty.cycle; /* * Start with escape, this will later become interpretted as it could * also by arrows for history functions. */ if (btty.flags & B_TTY_RAW_P2) { btty.flags &= ~B_TTY_MMASK; btty.flags |= B_TTY_COOKED; /* * If we get back here with P2 then we have an arrow escape. Start with * up and down arrow for history, then command line editing later. */ switch (ch) { case 0x43: /* Right */ { if (cbuf[btty.edit_p] != '\0') btty.edit_p++; break; } case 0x44: /* Left */ { if (--btty.edit_p < 0) btty.edit_p = 0; //snprintf(tbuf, btty.edit_p, "\r%s", btty.hist[btty.hist_tmp]); //v = write(btty.fd[1], tbuf, strlen(tbuf)); break; } case 0x41: /* Up */ if ((btty.hist_tmp < 50) && (btty.hist[btty.hist_tmp + 1] != NULL) && (btty.hist[btty.hist_tmp + 1][0] != '\0')) { btty.hist_tmp++; //memset(cbuf, 0, B_TTY_LINE_LEN); //memset(btty.hist[btty.hist_tmp], 0, B_TTY_LINE_LEN); snprintf(cbuf, btty.len, "%s", btty.hist[btty.hist_tmp]); snprintf(pbuf, btty.len, "%s%s", btty.prompt, cbuf); v = write(btty.fd[1], pbuf, strlen(pbuf)); } else snprintf(cbuf, btty.len, "%s", btty.hist[btty.hist_tmp]); btty.edit_p = strlen(cbuf);; break; case 0x42: /* Down */ if (btty.hist_tmp > 0) btty.hist_tmp--; snprintf(cbuf, btty.len, "%s", btty.hist[btty.hist_tmp]); snprintf(pbuf, btty.len, "\r%s%s", btty.prompt, cbuf); btty.edit_p = strlen(cbuf);; v = write(btty.fd[1], pbuf, strlen(pbuf)); break; } } else if (ch == 0x03) { /* ^C kill line btty.edit_p = 0; btty.hist_tmp = 0; btty.flags &= ~B_TTY_MMASK; btty.flags |= B_TTY_RAW_P; snprintf(pbuf, btty.len, "\r%s%s", btty.prompt, cbuf); memset(cbuf, 0, B_TTY_LINE_LEN); btty.edit_p = 0; v = write(btty.fd[1], pbuf, strlen(pbuf)); cliParamChange(global, 0.0f); return(0); */ snprintf(pbuf, btty.len, "\r%s%s\n\r", btty.prompt, cbuf); v = write(btty.fd[1], pbuf, strlen(pbuf)); memset(cbuf, 0, B_TTY_LINE_LEN); btty.edit_p = 0; snprintf(pbuf, btty.len, "\r%s%s", printprompt(global), cbuf); v = write(btty.fd[1], pbuf, strlen(pbuf)); } else if ((ch == 0x08) || (ch == 0x7f)) { int c; /* BS/DEL */ if (btty.edit_p == 0) { if (btty.flags & B_TTY_SEARCH) { btty.flags &= ~B_TTY_MMASK; btty.flags |= B_TTY_RAW; snprintf(pbuf, btty.len, "\r/"); v = write(btty.fd[1], pbuf, strlen(pbuf)); cliParamChange(global, 0.0f); return(1); } //snprintf(pbuf, btty.len, "\r:"); snprintf(pbuf, btty.len, "\r%s%s", btty.prompt, cbuf); //pbuf[1] = btty.delim; v = write(btty.fd[1], pbuf, strlen(pbuf)); return(0); } btty.edit_p--; for (c = btty.edit_p; c < strlen(cbuf); c++) cbuf[c] = cbuf[c + 1]; if (btty.flags & B_TTY_COOKED) snprintf(pbuf, btty.len, "\r%s%s", btty.prompt, cbuf); else if (btty.flags & B_TTY_SEARCH) snprintf(pbuf, btty.len, "\r/%s", cbuf); v = write(btty.fd[1], pbuf, strlen(pbuf)); if (strlen(cbuf) == btty.len) { cbuf[strlen(cbuf) - 1] = '\0'; btty.edit_p = strlen(cbuf);; } } else if ((ch == 0x0c) || (ch == 0x12)) { /* ^L ^R - redraw */ snprintf(pbuf, btty.len, "\r%s%s", btty.prompt, cbuf); pbuf[1] = btty.delim; } else if (ch == 0x09) { /* tab */ bttyComplete(global); } else if (ch == 0x01) { /* ^A start of line */ snprintf(pbuf, btty.len, "\r%s%s", btty.prompt, cbuf); btty.edit_p = 0; v = write(btty.fd[1], pbuf, strlen(pbuf)); } else if (ch == 0x05) { /* ^E end of line */ snprintf(pbuf, btty.len, "\r%s%s", btty.prompt, cbuf); btty.edit_p = strlen(cbuf); v = write(btty.fd[1], pbuf, strlen(pbuf)); } else if (ch == 0x0e) { /* Down hist ^n */ if (btty.hist_tmp > 0) btty.hist_tmp--; snprintf(cbuf, btty.len, "%s", btty.hist[btty.hist_tmp]); snprintf(pbuf, btty.len, "\r%s%s", btty.prompt, cbuf); btty.edit_p = strlen(cbuf);; v = write(btty.fd[1], pbuf, strlen(pbuf)); } else if (ch == 0x10) { /* Up hist ^p */ if ((btty.hist_tmp < 50) && (btty.hist[btty.hist_tmp + 1] != NULL) && (btty.hist[btty.hist_tmp + 1][0] != '\0')) { btty.hist_tmp++; //memset(cbuf, 0, B_TTY_LINE_LEN); //memset(btty.hist[btty.hist_tmp], 0, B_TTY_LINE_LEN); snprintf(cbuf, btty.len, "%s", btty.hist[btty.hist_tmp]); snprintf(pbuf, btty.len, "\r%s%s", btty.prompt, cbuf); v = write(btty.fd[1], pbuf, strlen(pbuf)); } else snprintf(cbuf, btty.len, "%s", btty.hist[btty.hist_tmp]); btty.edit_p = strlen(cbuf);; } else if (ch == 0x15) { /* ^U kill line */ memset(cbuf, 0, B_TTY_LINE_LEN); memset(btty.hist[0], 0, B_TTY_LINE_LEN); btty.edit_p = 0; btty.hist_tmp = 0; } else if (ch == 0x17) { int t = btty.edit_p - 1; int o = btty.edit_p; /* ^W kill word - current edit point to start of previous word */ snprintf(btty.hist[0], btty.len, "%s", cbuf); while (cbuf[t] == ' ') { if (--t == 0) break; } if (strlen(cbuf) != '\0') { while (t != 0) { if (cbuf[t] == ' ') break; t--; } if (t != 0) btty.edit_p = ++t; else btty.edit_p = 0; while ((cbuf[t++] = cbuf[o++]) != '\0') ; if (btty.flags & B_TTY_COOKED) snprintf(pbuf, btty.len, "\r%s%s", btty.prompt, cbuf); else snprintf(pbuf, btty.len, "\r/%s", cbuf); v = write(btty.fd[1], pbuf, strlen(pbuf)); } } else if (ch == 0x1b) { /* Esc - we should not actually get this */ btty.flags &= ~B_TTY_MMASK; btty.flags |= B_TTY_RAW_P; cliParamChange(global, 0.0f); return(1); } else if ((ch == 0x0a) || (ch == 0x0d)) { /* * Enter if (cbuf[0] == '\0') { snprintf(pbuf, btty.len, ":\r"); pbuf[0] = btty.delim; v = write(btty.fd[1], pbuf, strlen(pbuf)); btty.flags &= ~B_TTY_MMASK; btty.flags |= B_TTY_RAW_P; cliParamChange(global, 0.0f); return(1); } */ if (btty.flags & B_TTY_COOKED) { int i; snprintf(pbuf, btty.len, "\r%s%s\n\r", btty.prompt, cbuf); v = write(btty.fd[1], pbuf, strlen(pbuf)); if ((i = bttyInterpret(global, cbuf)) < 0) { brightonCLIcleanup(); return(i); } if (i != B_ERR_EARLY) { snprintf(pbuf, btty.len, "\r%s%s", printprompt(global), cbuf); v = write(btty.fd[1], pbuf, strlen(pbuf)); } return(i); } if (btty.flags & B_TTY_SEARCH) { if (cbuf[0] == '\0') { btty.flags &= ~B_TTY_MMASK; btty.flags |= B_TTY_RAW; snprintf(pbuf, btty.len, "\r/"); v = write(btty.fd[1], pbuf, strlen(pbuf)); cliParamChange(global, 0.0f); return(1); } snprintf(pbuf, btty.len, "/%s", cbuf); v = write(btty.fd[1], pbuf, strlen(pbuf)); return(bttySearch(global)); } } else { /* Insert char at edit point */ for (i = strlen(cbuf) + 1; i >= btty.edit_p; i--) cbuf[i] = cbuf[i - 1]; cbuf[btty.edit_p++] = ch; } if (btty.flags & B_TTY_SEARCH) { snprintf(pbuf, btty.len, "\r/%s", cbuf); v = write(btty.fd[1], pbuf, strlen(pbuf)); } else if (btty.flags & B_TTY_COOKED) { if (strlen(cbuf) >= 79) return(bttyInterpret(global, cbuf)); snprintf(pbuf, btty.len, "\r%s%s", btty.prompt, cbuf); v = write(btty.fd[1], pbuf, strlen(pbuf)); } /* Cursor positioning for command line editing */ *pbuf = 0x08; for (i = strlen(cbuf); i > btty.edit_p; i--) v = write(btty.fd[1], pbuf, 1); return(1); } int brightonCLIcheck(guimain *global) { char ch = 0, chmap = B_TTY_A_NULL; int i = 0, v = 0, r = 0, s; if (btty.flags & B_TTY_INIT) { struct termios attr; sleep(1); memset(&attr, 0, sizeof(struct termios)); tcgetattr(btty.fd[0], &resetattr); tcgetattr(btty.fd[0], &attr); cfmakeraw(&attr); tcsetattr(btty.fd[0], TCSANOW, &attr); btty.flags &= ~B_TTY_MMASK; if (SYNTHS->flags & REQ_DEBUG_1) { btty.p = RESOURCES->emulate.panel; snprintf(pbuf, btty.len, "panel: %i\r\n", btty.p); v = write(btty.fd[1], pbuf, strlen(pbuf)); } btty.flags &= ~B_TTY_INIT; btty.flags |= B_TTY_RAW; snprintf(pbuf, btty.len, "\n\rHi %s!\n\r", getenv("USER")); v = write(btty.fd[1], pbuf, strlen(pbuf)); snprintf(pbuf, btty.len, "Bristol Command Line Interface.\r\n"); v = write(btty.fd[1], pbuf, strlen(pbuf)); snprintf(pbuf, btty.len, "Cursor motion keys will access parameters.\r\n"); v = write(btty.fd[1], pbuf, strlen(pbuf)); snprintf(pbuf, btty.len, "Try ':help' and ':set cli' for information"); v = write(btty.fd[1], pbuf, strlen(pbuf)); btty.i = 0; } FD_ZERO(stdioset); FD_SET(btty.fd[0], stdioset); timeout.tv_sec = 0; if ((timeout.tv_usec = btty.acycle * 1000 - 1) < 0) timeout.tv_usec = 100000; /* * We have three modes here: * raw: default vi type control * insert mode: readline style entry * raw_p pending: seen escape but might be arrow keys, needs second state */ while ((s = select(2, stdioset, NULL, NULL, &timeout)) != 0) { r = read(btty.fd[0], &ch, 1); // pbuf[0] = ch + 96; // pbuf[1] = '\0'; // print(pbuf); printChar(ch); if (ch == 0x04) { brightonCLIcleanup(); return(-1); } switch (btty.flags & B_TTY_MMASK) { default: case B_TTY_RAW: if (ch == 0x1b) { /* Esc */ btty.flags &= ~B_TTY_MMASK; btty.flags |= B_TTY_RAW_ESC; return(1); } if (ch == 0x0c) { if ((unnamed(btty.i)) && (~btty.flags & B_TTY_AWV)) break; cliParamChange(global, 0.0f); return(0); } break; if (ch == 0x0d) { if (btty.i >= SYNTHS->win->app->resources[btty.p].ndevices) btty.i = SYNTHS->win->app->resources[btty.p].ndevices-1; if ((unnamed(btty.i)) && (~btty.flags & B_TTY_AWV)) break; cliParamChange(global, 0.0f); return(0); } break; case B_TTY_RAW_ESC: if (ch == '[') { btty.flags &= ~B_TTY_MMASK; btty.flags |= B_TTY_RAW_ESC2; return(1); } break; case B_TTY_RAW_P: /* If we get 'O' go to P2 else RAW */ btty.flags &= ~B_TTY_MMASK; if (ch == '[') { btty.flags |= B_TTY_RAW_P2; return(1); } btty.flags |= B_TTY_RAW; break; case B_TTY_RAW_P2: if ((ch == 0x41) || (ch == 0x42) || (ch == 0x43) || (ch == 0x44)) return(bttyCookedMode(global, ch)); btty.flags &= ~B_TTY_MMASK; btty.flags |= B_TTY_RAW; break; case B_TTY_COOKED: if (ch == 0x1b) { btty.flags &= ~B_TTY_MMASK; btty.flags |= B_TTY_RAW_P; return(1); } case B_TTY_SEARCH: return(bttyCookedMode(global, ch)); case B_TTY_PLAY: return(bttyPlayMode(global, ch)); } if (btty.flags & B_TTY_RAW_ESC2) { btty.flags &= ~B_TTY_MMASK; btty.flags |= B_TTY_RAW; switch (ch) { case 0x41: ch = 'k'; break; case 0x42: ch = 'j'; break; case 0x43: ch = 'l'; break; case 0x44: ch = 'h'; break; case 0x0d: case 0x0a: ch = 'l'; break; } } if (btty.flags & B_TTY_RAW_ESC2) { switch (ch) { case 0x5b: case 0x1b: btty.flags &= ~B_TTY_MMASK; btty.flags |= B_TTY_RAW_P; return(i); } } /* switch (ch) { case 0x0d: if (++btty.i >= SYNTHS->mem.active) btty.i = SYNTHS->mem.active -1; if (DEVICE(bbty.i).flags & BRIGHTON_WITHDRAWN) break; cliParamChange(global, 0.0f); return(0); }; */ for (i = 0; i < B_TTY_ACT_COUNT; i++) { if (action[i].map == '\0') break; if (action[i].map == ch) { chmap = action[i].imap; /* * We need to exec the template here, it is not predefined so * is probably an aliased command for accelerated access */ if (chmap >= B_TTY_A_PREDEF) { i = chmap; print(templates[i].opname); snprintf(cbuf, B_TTY_LINE_LEN, "%s", templates[i].opname); return(bttyInterpret(global, cbuf)); } break; } } if ((chmap == B_TTY_A_NULL) || (i == B_TTY_ACT_COUNT)) return(1); switch (chmap) { case B_TTY_A_M_TOG: { int cmem; if ((SYNTHS->flags & REQ_DEBUG_MASK) > REQ_DEBUG_2) snprintf(pbuf, btty.len, "excepted Control switch memory: %s\r\n", RESOURCES->name); v = write(btty.fd[1], pbuf, strlen(pbuf)); cmem = SYNTHS->cmem; if (SYNTHS->loadMemory != NULL) SYNTHS->loadMemory(SYNTHS, RESOURCES->name, 0, SYNTHS->lmem, SYNTHS->mem.active, 0, btty.fl); else loadMemory(SYNTHS, RESOURCES->name, 0, SYNTHS->lmem, SYNTHS->mem.active, 0, btty.fl); SYNTHS->lmem = cmem; break; } case B_TTY_A_M_WRITE: /* Save */ SYNTHS->cmem = SYNTHS->lmem; if (SYNTHS->saveMemory != NULL) SYNTHS->saveMemory(SYNTHS, RESOURCES->name, 0, SYNTHS->location, 0); else saveMemory(SYNTHS, RESOURCES->name, 0, SYNTHS->location, 0); snprintf(pbuf, btty.len, "\r\nwrite: %i", SYNTHS->location); v = write(btty.fd[1], pbuf, strlen(pbuf)); break; case B_TTY_A_M_READ: /* Open */ SYNTHS->lmem = SYNTHS->cmem; if (SYNTHS->loadMemory != NULL) SYNTHS->loadMemory(SYNTHS, RESOURCES->name, 0, SYNTHS->location, SYNTHS->mem.active, 0, btty.fl); else loadMemory(SYNTHS, RESOURCES->name, 0, SYNTHS->location, SYNTHS->mem.active, 0, btty.fl); SYNTHS->cmem = SYNTHS->location; snprintf(pbuf, btty.len, "read: %i\r\n", SYNTHS->location); v = write(btty.fd[1], pbuf, strlen(pbuf)); break; case B_TTY_A_M_DOWN: /* Mem down */ if (--SYNTHS->location < 0) SYNTHS->location = 99; if (loadMemory(SYNTHS, RESOURCES->name, 0, SYNTHS->location, SYNTHS->mem.active, 0, BRISTOL_STAT) < 0) snprintf(pbuf, btty.len, "free mem: %i\r\n", SYNTHS->location); else snprintf(pbuf, btty.len, "mem: %i\r\n", SYNTHS->location); v = write(btty.fd[1], pbuf, strlen(pbuf)); break; case B_TTY_A_M_UP: /* Mem up */ if (++SYNTHS->location > 99) SYNTHS->location = 0; if (loadMemory(SYNTHS, RESOURCES->name, 0, SYNTHS->location, SYNTHS->mem.active, 0, BRISTOL_STAT) < 0) snprintf(pbuf, btty.len, "free mem: %i\r\n", SYNTHS->location); else snprintf(pbuf, btty.len, "mem: %i\r\n", SYNTHS->location); v = write(btty.fd[1], pbuf, strlen(pbuf)); break; case B_TTY_A_LEFT: if (--btty.i < 0) { btty.i = 0; break; } if ((paramname(btty.i)[0] == '\0') && (~btty.flags & B_TTY_AWV)) { while (paramname(btty.i)[0] == '\0') { btty.i--; if (btty.i < 0) { btty.i = 0; return(1); } } } cliParamChange(global, 0.0f); break; case B_TTY_A_RIGHT: btty.i++; if (btty.i >= SYNTHS->win->app->resources[btty.p].ndevices) { btty.i = SYNTHS->win->app->resources[btty.p].ndevices - 1; break; } //if ((DEVICE(btty.i).flags & BRIGHTON_WITHDRAWN) if ((unnamed(btty.i)) && (~btty.flags & B_TTY_AWV)) { int h = btty.i - 1; //while (DEVICE(btty.i).flags & BRIGHTON_WITHDRAWN) while (paramname(btty.i)[0] == '\0') { if (++btty.i >= SYNTHS->win->app->resources[btty.p].ndevices) { if ((btty.i = h) < 0) btty.i = 0; return(1); } } } cliParamChange(global, 0.0f); break; case B_TTY_A_UPDATE: /* refresh */ cliParamChange(global, 0.0f); break; case B_TTY_A_DECMAX: /* Param down */ cliParamChange(global, -0.1f); break; case B_TTY_A_DEC: /* Param down */ cliParamChange(global, -btty.accel); break; /* * Param down */ case B_TTY_A_DEC1: cliParamChange(global, -1.0f/16383); break; case B_TTY_A_DEC4: cliParamChange(global, -4.0f/16383); break; case B_TTY_A_DECMIN: cliParamChange(global, -0.001f); break; case B_TTY_A_INCMAX: /* Param up */ cliParamChange(global, 0.1f); break; case B_TTY_A_INC: /* Param up */ cliParamChange(global, btty.accel); break; /* * Param up */ case B_TTY_A_INCMIN: cliParamChange(global, 0.001f); break; case B_TTY_A_INC1: cliParamChange(global, 1.0f/16383.001f); break; case B_TTY_A_INC4: cliParamChange(global, 4.0f/16383.001f); break; case B_TTY_A_INSERT: seqStop(global); btty.flags &= ~(B_TTY_MMASK|B_TTY_SEQ); btty.flags |= B_TTY_COOKED; btty.edit_p = 0; memset(cbuf, 0, B_TTY_LINE_LEN); snprintf(pbuf, btty.len, "\n\r%s", printprompt(global)); btty.delim = ':'; v = write(btty.fd[1], pbuf, strlen(pbuf)); break; case B_TTY_A_FIND: btty.flags &= ~B_TTY_MMASK; btty.flags |= B_TTY_SEARCH; btty.edit_p = 0; memset(cbuf, 0, B_TTY_LINE_LEN); snprintf(pbuf, btty.len, "\n\r/"); btty.delim = '/'; v = write(btty.fd[1], pbuf, strlen(pbuf)); break; default: case B_TTY_A_NULL: snprintf(pbuf, btty.len, "unimplemented char 0x%x\r\n", ch); if (SYNTHS->flags & REQ_DEBUG_1) v = write(btty.fd[1], pbuf, strlen(pbuf)); break; } lp = PDEV(btty.i)->value; } /* if the GUI has changed the value we show here, CLI to match */ if ((btty.flags & B_TTY_PLAY) && (btty.flags & B_TTY_PLAY_LINE)) { if (btty.flags & B_TTY_CLEAR_KEY) { brightonKeyInput(SYNTHS->win, btty.key, 0); btty.key = 255; } btty.flags |= B_TTY_CLEAR_KEY; } if (btty.flags & B_TTY_SEQ) { if (sequences[btty.sequence.id].count > 0) { if ((btty.sequence.count -= btty.acycle) <= 0) { /* Send note off/on */ print("note off"); if (btty.sequence.step < 0) btty.sequence.step = sequences[btty.sequence.id].count; else if (sequences[btty.sequence.id].step[btty.sequence.step] > 0) bristolMidiSendMsg(global->controlfd, SYNTHS->midichannel, BRISTOL_EVENT_KEYOFF, 0, sequences[btty.sequence.id].step[btty.sequence.step] + btty.sequence.transpose); if (++btty.sequence.step >= sequences[btty.sequence.id].count) btty.sequence.step = 0; print("note on"); if (sequences[btty.sequence.id].step[btty.sequence.step] > 0) bristolMidiSendMsg(global->controlfd, SYNTHS->midichannel, BRISTOL_EVENT_KEYON, 0, sequences[btty.sequence.id].step[btty.sequence.step] + btty.sequence.transpose); btty.sequence.count = 250 * 60 / sequences[btty.sequence.id].rate; snprintf(pbuf, btty.len, "rate %i, count %i(%i), step %i\n\r", sequences[0].rate, btty.sequence.count, btty.acycle, btty.sequence.step); v = write(btty.fd[1], pbuf, strlen(pbuf)); } } else { btty.flags &= ~B_TTY_SEQ; seqStop(global); } } if ((btty.flags & B_TTY_RAW) && (s == 0) && (r == 0) && (lp != PDEV(btty.i)->value)) { lp = PDEV(btty.i)->value; cliParamChange(global, 0.0f); } if ((r == 0) && (btty.flags & B_TTY_RAW_P)) { btty.flags &= ~B_TTY_MMASK; btty.flags |= B_TTY_RAW; cliParamChange(global, 0.0f); } return(r); } bristol-0.60.11/brighton/brightonRhodes.c0000644000175000017500000004365611746476475015262 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include #include "brighton.h" #include "brightonMini.h" #include "brightoninternals.h" static int rhodesInit(); static int rhodesConfigure(); static int rhodesCallback(brightonWindow *, int, int, float); static int rhodesMidiCallback(brightonWindow *, int, int, float); extern guimain global; #include "brightonKeys.h" #define OPTS_PANEL 0 #define MOD_PANEL 1 #define MEM_PANEL 2 #define KEY_PANEL 3 #define FIRST_DEV 0 #define MOD_COUNT 4 #define OPTS_COUNT 12 #define MEM_COUNT 17 #define OPTS_START 0 #define MOD_START OPTS_COUNT #define MEM_START (MOD_COUNT + MOD_START) #define ACTIVE_DEVS (OPTS_COUNT + MOD_COUNT - 1) #define DEVICE_COUNT (MOD_COUNT + OPTS_COUNT + MEM_COUNT) #define DISPLAY_DEV (MEM_COUNT - 1) #define MEM_MGT ACTIVE_DEVS #define MIDI_MGT (MEM_MGT + 12) extern int memCallback(brightonWindow * , int, int, float); extern brightonLocations mem[]; /* * This structure is for device definition. The structure is defined in * include/brighton.h, further definitions in brighton/brightonDevtable.h and * include/brightoninternals.h * * typedef int (*brightonCallback)(int, float); * typedef struct BrightonLocations { * int device; 0=rotary, 1=scale, etc. * float relx, rely; relative position with regards to 1000 by 1000 window * float relw, relh; relative height. * int from, to; * brightonCallback callback; specific to this dev * char *image; bitmap. If zero take a device default. * int flags; * } brightonLocations; * * This example is for a rhodesBristol type synth interface. */ #define R1 0 #define W1 100 #define L1 600 #define C1 40 #define C2 190 #define C3 340 #define C4 490 #define C5 700 #define C6 850 static brightonLocations locations[MOD_COUNT] = { {"Bass", 0, 90, 100, 300, 600, 0, 1, 0, 0, 0, 0}, {"Volume", 0, 123, 100, 300, 600, 0, 1, 0, 0, 0, 0}, {"", 2, 50, 200, 30, 400, 0, 1, 0, "bitmaps/buttons/rockerwhite.xpm", 0, 0}, {"Chorus", 0, 156, 100, 300, 600, 0, 1, 0, 0, 0, 0}, }; #define S1 200 /* Options should only be a few piano selectors, no programmers. */ static brightonLocations options[OPTS_COUNT] = { {"", 2, 100, 500, 50, 200, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 200, 500, 50, 200, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 300, 500, 50, 200, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 400, 500, 50, 200, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 500, 500, 50, 200, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 600, 500, 50, 200, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 700, 500, 50, 200, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 800, 500, 50, 200, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 0, 100, 200, 60, 300, 0, 1, 0, "bitmaps/knobs/knobrednew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, 200, 200, 60, 300, 0, 1, 0, "bitmaps/knobs/knobyellownew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, 300, 200, 60, 300, 0, 1, 0, "bitmaps/knobs/knobgreennew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, 400, 200, 60, 300, 0, 1, 0, "bitmaps/knobs/knobbluenew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, }; /* * This is a set of globals for the main window rendering. Again taken from * include/brighton.h */ brightonApp rhodesApp = { "rhodes", 0, /* no blueprint on wood background. */ "bitmaps/textures/leather.xpm", 0, rhodesInit, rhodesConfigure, /* 3 callbacks */ rhodesMidiCallback, 0, {16, 0, 2, 2, 5, 520, 0, 1}, 750, 250, 0, 0, 7, /* panel count */ { { "Opts", "bitmaps/blueprints/rhodesopts.xpm", "bitmaps/textures/metal5.xpm", /* flags */ 0x020, 0, 0, rhodesCallback, 19, 40, 600, 510, OPTS_COUNT, options }, { "Mods", "bitmaps/blueprints/rhodes.xpm", "bitmaps/images/rhodesplate.xpm", BRIGHTON_STRETCH, 0, 0, rhodesCallback, 12, 559, 976, 100, MOD_COUNT, locations }, { "Mem", "bitmaps/blueprints/genmem.xpm", "bitmaps/textures/metal5.xpm", /* flags */ 0x020, 0, 0, memCallback, 619, 40, 362, 510, MEM_COUNT, mem }, { "Keyboard", 0, "bitmaps/newkeys/dkbg.xpm", /* flags */ 0x020|BRIGHTON_STRETCH, 0, 0, keyCallback, 52, 662, 900, 305, KEY_COUNT_6_OCTAVE, keys6octave }, { "Rhodes", 0, "bitmaps/images/rhodes.xpm", BRIGHTON_STRETCH, /* flags */ 0, 0, 0, 12, 30, 976, 530, 0, 0 }, { "backing", 0, "bitmaps/textures/metal6.xpm", /* flags */ BRIGHTON_STRETCH, 0, 0, 0, 953, 662, 35, 310, 0, 0 }, { "backing", 0, "bitmaps/textures/metal6.xpm", /* flags */ BRIGHTON_STRETCH, 0, 0, 0, 12, 662, 40, 310, 0, 0 }, } }; /*static dispatcher dispatch[DEVICE_COUNT]; */ static int rhodesMidiSendMsg(void *synth, int fd, int chan, int c, int o, int v) { /*printf("rhodesMidiSendMsg(%i, %i, %i)\n", c, o, v); */ bristolMidiSendMsg(fd, chan, c, o, v); return(0); } /* * For the sake of ease of use, links have been placed here to be called * by any of the devices created. They would be better in some other file, * perhaps with this as a dispatch. * * Param refers to the device index in the locations table given below. */ static int rhodesCallback(brightonWindow * win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); int sendvalue; /* printf("rhodesCallback(%i, %i, %f): %x\n", panel, index, value, synth); */ if (synth == 0) return(0); if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0)) return(0); if (rhodesApp.resources[panel].devlocn[index].to == 1) sendvalue = value * C_RANGE_MIN_1; else sendvalue = value; switch (panel) { case OPTS_PANEL: index += OPTS_START; break; case MOD_PANEL: index += MOD_START; break; case MEM_PANEL: index += MEM_START; break; } synth->mem.param[index] = value; if ((!global.libtest) || (index >= ACTIVE_DEVS)) synth->dispatch[index].routine(synth, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #ifdef DEBUG else printf("dispatch[%p,%i](%i, %i, %i, %i, %i)\n", synth, index, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #endif return(0); } static void rhodesProgramme(guiSynth *synth, int fd, int chan, int cont, int op, int value) { brightonEvent event; if (synth->dispatch[OPTS_START].other2) { synth->dispatch[OPTS_START].other2 = 0; synth->mem.param[synth->dispatch[OPTS_START].other1] = 0; return; } if ((synth->flags & MEM_LOADING) == 0) { if (synth->dispatch[OPTS_START].other1 != -1) { synth->dispatch[OPTS_START].other2 = 1; if (synth->dispatch[OPTS_START].other1 != op) event.value = 0; else event.value = 1; brightonParamChange(synth->win, OPTS_PANEL, synth->dispatch[OPTS_START].other1, &event); } synth->dispatch[OPTS_START].other1 = op; synth->mem.param[op] = 1; } else return; if (synth->flags & SUPPRESS) return; if (value != 0) { float *memhold; float mem[256]; int optr, ind; /* printf("rhodesProgramme(%x, %i, %i, %i, %i, %i)\n", */ /* synth, fd, chan, cont, op, value); */ /* * Each of the 8 voices has an associated set of DX parameters. We * need to get hold of these, and send them directly over our config * interface tap - we cannot forward via the normal GUi interface since * we do not have these parameters mapped. * * The memories are mapped as 6 operators, each with 20 parameters, * of which 13 are active, and then we have 4 additional parameters for * algo, pitch, glide and volume. */ memhold = &synth->mem.param[0]; synth->mem.param = &mem[0]; ind = 1000 + op; /* * Load the memory parameters with no callbacks. We have to force the * loading since we are using 'rhodes' as our type, but the memories * are actually typed as DX. */ if (loadMemory(synth, "rhodes", 0, ind, 148, 0, BRISTOL_NOCALLS|BRISTOL_FORCE) < 0) { printf("Memory not found, returning\n"); synth->mem.param = memhold; synth->dispatch[OPTS_START].other1 = op; return; } for (optr = 0; optr < 6; optr++) { rhodesMidiSendMsg(synth, global.controlfd, synth->sid, 126, optr * 10, mem[optr * 20] * C_RANGE_MIN_1); rhodesMidiSendMsg(synth, global.controlfd, synth->sid, optr, 1, mem[optr * 20 + 1] * C_RANGE_MIN_1); rhodesMidiSendMsg(synth, global.controlfd, synth->sid, optr, 0, mem[optr * 20 + 2]); rhodesMidiSendMsg(synth, global.controlfd, synth->sid, optr, 6, mem[optr * 20 + 3] * C_RANGE_MIN_1); rhodesMidiSendMsg(synth, global.controlfd, synth->sid, 126, optr * 10 + 1, mem[optr * 20 + 4] * C_RANGE_MIN_1); rhodesMidiSendMsg(synth, global.controlfd, synth->sid, optr, 2, mem[optr * 20 + 5] * C_RANGE_MIN_1); rhodesMidiSendMsg(synth, global.controlfd, synth->sid, optr, 3, mem[optr * 20 + 6] * C_RANGE_MIN_1); rhodesMidiSendMsg(synth, global.controlfd, synth->sid, optr, 4, mem[optr * 20 + 7] * C_RANGE_MIN_1); rhodesMidiSendMsg(synth, global.controlfd, synth->sid, optr, 5, mem[optr * 20 + 8] * C_RANGE_MIN_1); rhodesMidiSendMsg(synth, global.controlfd, synth->sid, optr, 7, mem[optr * 20 + 9] * C_RANGE_MIN_1); rhodesMidiSendMsg(synth, global.controlfd, synth->sid, 126, optr * 10 + 2, mem[optr * 20 + 10] * C_RANGE_MIN_1); rhodesMidiSendMsg(synth, global.controlfd, synth->sid, 126, optr * 10 + 3, mem[optr * 20 + 11] * C_RANGE_MIN_1); rhodesMidiSendMsg(synth, global.controlfd, synth->sid, optr, 9, mem[optr * 20 + 12] * C_RANGE_MIN_1); rhodesMidiSendMsg(synth, global.controlfd, synth->sid, optr, 10, mem[optr * 20 + 13] * C_RANGE_MIN_1); rhodesMidiSendMsg(synth, global.controlfd, synth->sid, optr, 11, mem[optr * 20 + 14] * C_RANGE_MIN_1); rhodesMidiSendMsg(synth, global.controlfd, synth->sid, optr, 12, mem[optr * 20 + 15] * C_RANGE_MIN_1); } /* * These go through all the algorithms, looking for a single nonzero */ for (ind = 0; ind < 24; ind++) { if (mem[120 + ind] != 0) { bristolMidiSendMsg(global.controlfd, synth->sid, 126, 101, ind); break; } } rhodesMidiSendMsg(synth, global.controlfd, synth->sid, 126, 99, 0); rhodesMidiSendMsg(synth, global.controlfd, synth->sid, 126, 100, 0); rhodesMidiSendMsg(synth, global.controlfd, synth->sid, 126, 102, C_RANGE_MIN_1); synth->mem.param = memhold; synth->dispatch[OPTS_START].other1 = op; } } static int rhodesMidiCallback(brightonWindow *win, int command, int value, float v) { guiSynth *synth = findSynth(global.synths, win); printf("midi callback: %x, %i\n", command, value); switch(command) { case MIDI_PROGRAM: printf("midi program: %x, %i\n", command, value); synth->location = value; rhodesProgramme(synth, global.controlfd, synth->sid, synth->dispatch[OPTS_START].controller, synth->dispatch[OPTS_START].operator, 1.0f); break; case MIDI_BANK_SELECT: printf("midi banksel: %x, %i\n", command, value); synth->bank = value; break; } return(0); } static void rhodesPanelSwitch(guiSynth *id, int fd, int chan, int cont, int op, int value) { brightonEvent event; id->flags |= SUPPRESS; /*printf("rhodesPanelSwitch()\n"); */ /* * If the sendvalue is zero, then withdraw the opts window, draw the * slider window, and vice versa. */ if (value == 0) { event.type = BRIGHTON_EXPOSE; event.intvalue = 0; brightonParamChange(id->win, 0, -1, &event); event.intvalue = 0; brightonParamChange(id->win, 2, -1, &event); event.intvalue = 1; brightonParamChange(id->win, 4, -1, &event); } else { event.type = BRIGHTON_EXPOSE; event.intvalue = 0; brightonParamChange(id->win, 4, -1, &event); event.intvalue = 1; brightonParamChange(id->win, 0, -1, &event); event.intvalue = 1; brightonParamChange(id->win, 2, -1, &event); } id->flags &= ~SUPPRESS; } static void rhodesVolume(guiSynth *id, int fd, int chan, int cont, int op, int value) { /*printf("rhodesVolume(%i)\n", value); */ bristolMidiSendMsg(global.controlfd, chan, 126, 102, value); } static void rhodesBoost(guiSynth *synth, int fd, int chan, int cont, int op, int value) { /*printf("rhodesBoost(%i)\n", value); */ bristolMidiControl(global.controlfd, synth->sid, 0, 1, value >> 7); } static void rhodesChorus(guiSynth *synth, int fd, int chan, int cont, int op, int value) { /*printf("Rhodes chorus: %i\n", value); */ bristolMidiSendMsg(global.controlfd, synth->sid, 123, 0, value); bristolMidiSendMsg(global.controlfd, synth->sid, 123, 3, value); } /* * Any location initialisation required to run the callbacks. For bristol, this * will connect to the engine, and give it some base parameters. * May need to generate some application specific menus. * Will also then make specific requests to some of the devices to alter their * rendering. */ static int rhodesInit(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); dispatcher *dispatch; int i; if (synth == 0) { synth = findSynth(global.synths, 0); if (synth == 0) { printf("cannot init\n"); return(0); } } synth->win = win; printf("Initialise the rhodes link to bristol: %p\n", synth->win); synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float)); synth->mem.count = DEVICE_COUNT; synth->mem.active = ACTIVE_DEVS; synth->dispatch = (dispatcher *) brightonmalloc(DEVICE_COUNT * sizeof(dispatcher)); dispatch = synth->dispatch; /* * The rhodes is actually a DX algorithm but it may eventually use a * wrapper in the engine such that the FM coding is fed into a chorus. synth->synthtype = BRISTOL_DX; */ /* * We really want to have three connection mechanisms. These should be * 1. Unix named sockets. * 2. UDP sockets. * 3. MIDI pipe. */ if (!global.libtest) if ((synth->sid = initConnection(&global, synth)) < 0) return(-1); for (i = 0; i < DEVICE_COUNT; i++) synth->dispatch[i].routine = rhodesMidiSendMsg; synth->dispatch[MOD_START + 0].routine = (synthRoutine) rhodesBoost; synth->dispatch[MOD_START + 1].routine = (synthRoutine) rhodesVolume; synth->dispatch[MOD_START + 2].routine = (synthRoutine) rhodesPanelSwitch; synth->dispatch[MOD_START + 3].controller = 123; synth->dispatch[MOD_START + 3].operator = 0; synth->dispatch[MOD_START + 3].routine = (synthRoutine) rhodesChorus; synth->dispatch[OPTS_START + 0].routine = synth->dispatch[OPTS_START + 1].routine = synth->dispatch[OPTS_START + 2].routine = synth->dispatch[OPTS_START + 3].routine = synth->dispatch[OPTS_START + 4].routine = synth->dispatch[OPTS_START + 5].routine = synth->dispatch[OPTS_START + 6].routine = synth->dispatch[OPTS_START + 7].routine = (synthRoutine) rhodesProgramme; synth->dispatch[OPTS_START + 0].operator = 0; synth->dispatch[OPTS_START + 1].operator = 1; synth->dispatch[OPTS_START + 2].operator = 2; synth->dispatch[OPTS_START + 3].operator = 3; synth->dispatch[OPTS_START + 4].operator = 4; synth->dispatch[OPTS_START + 5].operator = 5; synth->dispatch[OPTS_START + 6].operator = 6; synth->dispatch[OPTS_START + 7].operator = 7; synth->dispatch[OPTS_START + 8].controller = synth->dispatch[OPTS_START + 9].controller = synth->dispatch[OPTS_START + 10].controller = synth->dispatch[OPTS_START + 11].controller = 123; synth->dispatch[OPTS_START + 8].operator = 0; synth->dispatch[OPTS_START + 9].operator = 1; synth->dispatch[OPTS_START + 10].operator = 2; synth->dispatch[OPTS_START + 11].operator = 3; return(0); } /* * This will be called to make any routine specific parameters available. */ static int rhodesConfigure(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); brightonEvent event; if (synth == 0) { printf("problems going operational\n"); return(-1); } if (synth->flags & OPERATIONAL) return(0); printf("going operational\n"); synth->flags |= OPERATIONAL; synth->keypanel = 3; synth->keypanel2 = -1; synth->transpose = 36; /* loadMemory(synth, "rhodes", 0, synth->location, synth->mem.active, */ /* FIRST_DEV, BRISTOL_NOCALLS|BRISTOL_FORCE); */ rhodesProgramme(synth, global.controlfd, synth->sid, synth->dispatch[OPTS_START].controller, synth->dispatch[OPTS_START].operator, 1.0f); displayPanelText(synth, "PRG", synth->location, MEM_PANEL, MEM_COUNT - 1); /* * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only * occurs on first paint, so we suppress the first paint, and then request * an expose here. */ event.type = BRIGHTON_EXPOSE; event.intvalue = 1; brightonParamChange(synth->win, KEY_PANEL, -1, &event); event.type = BRIGHTON_FLOAT; event.value = 1; brightonParamChange(synth->win, 0, 0, &event); configureGlobals(synth); event.type = BRIGHTON_FLOAT; event.value = 0.1; brightonParamChange(synth->win, OPTS_PANEL, 8, &event); brightonParamChange(synth->win, OPTS_PANEL, 9, &event); brightonParamChange(synth->win, OPTS_PANEL, 10, &event); event.value = 0.5; brightonParamChange(synth->win, OPTS_PANEL, 11, &event); brightonPut(synth->win, "bitmaps/blueprints/rhodesshade.xpm", 0, 0, synth->win->width, synth->win->height); return(0); } bristol-0.60.11/brighton/brightonDX.c0000644000175000017500000011342311746476475014337 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include #include "brighton.h" #include "brightonMini.h" #include "brightoninternals.h" static int dxInit(); static int dxConfigure(); static int dxCallback(brightonWindow * , int, int, float); static int dxMidiCallback(brightonWindow * , int, int, float); extern guimain global; #include "brightonKeys.h" #define DX7 #ifdef DX7 #define BLUEPRINT "bitmaps/blueprints/dx7.xpm" #else #define BLUEPRINT "bitmaps/blueprints/dx.xpm" #endif #define OP_COUNT 6 #define FIRST_DEV 0 #define PARAM_COUNT 20 #define ALGOS_COUNT 29 #define MEM_COUNT 17 #define ACTIVE_DEVS (PARAM_COUNT * OP_COUNT + ALGOS_COUNT + FIRST_DEV) #define DISPLAY_DEV (MEM_COUNT - 3) #define DISPLAY_PANEL 7 #define OP_START FIRST_DEV #define OP1_START FIRST_DEV #define OP2_START (OP1_START + PARAM_COUNT) #define OP3_START (OP2_START + PARAM_COUNT) #define OP4_START (OP3_START + PARAM_COUNT) #define OP5_START (OP4_START + PARAM_COUNT) #define OP6_START (OP5_START + PARAM_COUNT) #define ALGO_START (PARAM_COUNT * OP_COUNT + FIRST_DEV) #define MEM_START ACTIVE_DEVS #define OP_PANEL 0 #define ALGOS_PANEL OP_COUNT #define MEM_PANEL (ALGOS_PANEL + 1) #define KEY_PANEL 8 #define DEVICE_COUNT (ACTIVE_DEVS + MEM_COUNT) /* * This structure is for device definition. The structure is defined in * include/brighton.h, further definitions in brighton/brightonDevtable.h and * include/brightoninternals.h * * typedef int (*brightonCallback)(int, float); * typedef struct BrightonLocations { * int device; 0=rotary, 1=scale, etc. * float relx, rely; relative position with regards to 1000 by 1000 window * float relw, relh; relative height. * int from, to; * brightonCallback callback; specific to this dev * char *image; bitmap. If zero take a device default. * int flags; * } brightonLocations; * * This example is for a dxBristol type synth interface. */ #define OP1XPM "bitmaps/images/op1.xpm" #define OP2XPM "bitmaps/images/op2.xpm" #define OP3XPM "bitmaps/images/op3.xpm" #define OP4XPM "bitmaps/images/op4.xpm" #define OP5XPM "bitmaps/images/op5.xpm" #define OP6XPM "bitmaps/images/op6.xpm" #define R1 150 #define R2 665 #define D3 90 #ifdef DX7 #define D1 123 #define C0 35 #define C1 (C0 + D1) #define C2 (C1 + D1) #define C3 (C2 + D1) #define C4 (C3 + D1) #define C5 (C4 + D1) #define C6 (C5 + D1) #define C7 (C6 + D1) #else #define D1 139 #define C0 35 #define C1 (C0 + D1) #define C2 (C1 + D1) #define C3 (C2 + D1) #define C4 (C3 + D1) #define C5 (C4 + D1) #define C6 (C5 + D1) #endif #define S1 300 #define S2 40 #define S3 250 /* * This needs to be changed for a 7 parameter envelope, A-L1-A-L2-D-S-R. * Rework is non trivial, need to rework the env, which is ok, the GUI, also * easy, but it requires extra operator parameters. */ #ifdef DX7 static brightonLocations locations[PARAM_COUNT] = { /* in gain */ {"", 0, C1, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knobrednew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, /* tune */ {"", 0, C3, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knobgreynew.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_NOTCH}, /* transpose */ {"", 0, C4, R2, S1, S1, 0, 5, 0, "bitmaps/knobs/knobgreynew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, /* out gain */ {"", 0, C2, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knobrednew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, /* lfo */ {"", 2, C5, R2, S2, S3, 0, 1.01, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, /* attack */ {"", 0, C1, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knobbluenew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, C5, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knobbluenew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, C6, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knobbluenew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, C7, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knobbluenew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, /* touch */ {"", 0, C0, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knobgreennew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, /* pan */ {"", 0, C7, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knobyellownew.xpm", "bitmaps/knobs/alpharotary.xpm", BRIGHTON_NOTCH}, /* igc, ogc */ {"", 2, C5 + D3, R2, S2, S3, 0, 1.01, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, C5 + D3 + D3, R2, S2, S3, 0, 1.01, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* L1-A-L2 */ {"", 0, C2, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knobbluenew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, C3, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knobbluenew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, C4, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knobbluenew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, /* spares */ {"", -1, C6, R1, S1, S1, 0, 1, 0, 0, 0, 0}, {"", -1, C6, R1, S1, S1, 0, 1, 0, 0, 0, 0}, {"", -1, C6, R1, S1, S1, 0, 1, 0, 0, 0, 0}, {"", 4, 0, 200, 140, 250, 0, 1, 0, OP1XPM, 0, 0} }; #else static brightonLocations locations[PARAM_COUNT] = { /* in gain */ {"", 0, C0, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knobred.xpm", 0, 0}, /* tune */ {"", 0, C2, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knoborange.xpm", 0, 0}, /* transpose */ {"", 0, C3, R1, S1, S1, 0, 5, 0, "bitmaps/knobs/knoborange.xpm", 0, 0}, /* out gain */ {"", 0, C6, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knobred.xpm", 0, 0}, /* lfo */ {"", 2, C4, R1, S2, S3, 0, 1.01, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0}, /* attack */ {"", 0, C2, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", 0, 0}, {"", 0, C3, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", 0, 0}, {"", 0, C4, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", 0, 0}, {"", 0, C5, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", 0, 0}, /* touch */ {"", 0, C1, R2, S1, S1, 0, 1, 0, 0, 0, 0}, /* pan */ {"", 0, C6, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knobyellow.xpm", 0, 0}, /* igc, ogc */ {"", 2, C4 + D3, R1, S2, S3, 0, 1.01, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, C4 + D3 + D3, R1, S2, S3, 0, 1.01, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, /* spares */ {"", -1, C6, R1, S1, S1, 0, 1, 0, 0, 0, 0}, {"", -1, C6, R1, S1, S1, 0, 1, 0, 0, 0, 0}, {"", -1, C6, R1, S1, S1, 0, 1, 0, 0, 0, 0}, {"", -1, C6, R1, S1, S1, 0, 1, 0, 0, 0, 0}, {"", -1, C6, R1, S1, S1, 0, 1, 0, 0, 0, 0}, {"", -1, C6, R1, S1, S1, 0, 1, 0, 0, 0, 0}, {"", 4, 60, 100, 150, 300, 0, 1, 0, OP1XPM, 0, 0} }; #endif #define D2 50 #define S4 45 #define S5 250 #define AR1 150 #define AR2 425 #define AR3 700 #define AC0 50 #define AC1 (AC0 + D2) #define AC2 (AC1 + D2) #define AC3 (AC2 + D2) #define AC4 (AC3 + D2) #define AC5 (AC4 + D2) #define AC6 (AC5 + D2) #define AC7 (AC6 + D2) #define AC8 (AC7 + D2 + 253) #define AC9 (AC8 + D2 + 142) #define AC10 (AC9 + D2 + 10) static brightonLocations algopanel[ALGOS_COUNT] = { {"", 2, AC0, AR1, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, AC1, AR1, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, AC2, AR1, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, AC3, AR1, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, AC4, AR1, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, AC5, AR1, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, AC6, AR1, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, AC7, AR1, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, AC0, AR2, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, AC1, AR2, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, AC2, AR2, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, AC3, AR2, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, AC4, AR2, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, AC5, AR2, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, AC6, AR2, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, AC7, AR2, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, AC0, AR3, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, AC1, AR3, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, AC2, AR3, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, AC3, AR3, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, AC4, AR3, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, AC5, AR3, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, AC6, AR3, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, AC7, AR3, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 0, AC8, R1, S1 + 10, S1 + 10, 0, 1, 0, "bitmaps/knobs/knobgreynew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 0, AC8, R2, S1 + 10, S1 + 10, 0, 1, 0, "bitmaps/knobs/knobgreynew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, /* Volume */ {"", 0, AC9 - 20, R2, S1 + 10, S1 + 10, 0, 1, 0, "bitmaps/knobs/knobgreynew.xpm", "bitmaps/knobs/alpharotary.xpm", 0}, {"", 2, AC9, R1 + 40, S4, S5, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 4, AC7 + 90, AR1, 190, 800, 0, 1, 0, 0, 0, 0}, }; #define MS1 75 #define MS2 200 #define MD1 210 #define MD2 80 #define MR0 100 #define MR1 (MR0 + MD1) #define MR2 (MR1 + MD1) #define MR3 (MR2 + MD1) #define MC0 500 #define MC1 (MC0 + MD2) #define MC2 (MC1 + MD2) static brightonLocations mempanel[MEM_COUNT] = { /* Memory buttons from 0 */ {"", 2, MC1, MR3, MS1, MS2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlw.xpm", BRIGHTON_CHECKBUTTON}, /* from 1 */ {"", 2, MC0, MR0, MS1, MS2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlw.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, MC1, MR0, MS1, MS2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlw.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, MC2, MR0, MS1, MS2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlw.xpm", BRIGHTON_CHECKBUTTON}, /* from 4 */ {"", 2, MC0, MR1, MS1, MS2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlw.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, MC1, MR1, MS1, MS2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlw.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, MC2, MR1, MS1, MS2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlw.xpm", BRIGHTON_CHECKBUTTON}, /* from 7 */ {"", 2, MC0, MR2, MS1, MS2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlw.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, MC1, MR2, MS1, MS2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlw.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, MC2, MR2, MS1, MS2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm", "bitmaps/buttons/touchnlw.xpm", BRIGHTON_CHECKBUTTON}, /* load save */ {"", 2, 290, MR3, 45, MS2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 410, MR3, 45, MS2, 0, 1, 0, "bitmaps/buttons/pressoffo.xpm", "bitmaps/buttons/pressono.xpm", BRIGHTON_CHECKBUTTON}, /* midi up/down */ {"", 2, 60, MR3, 45, MS2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, 175, MR3, 45, MS2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON}, {"", 3, 15, 100, 485, 310, 0, 1, 0, 0, "bitmaps/images/alphadisplay3.xpm", 0}, /* up/down */ {"", 2, MC0, MR3, MS1, MS2, 0, 1, 0, "bitmaps/buttons/touchnl.xpm", "bitmaps/buttons/touchnl.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, MC2, MR3, MS1, MS2, 0, 1, 0, "bitmaps/buttons/touchnl.xpm", "bitmaps/buttons/touchnl.xpm", BRIGHTON_CHECKBUTTON}, }; /* * This is a set of globals for the main window rendering. Again taken from * include/brighton.h */ brightonApp dxApp = { "dx", 0, /* no blueprint on wood background. */ "bitmaps/textures/metal6.xpm", BRIGHTON_STRETCH, dxInit, dxConfigure, /* 3 callbacks, unused? */ dxMidiCallback, destroySynth, {8, 0, 2, 2, 5, 520, 0, 0}, 820, 300, 0, 0, 15, /* one panel only */ { { "DX", BLUEPRINT, "bitmaps/textures/metal5.xpm", 0, /* flags */ 0, 0, dxCallback, 20, 15, 310, 230, PARAM_COUNT, locations }, { "DX", BLUEPRINT, "bitmaps/textures/metal5.xpm", 0, /* flags */ 0, 0, dxCallback, 345, 15, 310, 230, PARAM_COUNT, 0 }, { "DX", BLUEPRINT, "bitmaps/textures/metal5.xpm", 0, /* flags */ 0, 0, dxCallback, 666, 15, 310, 230, PARAM_COUNT, locations }, { "DX", BLUEPRINT, "bitmaps/textures/metal5.xpm", 0, /* flags */ 0, 0, dxCallback, 20, 254, 310, 230, PARAM_COUNT, locations }, { "DX", BLUEPRINT, "bitmaps/textures/metal5.xpm", 0, /* flags */ 0, 0, dxCallback, 345, 254, 310, 230, PARAM_COUNT, locations }, { "DX", BLUEPRINT, "bitmaps/textures/metal5.xpm", 0, /* flags */ 0, 0, dxCallback, 666, 254, 310, 230, PARAM_COUNT, locations }, { "DX", "bitmaps/blueprints/dxalgo.xpm", "bitmaps/textures/metal5.xpm", 0, /* flags */ 0, 0, dxCallback, 20, 508, 310, 220, ALGOS_COUNT, algopanel }, { "DX", "bitmaps/blueprints/dxmem.xpm", "bitmaps/textures/metal5.xpm", 0, /* flags */ 0, 0, dxCallback, 666, 508, 310, 220, MEM_COUNT, mempanel }, { "Keyboard", 0, "bitmaps/newkeys/dkbg.xpm", /* flags */ 0x020|BRIGHTON_STRETCH, 0, 0, keyCallback, 110, 735, 870, 260, KEY_COUNT_6_OCTAVE, keys6octave }, { "Mods", "bitmaps/blueprints/mods.xpm", "bitmaps/textures/metal5.xpm", 0, 0, 0, modCallback, 19, 745, 90, 230, 2, mods }, /* Wood rim */ { "Wood", 0, "bitmaps/textures/wood2.xpm", 0, 0, 0, 0, 0, 0, 15, 1000, 0, 0 }, { "Wood", 0, "bitmaps/textures/wood2.xpm", 0, 0, 0, 0, 985, 0, 15, 1000, 0, 0 }, { "Wood", 0, "bitmaps/textures/wood.xpm", 0, 0, 0, 0, 2, 495, 13, 490, 0, 0 }, { "Wood", 0, "bitmaps/textures/wood.xpm", 0, 0, 0, 0, 986, 495, 13, 490, 0, 0 }, { "Envelope", 0, "bitmaps/textures/metal5.xpm", 0, /* flags */ 0, 0, 0, 330, 508, 337, 223, 0, 0 }, } }; /*static dispatcher dispatch[DEVICE_COUNT]; */ static int dxMidiSendMsg(void *synth, int fd, int chan, int c, int o, int v) { /*printf("%i, %i, %i\n", c, o, v); */ bristolMidiSendMsg(fd, chan, c, o, v); return(0); } int dxLoadMem(guiSynth *synth, char *algo, char *name, int location, int active, int skip, int flags) { brightonEvent event; int op; float mo, fmop[OP_COUNT][2]; /* * See if the memory actually exists. This is a bit of file system overhead * but prevents attempting to load non-existant memories */ op = loadMemory(synth, algo, name, location, active, skip, BRISTOL_STAT); if (flags == 2) return(op); if (op < 0) return(op); event.type = BRIGHTON_FLOAT; event.value = 0.0; /* * Zero out diverse gain functions to prevent a noisy transition. * What happens is that as the parameters change and the algorithm alters * we get a LOT of FM noise. We can dump this by zeroing the output * parameters. We have to be careful, since if the memory does not load, * for example it does not exist, then we have to reset the parameters * afterwards. * * Start with main out. */ mo = synth->mem.param[OP_COUNT * PARAM_COUNT + 26]; brightonParamChange(synth->win, ALGOS_PANEL, 26, &event); for (op = 0; op < 6; op++) { /* * Output gain */ fmop[op][0] = synth->mem.param[op * PARAM_COUNT]; brightonParamChange(synth->win, op, 0, &event); /* * Input gain */ fmop[op][1] = synth->mem.param[op * PARAM_COUNT + 3]; brightonParamChange(synth->win, op, 3, &event); } if (loadMemory(synth, algo, name, location, active, skip, flags) == 0) return(0); /* * Load failed, return the gain parameters to their previous values. */ event.value = mo; brightonParamChange(synth->win, ALGOS_PANEL, 26, &event); for (op = 0; op < 6; op++) { /* * Output gain */ event.value = fmop[op][0]; brightonParamChange(synth->win, op, 0, &event); /* * Input gain */ event.value = fmop[op][1]; brightonParamChange(synth->win, op, 3, &event); } return(-1); } static int dxMidiCallback(brightonWindow *win, int command, int value, float v) { guiSynth *synth = findSynth(global.synths, win); printf("midi callback: %x, %i\n", command, value); switch(command) { case MIDI_PROGRAM: printf("midi program: %x, %i\n", command, value); synth->location = value; dxLoadMem(synth, "dx", 0, synth->location, synth->mem.active, FIRST_DEV, 0); break; case MIDI_BANK_SELECT: printf("midi banksel: %x, %i\n", command, value); synth->bank = value; break; } return(0); } static void dxMemory(guiSynth *synth, int fd, int chan, int c, int o, int v) { switch (c) { default: case 0: synth->location = synth->location * 10 + o; if (synth->location >= 1000) synth->location = o; if (dxLoadMem(synth, "dx", 0, synth->location, synth->mem.active, FIRST_DEV, BRISTOL_STAT) < 0) displayPanelText(synth, "FRE", synth->location, DISPLAY_PANEL, DISPLAY_DEV); else displayPanelText(synth, "PRG", synth->location, DISPLAY_PANEL, DISPLAY_DEV); break; case 1: if (dxLoadMem(synth, "dx", 0, synth->location, synth->mem.active, FIRST_DEV, 0) < 0) displayPanelText(synth, "FRE", synth->location, DISPLAY_PANEL, DISPLAY_DEV); else displayPanelText(synth, "PRG", synth->location, DISPLAY_PANEL, DISPLAY_DEV); break; case 2: saveMemory(synth, "dx", 0, synth->location, FIRST_DEV); displayPanelText(synth, "PRG", synth->location, DISPLAY_PANEL, DISPLAY_DEV); break; case 3: while (dxLoadMem(synth, "dx", 0, --synth->location, synth->mem.active, FIRST_DEV, 0) < 0) { if (synth->location < 0) synth->location = 999; } displayPanelText(synth, "PRG", synth->location, DISPLAY_PANEL, DISPLAY_DEV); break; case 4: while (dxLoadMem(synth, "dx", 0, ++synth->location, synth->mem.active, FIRST_DEV, 0) < 0) { if (synth->location > 999) synth->location = -1; } displayPanelText(synth, "PRG", synth->location, DISPLAY_PANEL, DISPLAY_DEV); break; } } static int dxMidi(guiSynth *synth, int fd, int chan, int c, int o, int v) { int newchan; if ((synth->flags & OPERATIONAL) == 0) return(0); if (c == 1) { if ((newchan = synth->midichannel - 1) < 0) { synth->midichannel = 0; return(0); } } else { if ((newchan = synth->midichannel + 1) >= 16) { synth->midichannel = 15; return(0); } } if (global.libtest == 0) bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0, BRISTOL_MIDICHANNEL|newchan); synth->midichannel = newchan; displayPanelText(synth, "MIDI", synth->midichannel + 1, DISPLAY_PANEL, DISPLAY_DEV); return(0); } /* * For the sake of ease of use, links have been placed here to be called * by any of the devices created. They would be better in some other file, * perhaps with this as a dispatch. * * Param refers to the device index in the locations table given below. */ static int dxCallback(brightonWindow * win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); int sendvalue; if (synth == 0) return(0); if (dxApp.resources[panel].devlocn[index].to == 1) sendvalue = value * C_RANGE_MIN_1; else sendvalue = value; switch (panel) { case OP_PANEL: case OP_PANEL + 1: case OP_PANEL + 2: case OP_PANEL + 3: case OP_PANEL + 4: case OP_PANEL + 5: index += panel * PARAM_COUNT; break; case ALGOS_PANEL: index += ALGO_START; break; case MEM_PANEL: index += MEM_START; break; default: printf("unknown panel\n"); break; } if ((synth->flags & OPERATIONAL) == 0) return(0); /* printf("dxCallback(%i, %f): %x\n", index, value, synth); */ synth->mem.param[index] = value; synth->dispatch[index].routine(synth, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #ifdef DEBUG else printf("dispatch[%x,%i](%i, %i, %i, %i, %i)\n", (size_t) synth, index, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #endif return(0); } static void dxAlgo(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; /* printf("dxAlgo(%x, %i, %i, %i, %i, %i): %i\n", */ /* synth, fd, chan, c, o, v, synth->mem.param[v - 1]); */ /* * These will be radio buttons */ if (synth->dispatch[ALGO_START].other2) { synth->dispatch[ALGO_START].other2 = 0; return; } if (v == 0) return; if (synth->dispatch[ALGO_START].other1 >= 0) { synth->dispatch[ALGO_START].other2 = 1; if (synth->dispatch[ALGO_START].other1 != o) event.value = 0; else event.value = 1; /*printf("other one is %i\n", synth->dispatch[ALGO_START].other1); */ brightonParamChange(synth->win, ALGOS_PANEL, synth->dispatch[ALGO_START].other1, &event); } if (v != 0) { char bitmap[128]; event.type = BRIGHTON_MEM; sprintf(bitmap, "bitmaps/images/algo%i.xpm", o); event.m = bitmap; /*printf("%i %i: RECONFIGURING BITMAP\n", v, synth->mem.param[ALGO_START + o]); */ brightonParamChange(synth->win, ALGOS_PANEL, ALGOS_COUNT - 1, &event); } bristolMidiSendMsg(global.controlfd, synth->sid, 126, 101, o); synth->dispatch[ALGO_START].other1 = o; } static void dxTune(guiSynth *synth) { brightonEvent event; printf("dxTune(%p, %i, %i)\n", synth->win, OP_PANEL, OP1_START); event.value = 0.5; brightonParamChange(synth->win, 0, 1, &event); brightonParamChange(synth->win, 1, 1, &event); brightonParamChange(synth->win, 2, 1, &event); brightonParamChange(synth->win, 3, 1, &event); brightonParamChange(synth->win, 4, 1, &event); brightonParamChange(synth->win, 5, 1, &event); } /* * Any location initialisation required to run the callbacks. For bristol, this * will connect to the engine, and give it some base parameters. * May need to generate some application specific menus. * Will also then make specific requests to some of the devices to alter their * rendering. */ static int dxInit(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); dispatcher *dispatch; int i; /* brightonEvent event; char bitmap[128]; event.type = BRIGHTON_MEM; event.m = OP2XPM; brightonParamChange(synth->win, ALGOS_PANEL, ALGOS_COUNT - 1, &event); */ if (synth == 0) { synth = findSynth(global.synths, 0); if (synth == 0) { printf("cannot init\n"); return(0); } } synth->win = win; printf("Initialise the dx link to bristol: %p\n", synth->win); synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float)); synth->mem.count = DEVICE_COUNT; synth->mem.active = ACTIVE_DEVS; synth->dispatch = (dispatcher *) brightonmalloc(DEVICE_COUNT * sizeof(dispatcher)); dispatch = synth->dispatch; /* * We really want to have three connection mechanisms. These should be * 1. Unix named sockets. * 2. UDP sockets. * 3. MIDI pipe. */ if (!global.libtest) if ((synth->sid = initConnection(&global, synth)) < 0) return(-1); for (i = 0; i < DEVICE_COUNT; i++) synth->dispatch[i].routine = dxMidiSendMsg; /* algo panel */ dispatch[ALGO_START].operator = 0; dispatch[ALGO_START + 1].operator = 1; dispatch[ALGO_START + 2].operator = 2; dispatch[ALGO_START + 3].operator = 3; dispatch[ALGO_START + 4].operator = 4; dispatch[ALGO_START + 5].operator = 5; dispatch[ALGO_START + 6].operator = 6; dispatch[ALGO_START + 7].operator = 7; dispatch[ALGO_START + 8].operator = 8; dispatch[ALGO_START + 9].operator = 9; dispatch[ALGO_START + 10].operator = 10; dispatch[ALGO_START + 11].operator = 11; dispatch[ALGO_START + 12].operator = 12; dispatch[ALGO_START + 13].operator = 13; dispatch[ALGO_START + 14].operator = 14; dispatch[ALGO_START + 15].operator = 15; dispatch[ALGO_START + 16].operator = 16; dispatch[ALGO_START + 17].operator = 17; dispatch[ALGO_START + 18].operator = 18; dispatch[ALGO_START + 19].operator = 19; dispatch[ALGO_START + 20].operator = 20; dispatch[ALGO_START + 21].operator = 21; dispatch[ALGO_START + 22].operator = 22; dispatch[ALGO_START + 23].operator = 23; dispatch[ALGO_START].routine = dispatch[ALGO_START + 1].routine = dispatch[ALGO_START + 2].routine = dispatch[ALGO_START + 3].routine = dispatch[ALGO_START + 4].routine = dispatch[ALGO_START + 5].routine = dispatch[ALGO_START + 6].routine = dispatch[ALGO_START + 7].routine = dispatch[ALGO_START + 8].routine = dispatch[ALGO_START + 9].routine = dispatch[ALGO_START + 10].routine = dispatch[ALGO_START + 11].routine = dispatch[ALGO_START + 12].routine = dispatch[ALGO_START + 13].routine = dispatch[ALGO_START + 14].routine = dispatch[ALGO_START + 15].routine = dispatch[ALGO_START + 16].routine = dispatch[ALGO_START + 17].routine = dispatch[ALGO_START + 18].routine = dispatch[ALGO_START + 19].routine = dispatch[ALGO_START + 20].routine = dispatch[ALGO_START + 21].routine = dispatch[ALGO_START + 22].routine = dispatch[ALGO_START + 23].routine = (synthRoutine) dxAlgo; dispatch[ALGO_START + 24].controller = 126; dispatch[ALGO_START + 24].operator = 99; dispatch[ALGO_START + 25].controller = 126; dispatch[ALGO_START + 25].operator = 100; dispatch[ALGO_START + 27].routine = (synthRoutine) dxTune; /* Main volume */ dispatch[ALGO_START + 26].controller = 126; dispatch[ALGO_START + 26].operator = 102; /* operator = 1 */ dispatch[OP1_START].controller = 126; dispatch[OP1_START].operator = 0; dispatch[OP1_START + 1].controller = 0; dispatch[OP1_START + 1].operator = 1; dispatch[OP1_START + 2].controller = 0; dispatch[OP1_START + 2].operator = 0; /* envelope */ dispatch[OP1_START + 5].controller = 0; dispatch[OP1_START + 5].operator = 2; dispatch[OP1_START + 6].controller = 0; dispatch[OP1_START + 6].operator = 3; dispatch[OP1_START + 7].controller = 0; dispatch[OP1_START + 7].operator = 4; dispatch[OP1_START + 8].controller = 0; dispatch[OP1_START + 8].operator = 5; dispatch[OP1_START + 3].controller = 0; dispatch[OP1_START + 3].operator = 6; dispatch[OP1_START + 9].controller = 0; dispatch[OP1_START + 9].operator = 7; dispatch[OP1_START + 4].controller = 126; dispatch[OP1_START + 4].operator = 1; dispatch[OP1_START + 10].controller = 126; dispatch[OP1_START + 10].operator = 2; dispatch[OP1_START + 11].controller = 126; dispatch[OP1_START + 11].operator = 3; dispatch[OP1_START + 12].controller = 0; dispatch[OP1_START + 12].operator = 8; /* L1-A-L2 */ dispatch[OP1_START + 13].controller = 0; dispatch[OP1_START + 13].operator = 9; dispatch[OP1_START + 14].controller = 0; dispatch[OP1_START + 14].operator = 10; dispatch[OP1_START + 15].controller = 0; dispatch[OP1_START + 15].operator = 11; /* operator = 2 */ dispatch[OP2_START].controller = 126; dispatch[OP2_START].operator = 10; dispatch[OP2_START + 1].controller = 1; dispatch[OP2_START + 1].operator = 1; dispatch[OP2_START + 2].controller = 1; dispatch[OP2_START + 2].operator = 0; /* envelope */ dispatch[OP2_START + 5].controller = 1; dispatch[OP2_START + 5].operator = 2; dispatch[OP2_START + 6].controller = 1; dispatch[OP2_START + 6].operator = 3; dispatch[OP2_START + 7].controller = 1; dispatch[OP2_START + 7].operator = 4; dispatch[OP2_START + 8].controller = 1; dispatch[OP2_START + 8].operator = 5; dispatch[OP2_START + 3].controller = 1; dispatch[OP2_START + 3].operator = 6; dispatch[OP2_START + 9].controller = 1; dispatch[OP2_START + 9].operator = 7; dispatch[OP2_START + 4].controller = 126; dispatch[OP2_START + 4].operator = 11; dispatch[OP2_START + 10].controller = 126; dispatch[OP2_START + 10].operator = 12; dispatch[OP2_START + 11].controller = 126; dispatch[OP2_START + 11].operator = 13; dispatch[OP2_START + 12].controller = 1; dispatch[OP2_START + 12].operator = 8; /* L1-A-L2 */ dispatch[OP2_START + 13].controller = 1; dispatch[OP2_START + 13].operator = 9; dispatch[OP2_START + 14].controller = 1; dispatch[OP2_START + 14].operator = 10; dispatch[OP2_START + 15].controller = 1; dispatch[OP2_START + 15].operator = 11; /* operator = 3 */ dispatch[OP3_START].controller = 126; dispatch[OP3_START].operator = 20; dispatch[OP3_START + 1].controller = 2; dispatch[OP3_START + 1].operator = 1; dispatch[OP3_START + 2].controller = 2; dispatch[OP3_START + 2].operator = 0; /* envelope */ dispatch[OP3_START + 5].controller = 2; dispatch[OP3_START + 5].operator = 2; dispatch[OP3_START + 6].controller = 2; dispatch[OP3_START + 6].operator = 3; dispatch[OP3_START + 7].controller = 2; dispatch[OP3_START + 7].operator = 4; dispatch[OP3_START + 8].controller = 2; dispatch[OP3_START + 8].operator = 5; dispatch[OP3_START + 3].controller = 2; dispatch[OP3_START + 3].operator = 6; dispatch[OP3_START + 9].controller = 2; dispatch[OP3_START + 9].operator = 7; dispatch[OP3_START + 4].controller = 126; dispatch[OP3_START + 4].operator = 21; dispatch[OP3_START + 10].controller = 126; dispatch[OP3_START + 10].operator = 22; dispatch[OP3_START + 11].controller = 126; dispatch[OP3_START + 11].operator = 23; dispatch[OP3_START + 12].controller = 2; dispatch[OP3_START + 12].operator = 8; /* L1-A-L2 */ dispatch[OP3_START + 13].controller = 2; dispatch[OP3_START + 13].operator = 9; dispatch[OP3_START + 14].controller = 2; dispatch[OP3_START + 14].operator = 10; dispatch[OP3_START + 15].controller = 2; dispatch[OP3_START + 15].operator = 11; /* operator = 4 */ dispatch[OP4_START].controller = 126; dispatch[OP4_START].operator = 30; dispatch[OP4_START + 1].controller = 3; dispatch[OP4_START + 1].operator = 1; dispatch[OP4_START + 2].controller = 3; dispatch[OP4_START + 2].operator = 0; /* envelope */ dispatch[OP4_START + 5].controller = 3; dispatch[OP4_START + 5].operator = 2; dispatch[OP4_START + 6].controller = 3; dispatch[OP4_START + 6].operator = 3; dispatch[OP4_START + 7].controller = 3; dispatch[OP4_START + 7].operator = 4; dispatch[OP4_START + 8].controller = 3; dispatch[OP4_START + 8].operator = 5; dispatch[OP4_START + 3].controller = 3; dispatch[OP4_START + 3].operator = 6; dispatch[OP4_START + 9].controller = 3; dispatch[OP4_START + 9].operator = 7; dispatch[OP4_START + 4].controller = 126; dispatch[OP4_START + 4].operator = 31; dispatch[OP4_START + 10].controller = 126; dispatch[OP4_START + 10].operator = 32; dispatch[OP4_START + 11].controller = 126; dispatch[OP4_START + 11].operator = 33; dispatch[OP4_START + 12].controller = 3; dispatch[OP4_START + 12].operator = 8; /* L1-A-L2 */ dispatch[OP4_START + 13].controller = 3; dispatch[OP4_START + 13].operator = 9; dispatch[OP4_START + 14].controller = 3; dispatch[OP4_START + 14].operator = 10; dispatch[OP4_START + 15].controller = 3; dispatch[OP4_START + 15].operator = 11; /* operator = 5 */ dispatch[OP5_START].controller = 126; dispatch[OP5_START].operator = 40; dispatch[OP5_START + 1].controller = 4; dispatch[OP5_START + 1].operator = 1; dispatch[OP5_START + 2].controller = 4; dispatch[OP5_START + 2].operator = 0; /* envelope */ dispatch[OP5_START + 5].controller = 4; dispatch[OP5_START + 5].operator = 2; dispatch[OP5_START + 6].controller = 4; dispatch[OP5_START + 6].operator = 3; dispatch[OP5_START + 7].controller = 4; dispatch[OP5_START + 7].operator = 4; dispatch[OP5_START + 8].controller = 4; dispatch[OP5_START + 8].operator = 5; dispatch[OP5_START + 3].controller = 4; dispatch[OP5_START + 3].operator = 6; dispatch[OP5_START + 9].controller = 4; dispatch[OP5_START + 9].operator = 7; dispatch[OP5_START + 4].controller = 126; dispatch[OP5_START + 4].operator = 41; dispatch[OP5_START + 10].controller = 126; dispatch[OP5_START + 10].operator = 42; dispatch[OP5_START + 11].controller = 126; dispatch[OP5_START + 11].operator = 43; dispatch[OP5_START + 12].controller = 4; dispatch[OP5_START + 12].operator = 8; /* L1-A-L2 */ dispatch[OP5_START + 13].controller = 4; dispatch[OP5_START + 13].operator = 9; dispatch[OP5_START + 14].controller = 4; dispatch[OP5_START + 14].operator = 10; dispatch[OP5_START + 15].controller = 4; dispatch[OP5_START + 15].operator = 11; /* operator = 6 */ dispatch[OP6_START].controller = 126; dispatch[OP6_START].operator = 50; dispatch[OP6_START + 1].controller = 5; dispatch[OP6_START + 1].operator = 1; dispatch[OP6_START + 2].controller = 5; dispatch[OP6_START + 2].operator = 0; /* envelope */ dispatch[OP6_START + 5].controller = 5; dispatch[OP6_START + 5].operator = 2; dispatch[OP6_START + 6].controller = 5; dispatch[OP6_START + 6].operator = 3; dispatch[OP6_START + 7].controller = 5; dispatch[OP6_START + 7].operator = 4; dispatch[OP6_START + 8].controller = 5; dispatch[OP6_START + 8].operator = 5; dispatch[OP6_START + 3].controller = 5; dispatch[OP6_START + 3].operator = 6; dispatch[OP6_START + 9].controller = 5; dispatch[OP6_START + 9].operator = 7; dispatch[OP6_START + 4].controller = 126; dispatch[OP6_START + 4].operator = 51; dispatch[OP6_START + 10].controller = 126; dispatch[OP6_START + 10].operator = 52; dispatch[OP6_START + 11].controller = 126; dispatch[OP6_START + 11].operator = 53; dispatch[OP6_START + 12].controller = 5; dispatch[OP6_START + 12].operator = 8; /* L1-A-L2 */ dispatch[OP6_START + 13].controller = 5; dispatch[OP6_START + 13].operator = 9; dispatch[OP6_START + 14].controller = 5; dispatch[OP6_START + 14].operator = 10; dispatch[OP6_START + 15].controller = 5; dispatch[OP6_START + 15].operator = 11; /* memories */ dispatch[MEM_START].operator = 0; dispatch[MEM_START + 1].operator = 1; dispatch[MEM_START + 2].operator = 2; dispatch[MEM_START + 3].operator = 3; dispatch[MEM_START + 4].operator = 4; dispatch[MEM_START + 5].operator = 5; dispatch[MEM_START + 6].operator = 6; dispatch[MEM_START + 7].operator = 7; dispatch[MEM_START + 8].operator = 8; dispatch[MEM_START + 9].operator = 9; dispatch[MEM_START].routine = dispatch[MEM_START + 1].routine = dispatch[MEM_START + 2].routine = dispatch[MEM_START + 3].routine = dispatch[MEM_START + 4].routine = dispatch[MEM_START + 5].routine = dispatch[MEM_START + 6].routine = dispatch[MEM_START + 7].routine = dispatch[MEM_START + 8].routine = dispatch[MEM_START + 9].routine = dispatch[MEM_START + 10].routine = dispatch[MEM_START + 11].routine = dispatch[MEM_START + 15].routine = dispatch[MEM_START + 16].routine = (synthRoutine) dxMemory; dispatch[MEM_START + 10].controller = 1; dispatch[MEM_START + 11].controller = 2; dispatch[MEM_START + 15].controller = 3; dispatch[MEM_START + 16].controller = 4; /* Midi */ dispatch[MEM_START + 12].controller = 2; dispatch[MEM_START + 13].controller = 1; dispatch[MEM_START + 12].routine = dispatch[MEM_START + 13].routine = (synthRoutine) dxMidi; /* * We need to hack in the correct bitmaps for each op. They are all copies * of the same locations structure, but they need a unique image bitmap * for the "OP X" text. */ if (dxApp.resources[1].devlocn == 0) { int index; for (index = 1; index < 6; index++) { dxApp.resources[index].devlocn = (brightonLocations *) brightonmalloc(sizeof(locations)); bcopy(dxApp.resources[0].devlocn, dxApp.resources[index].devlocn, sizeof(locations)); } dxApp.resources[1].devlocn[PARAM_COUNT - 1].image = OP2XPM; dxApp.resources[2].devlocn[PARAM_COUNT - 1].image = OP3XPM; dxApp.resources[3].devlocn[PARAM_COUNT - 1].image = OP4XPM; dxApp.resources[4].devlocn[PARAM_COUNT - 1].image = OP5XPM; dxApp.resources[5].devlocn[PARAM_COUNT - 1].image = OP6XPM; } return(0); } /* * This will be called to make any routine specific parameters available. */ static int dxConfigure(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); brightonEvent event; if (synth == 0) { printf("problems going operational\n"); return(-1); } if (synth->flags & OPERATIONAL) return(0); printf("going operational %p %p\n", synth, synth->win); synth->flags |= OPERATIONAL; synth->keypanel = 8; synth->keypanel2 = -1; synth->transpose = 36; synth->dispatch[ALGO_START].other2 = 0; synth->dispatch[ALGO_START].other1 = -1; dxLoadMem(synth, "dx", 0, 0, synth->mem.active, FIRST_DEV, BRISTOL_FORCE); brightonPut(win, "bitmaps/blueprints/dxshade.xpm", 0, 0, win->width, win->height); /* * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only * occurs on first paint, so we suppress the first paint, and then request * an expose here. */ event.type = BRIGHTON_EXPOSE; event.intvalue = 1; brightonParamChange(synth->win, KEY_PANEL, -1, &event); configureGlobals(synth); return(0); } bristol-0.60.11/brighton/brightonRhodesBass.c0000644000175000017500000003777511746476475016100 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include #include "brighton.h" #include "brightonMini.h" #include "brightoninternals.h" static int rBassInit(); static int rBassConfigure(); static int rBassCallback(brightonWindow *, int, int, float); static int rBassMidiCallback(brightonWindow *, int, int, float); extern guimain global; #include "brightonKeys.h" #define OPTS_PANEL 0 #define MOD_PANEL 1 #define MEM_PANEL 2 #define KEY_PANEL 3 #define FIRST_DEV 0 #define MOD_COUNT 2 #define OPTS_COUNT 8 #define MEM_COUNT 17 #define OPTS_START 0 #define MOD_START OPTS_COUNT #define MEM_START (MOD_COUNT + MOD_START) #define ACTIVE_DEVS (OPTS_COUNT + MOD_COUNT - 1) #define DEVICE_COUNT (MOD_COUNT + OPTS_COUNT + MEM_COUNT) #define DISPLAY_DEV (MEM_COUNT - 1) #define MEM_MGT ACTIVE_DEVS #define MIDI_MGT (MEM_MGT + 12) extern int memCallback(brightonWindow * , int, int, float); extern brightonLocations mem[]; /* * This structure is for device definition. The structure is defined in * include/brighton.h, further definitions in brighton/brightonDevtable.h and * include/brightoninternals.h * * typedef int (*brightonCallback)(int, float); * typedef struct BrightonLocations { * int device; 0=rotary, 1=scale, etc. * float relx, rely; relative position with regards to 1000 by 1000 window * float relw, relh; relative height. * int from, to; * brightonCallback callback; specific to this dev * char *image; bitmap. If zero take a device default. * int flags; * } brightonLocations; * * This example is for a rBassBristol type synth interface. */ #define R1 0 #define W1 100 #define L1 600 #define C1 40 #define C2 190 #define C3 340 #define C4 490 #define C5 700 #define C6 850 static brightonLocations locations[MOD_COUNT] = { {"Bass", 0, 50, 100, 400, 700, 0, 1, 0, 0, 0, 0}, {"Volume", 0, 125, 100, 400, 700, 0, 1, 0, 0, 0, 0}, /* {"", 2, 50, 200, 30, 400, 0, 1, 0, */ /* "bitmaps/buttons/rockerwhite.xpm", 0, 0}, */ }; #define S1 200 /* Options should only be a few piano selectors, no programmers. */ static brightonLocations options[OPTS_COUNT] = { {"", 2, 100, 500, 50, 200, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 200, 500, 50, 200, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 300, 500, 50, 200, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 400, 500, 50, 200, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 500, 500, 50, 200, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 600, 500, 50, 200, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 700, 500, 50, 200, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, {"", 2, 800, 500, 50, 200, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0}, }; /* * This is a set of globals for the main window rendering. Again taken from * include/brighton.h */ brightonApp rhodesBassApp = { "rhodesbass", 0, /* no blueprint on wood background. */ "bitmaps/textures/leather.xpm", 0, rBassInit, rBassConfigure, /* 3 callbacks */ rBassMidiCallback, 0, {32, 0, 2, 2, 5, 520, 0, 1}, 290, 200, 0, 0, 7, /* panel count */ { { "Opts", "bitmaps/blueprints/rhodesopts.xpm", "bitmaps/textures/metal5.xpm", /* flags */ 0x020, 0, 0, rBassCallback, 19, 40, 600, 400, OPTS_COUNT, options }, { "Mods", "bitmaps/blueprints/rhodes.xpm", "bitmaps/images/rhodesplate.xpm", BRIGHTON_STRETCH, 0, 0, rBassCallback, 12, 499, 976, 100, MOD_COUNT, locations }, { "Mem", "bitmaps/blueprints/genmem.xpm", "bitmaps/textures/metal5.xpm", /* flags */ 0x020, 0, 0, memCallback, 619, 40, 362, 400, MEM_COUNT, mem }, { "Keyboard", 0, "bitmaps/newkeys/ekbg.xpm", /* flags */ 0x020|BRIGHTON_STRETCH, 0, 0, keyCallback, 70, 602, 870, 375, KEY_COUNT_2OCTAVE, keys2octave }, { "Rhodes", 0, "bitmaps/images/rhodes.xpm", BRIGHTON_STRETCH, /* flags */ 0, 0, 0, 12, 20, 976, 475, 0, 0 }, { "backing", 0, "bitmaps/textures/metal6.xpm", /* flags */ BRIGHTON_STRETCH, 0, 0, 0, 928, 602, 60, 370, 0, 0 }, { "backing", 0, "bitmaps/textures/metal6.xpm", /* flags */ BRIGHTON_STRETCH, 0, 0, 0, 12, 602, 60, 370, 0, 0 }, } }; /*static dispatcher dispatch[DEVICE_COUNT]; */ static int rBassMidiSendMsg(void *synth, int fd, int chan, int c, int o, int v) { /*printf("rBassMidiSendMsg(%i, %i, %i)\n", c, o, v); */ bristolMidiSendMsg(fd, chan, c, o, v); return(0); } /* * For the sake of ease of use, links have been placed here to be called * by any of the devices created. They would be better in some other file, * perhaps with this as a dispatch. * * Param refers to the device index in the locations table given below. */ static int rBassCallback(brightonWindow * win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); int sendvalue; /* printf("rBassCallback(%i, %i, %f): %x\n", panel, index, value, synth); */ if (synth == 0) return(0); if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0)) return(0); if (rhodesBassApp.resources[panel].devlocn[index].to == 1) sendvalue = value * C_RANGE_MIN_1; else sendvalue = value; switch (panel) { case OPTS_PANEL: index += OPTS_START; break; case MOD_PANEL: index += MOD_START; break; case MEM_PANEL: index += MEM_START; break; } synth->mem.param[index] = value; if ((!global.libtest) || (index >= ACTIVE_DEVS)) synth->dispatch[index].routine(synth, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #ifdef DEBUG else printf("dispatch[%p,%i](%i, %i, %i, %i, %i)\n", synth, index, global.controlfd, synth->sid, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); #endif return(0); } static void rBassProgramme(guiSynth *synth, int fd, int chan, int cont, int op, int value) { brightonEvent event; if (synth->dispatch[OPTS_START].other2) { synth->dispatch[OPTS_START].other2 = 0; synth->mem.param[synth->dispatch[OPTS_START].other1] = 0; return; } if ((synth->flags & MEM_LOADING) == 0) { if (synth->dispatch[OPTS_START].other1 != -1) { synth->dispatch[OPTS_START].other2 = 1; if (synth->dispatch[OPTS_START].other1 != op) event.value = 0; else event.value = 1; brightonParamChange(synth->win, OPTS_PANEL, synth->dispatch[OPTS_START].other1, &event); } synth->dispatch[OPTS_START].other1 = op; synth->mem.param[op] = 1; } if (synth->flags & SUPPRESS) return; if (value != 0) { float *memhold; float mem[256]; int optr, ind; /* printf("rBassProgramme(%x, %i, %i, %i, %i, %i)\n", */ /* synth, fd, chan, cont, op, value); */ /* * Each of the 8 voices has an associated set of DX parameters. We * need to get hold of these, and send them directly over our config * interface tap - we cannot forward via the normal GUi interface since * we do not have these parameters mapped. * * The memories are mapped as 6 operators, each with 20 parameters, * of which 13 are active, and then we have 4 additional parameters for * algo, pitch, glide and volume. */ memhold = &synth->mem.param[0]; synth->mem.param = &mem[0]; ind = 1000 + op; /* * Load the memory parameters with no callbacks. */ if (loadMemory(synth, "rhodes", 0, ind, 148, 0, BRISTOL_FORCE|BRISTOL_NOCALLS) < 0) { printf("NO MEM FOUND, returning\n"); synth->mem.param = memhold; synth->dispatch[OPTS_START].other1 = op; return; } for (optr = 0; optr < 6; optr++) { /*printf("configuring operator %i\n", optr); */ rBassMidiSendMsg(synth, global.controlfd, synth->sid, 126, optr * 10, mem[optr * 20] * C_RANGE_MIN_1); rBassMidiSendMsg(synth, global.controlfd, synth->sid, optr, 1, mem[optr * 20 + 1] * C_RANGE_MIN_1); rBassMidiSendMsg(synth, global.controlfd, synth->sid, optr, 0, mem[optr * 20 + 2]); rBassMidiSendMsg(synth, global.controlfd, synth->sid, optr, 6, mem[optr * 20 + 3] * C_RANGE_MIN_1); rBassMidiSendMsg(synth, global.controlfd, synth->sid, 126, optr * 10 + 1, mem[optr * 20 + 4] * C_RANGE_MIN_1); rBassMidiSendMsg(synth, global.controlfd, synth->sid, optr, 2, mem[optr * 20 + 5] * C_RANGE_MIN_1); rBassMidiSendMsg(synth, global.controlfd, synth->sid, optr, 3, mem[optr * 20 + 6] * C_RANGE_MIN_1); rBassMidiSendMsg(synth, global.controlfd, synth->sid, optr, 4, mem[optr * 20 + 7] * C_RANGE_MIN_1); rBassMidiSendMsg(synth, global.controlfd, synth->sid, optr, 5, mem[optr * 20 + 8] * C_RANGE_MIN_1); rBassMidiSendMsg(synth, global.controlfd, synth->sid, optr, 7, mem[optr * 20 + 9] * C_RANGE_MIN_1); rBassMidiSendMsg(synth, global.controlfd, synth->sid, 126, optr * 10 + 2, mem[optr * 20 + 10] * C_RANGE_MIN_1); rBassMidiSendMsg(synth, global.controlfd, synth->sid, 126, optr * 10 + 3, mem[optr * 20 + 11] * C_RANGE_MIN_1); rBassMidiSendMsg(synth, global.controlfd, synth->sid, optr, 9, mem[optr * 20 + 12] * C_RANGE_MIN_1); rBassMidiSendMsg(synth, global.controlfd, synth->sid, optr, 10, mem[optr * 20 + 13] * C_RANGE_MIN_1); rBassMidiSendMsg(synth, global.controlfd, synth->sid, optr, 11, mem[optr * 20 + 14] * C_RANGE_MIN_1); rBassMidiSendMsg(synth, global.controlfd, synth->sid, optr, 12, mem[optr * 20 + 15] * C_RANGE_MIN_1); } /* * These go through all the algorithms, looking for a single nonzero */ for (ind = 0; ind < 24; ind++) { if (mem[120 + ind] != 0) { /*printf("configuring algo %i\n", ind); */ bristolMidiSendMsg(global.controlfd, synth->sid, 126, 101, ind); } } rBassMidiSendMsg(synth, global.controlfd, synth->sid, 126, 102, C_RANGE_MIN_1); synth->mem.param = memhold; synth->dispatch[OPTS_START].other1 = op; } } static int rBassMidiCallback(brightonWindow *win, int command, int value, float v) { guiSynth *synth = findSynth(global.synths, win); printf("midi callback: %x, %i\n", command, value); switch(command) { case MIDI_PROGRAM: printf("midi program: %x, %i\n", command, value); synth->location = value; rBassProgramme(synth, global.controlfd, synth->sid, synth->dispatch[OPTS_START].controller, synth->dispatch[OPTS_START].operator, 1.0f); break; case MIDI_BANK_SELECT: printf("midi banksel: %x, %i\n", command, value); synth->bank = value; break; } return(0); } static void rBassPanelSwitch(guiSynth *id, int fd, int chan, int cont, int op, int value) { brightonEvent event; id->flags |= SUPPRESS; /*printf("rBassPanelSwitch()\n"); */ /* * If the sendvalue is zero, then withdraw the opts window, draw the * slider window, and vice versa. */ if (value == 0) { event.type = BRIGHTON_EXPOSE; event.intvalue = 0; brightonParamChange(id->win, 0, -1, &event); event.intvalue = 0; brightonParamChange(id->win, 2, -1, &event); event.intvalue = 1; brightonParamChange(id->win, 4, -1, &event); } else { event.type = BRIGHTON_EXPOSE; event.intvalue = 0; brightonParamChange(id->win, 4, -1, &event); event.intvalue = 1; brightonParamChange(id->win, 0, -1, &event); event.intvalue = 1; brightonParamChange(id->win, 2, -1, &event); } id->flags &= ~SUPPRESS; } static void rBassVolume(guiSynth *id, int fd, int chan, int cont, int op, int value) { /*printf("rBassVolume(%i)\n", value); */ bristolMidiSendMsg(global.controlfd, chan, 126, 102, value); } static void rBassBoost(guiSynth *synth, int fd, int chan, int cont, int op, int value) { /*printf("rBassBoost(%i)\n", value); */ bristolMidiControl(global.controlfd, synth->midichannel, 0, 1, value >> 7); } /* * Any location initialisation required to run the callbacks. For bristol, this * will connect to the engine, and give it some base parameters. * May need to generate some application specific menus. * Will also then make specific requests to some of the devices to alter their * rendering. */ static int rBassInit(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); dispatcher *dispatch; int i; if (synth == 0) { synth = findSynth(global.synths, 0); if (synth == 0) { printf("cannot init\n"); return(0); } } synth->win = win; printf("Initialise the Rhodes Bass link to bristol: %p\n", synth->win); synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float)); synth->mem.count = DEVICE_COUNT; synth->mem.active = ACTIVE_DEVS; synth->dispatch = (dispatcher *) brightonmalloc(DEVICE_COUNT * sizeof(dispatcher)); dispatch = synth->dispatch; /* * The rhodes is actually a DX algorithm */ synth->synthtype = 3; /* * We really want to have three connection mechanisms. These should be * 1. Unix named sockets. * 2. UDP sockets. * 3. MIDI pipe. */ if (!global.libtest) if ((synth->sid = initConnection(&global, synth)) < 0) return(-1); for (i = 0; i < DEVICE_COUNT; i++) { synth->dispatch[i].routine = rBassMidiSendMsg; } synth->dispatch[MOD_START + 0].routine = (synthRoutine) rBassBoost; synth->dispatch[MOD_START + 1].routine = (synthRoutine) rBassVolume; synth->dispatch[MOD_START + 2].routine = (synthRoutine) rBassPanelSwitch; synth->dispatch[OPTS_START + 0].routine = synth->dispatch[OPTS_START + 1].routine = synth->dispatch[OPTS_START + 2].routine = synth->dispatch[OPTS_START + 3].routine = synth->dispatch[OPTS_START + 4].routine = synth->dispatch[OPTS_START + 5].routine = synth->dispatch[OPTS_START + 6].routine = synth->dispatch[OPTS_START + 7].routine = (synthRoutine) rBassProgramme; synth->dispatch[OPTS_START + 0].operator = 0; synth->dispatch[OPTS_START + 1].operator = 1; synth->dispatch[OPTS_START + 2].operator = 2; synth->dispatch[OPTS_START + 3].operator = 3; synth->dispatch[OPTS_START + 4].operator = 4; synth->dispatch[OPTS_START + 5].operator = 5; synth->dispatch[OPTS_START + 6].operator = 6; synth->dispatch[OPTS_START + 7].operator = 7; return(0); } /* * This will be called to make any routine specific parameters available. */ static int rBassConfigure(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); brightonEvent event; if (synth == 0) { printf("problems going operational\n"); return(-1); } if (synth->flags & OPERATIONAL) return(0); printf("going operational\n"); synth->flags |= OPERATIONAL; synth->keypanel = 3; synth->keypanel2 = -1; synth->transpose = 48; /* loadMemory(synth, "rhodes", 0, synth->location, synth->mem.active, */ /* FIRST_DEV, 0); */ rBassProgramme(synth, global.controlfd, synth->sid, synth->dispatch[OPTS_START].controller, synth->dispatch[OPTS_START].operator, 1.0f); displayPanelText(synth, "PRG", synth->location, MEM_PANEL, MEM_COUNT - 1); /* * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only * occurs on first paint, so we suppress the first paint, and then request * an expose here. */ event.type = BRIGHTON_EXPOSE; event.intvalue = 1; brightonParamChange(synth->win, KEY_PANEL, -1, &event); event.type = BRIGHTON_FLOAT; event.value = 1; brightonParamChange(synth->win, 0, 0, &event); configureGlobals(synth); brightonPut(synth->win, "bitmaps/blueprints/rhodesbassshade.xpm", 0, 0, synth->win->width, synth->win->height); return(0); } bristol-0.60.11/brighton/brightonSID2.c0000644000175000017500000021113611746476475014525 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include #include "brighton.h" #include "brightonMini.h" #include "brightoninternals.h" #include "brightonSID2.h" static int sid2Init(); static int sid2Configure(); static int sid2Callback(brightonWindow *, int, int, float); static int sid2ModCallback(brightonWindow *, int, int, float); static int midiCallback(brightonWindow *, int, int, float); static int sid2KeyCallback(brightonWindow *, int, int, float); extern guimain global; #include "brightonKeys.h" #define SYNTH_NAME synth->resources->name #define DEVICE_COUNT 254 #define ACTIVE_DEVS 229 #define MEM_START (ACTIVE_DEVS + 8) /* 8 are for globals */ #define KEY_PANEL 1 #define MODS_PANEL 2 #define DISPLAY_DEV (DEVICE_COUNT - 1) static int dc, mbh = 0; /* * This structure is for device definition. The structure is defined in * include/brighton.h, further definitions in brighton/brightonDevtable.h and * include/brightoninternals.h * * typedef int (*brightonCallback)(int, float); * typedef struct BrightonLocations { * int device; 0=rotary, 1=scale, etc. * float relx, rely; relative position with regards to 1000 by 1000 window * float relw, relh; relative height. * int from, to; * brightonCallback callback; specific to this dev * char *image; bitmap. If zero take a device default. * int flags; * } brightonLocations; * * This example is for a sid2Bristol type synth interface. */ /* * GUI needs the following: * * Modes: * * Mono * Poly-H * Poly-V * Voice ALL/1/2/3/4/5 * * Voice-3 PolyMod section to include LFO option, touch, destination. * * PolyMod needs: * * On/off button (No) * LFO button * Tracking button (LFO frequency) * Tracking button (ENV gain) * Tracking button (Voice gain) * Legato button * PPM button * * OSC Routing - 6 bus volumes, touch * ENV Routing - 6 bus volumes, touch * Prod Routing- 6 bus volumes, touch * * LFO-1 * * Remove noise * Stack waveforms * Legato Env * * LFO-2 MonoMods -> S&H. Product. * * No Arpeggiator * * Add in analogue parameters: * S/N, Detune, DC/Bias, Leakage, tune/trans, volume. * perhaps leave out DC Bias? * * Filter: cutoff, res, pole mix, volume+touch, pan. * * Want to have 6 mod busses. The mono mods will be routed to them, the poly * mods also, then the busses can be directed to destinations with routing * buttons. Internally these should be mod routes per chip, presentation may * be distinct - PPM switch: * PPM off - MMods to all, PolyMods to self * PPM on - MMods to any, PolyMods to any * * Add stereo panning for voices. Add global volume, global tuning. There are * also some voice controls I need to add. * * FIX: * Velocity opion per voice - could be in PolyMods? * Keyboard ranging per voice (and arpeggiate?) * Pan - per voice or Mono/All use slightly different positioning +/- * * To send so many voice and routing messages will probably need to either * notify engine of which voice is under control or use different controller * id from 100 for example. */ /* SID2-1 */ #define V1R1 50 #define V1R2 125 #define V1R3 250 #define VD1 36 #define VD2 22 #define VD3 2 #define VBW1 28 #define VBW2 10 #define VBW3 45 #define VBH1 30 #define VBH2 70 #define VBH3 235 #define VBH4 200 #define V1C1 25 #define V1C2 (V1C1 + VD1) #define V1C3 (V1C2 + VD1) #define V1C4 (V1C3 + VD1) #define V1C1b (V1C1 + VD3) #define V1C2b (V1C2 + VD3) #define V1C3b (V1C3 + VD3) #define V1C4b (V1C4 + VD3) #define V1C5 (V1C4 + VD1 + 15) #define V1C6 (V1C5 + VD2) #define V1C7 (V1C6 + VD2) #define V1C8 (V1C7 + VD2) #define V2C1 (V1C8 + VD2 + VD1) #define V2C2 (V2C1 + VD1) #define V2C3 (V2C2 + VD1) #define V2C4 (V2C3 + VD1) #define V2C1b (V2C1 + VD3) #define V2C2b (V2C2 + VD3) #define V2C3b (V2C3 + VD3) #define V2C4b (V2C4 + VD3) #define V2C5 (V2C4 + VD1 + 15) #define V2C6 (V2C5 + VD2) #define V2C7 (V2C6 + VD2) #define V2C8 (V2C7 + VD2) #define V3C1 (V2C8 + VD2 + VD1) #define V3C2 (V3C1 + VD1) #define V3C3 (V3C2 + VD1) #define V3C4 (V3C3 + VD1) #define V3C1b (V3C1 + VD3) #define V3C2b (V3C2 + VD3) #define V3C3b (V3C3 + VD3) #define V3C4b (V3C4 + VD3) #define V3C5 (V3C4 + VD1 + 15) #define V3C6 (V3C5 + VD2) #define V3C7 (V3C6 + VD2) #define V3C8 (V3C7 + VD2) #define FC1 (V3C8 + VD2 + VD1) #define FC2 (FC1 + VD1) #define FC3 (FC2 + VD1) #define FC1b (FC1 + VD3) #define FC2b (FC2 + VD3) #define FC3b (FC3 + VD3) /* SID2-2 Mods */ #define S2R0 460 #define S2R1 (S2R0 + 30) //630 #define S2R2 (S2R1 + 30) //675 #define S2R3 (S2R2 + 50) //750 #define S2R4 (S2R3 + 50) //825 /* SID2-2 Mods */ #define S2R5 760 #define S2R6 (S2R5 + 30) //630 #define S2R7 (S2R6 + 30) //675 #define S2R8 (S2R7 + 50) //750 #define S2R9 (S2R8 + 50) //825 #define S2C0 700 #define S2C1 20 #define S2C1b (S2C1 + VD1/2) #define S2C2 (S2C1 + VD1) #define S2C2b (S2C1 + VD1 + VD1/2) #define S2C3 (S2C2 + VD1) #define S2C3b (S2C3 + VD1/2) #define S2C4 (S2C3 + VD1) #define S2C5 (S2C4 + VD1 + VD2) #define S2C6 (S2C5 + VD1) #define S2C7 (S2C5 + VD1) #define S2C8 (S2C7 + VD1) #define S2C8b (S2C8 + VD1) #define S2C9 (S2C8b + VD2) #define S2C10 (S2C9 + VD2) #define S2C11 (S2C10 + VD2) #define S2C12 (S2C11 + VD2) #define S2C13 (S2C12 + VD1 + 10) #define S2C14 (S2C13 + VD1/2) #define S2C15 (S2C13 + VD1) #define S2C16 730 //(S2C15 + VD1 + VD2) #define S2C17 (S2C16 + VD1) #define S2C18 (S2C17 + VD1) #define S2C19 (S2C18 + VD1) #define S2C20 (S2C19 + VD1) #define S2C21 (S2C20 + VD1) #define S2C22 (S2C21 + VD1) #define S2C23 (S2C22 + VD1 + 10) #define S3C0 730 #define S3C1 (S3C0 + 40) #define S3C2 (S3C1 + 45) #define S3C3 (S3C2 + 45) #define S3C4 (S3C3 + 40) #define S3C5 (S3C4 + 50) #define SRD1 34 #define SRC0 450 #define SRC1 (SRC0 + SRD1) #define SRC2 (SRC1 + SRD1) #define SRC3 (SRC2 + SRD1) #define SRC4 (SRC3 + SRD1) #define SRC5 (SRC4 + SRD1) #define SRC6 (SRC5 + SRD1) #define SRR0 (S2R5-35) #define SRR1 (S2R5) #define SRR2 (S2R5+35) #define SRR3 (S2R5+70) #define SRR4 (S2R5+105) #define SRR5 (S2R5+140) #define SRR6 (S2R5+175) static brightonLocations modwheel[5] = { {"", BRIGHTON_MODWHEEL, 0, 0, 390, 1000, 0, 1, 0, "bitmaps/knobs/modwheel.xpm", 0, BRIGHTON_HSCALE|BRIGHTON_NOSHADOW|BRIGHTON_NOTCH}, {"", 2, 500, 50, 500, 130, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, 500, 306, 500, 130, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, 500, 562, 500, 130, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, 500, 820, 500, 130, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbongreen.xpm", 0}, }; static brightonLocations locations[DEVICE_COUNT] = { /* * Three voices with same parameterisation, roughly * Tri/Ramp/Square/Noise Buttons * RM/SYNC/Mute/Routing(Multi global) Buttons * PW/Tune/transpose(/Glide?) - Pots * Att/Dec/Sust/Rel - Sliders */ {"", 2, V1C1, V1R1, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, V1C2, V1R1, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, V1C3, V1R1, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, V1C4, V1R1, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 0, V1C1b, V1R2, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobred.xpm", 0, 0}, {"", 0, V1C2b, V1R2, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobred.xpm", 0, BRIGHTON_NOTCH}, {"", 0, V1C3b, V1R2, VBW3, VBH2, 0, 24,0, "bitmaps/knobs/knobred.xpm", 0, 0}, {"", 0, V1C4b, V1R2, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobred.xpm", 0, 0}, {"", 2, V1C1, V1R3, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, V1C2, V1R3, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, V1C3, V1R3, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, V1C4, V1R3, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 1, V1C5, V1R1, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, 0}, {"", 1, V1C6, V1R1, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, 0}, {"", 1, V1C7, V1R1, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, 0}, {"", 1, V1C8, V1R1, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, 0}, /* Voice 2 - 16 */ {"", 2, V2C1, V1R1, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, V2C2, V1R1, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, V2C3, V1R1, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, V2C4, V1R1, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 0, V2C1b, V1R2, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobred.xpm", 0,0}, {"", 0, V2C2b, V1R2, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobred.xpm", 0, BRIGHTON_NOTCH}, {"", 0, V2C3b, V1R2, VBW3, VBH2, 0, 24, 0, "bitmaps/knobs/knobred.xpm",0,0}, {"", 0, V2C4b, V1R2, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobred.xpm", 0,0}, {"", 2, V2C1, V1R3, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, V2C2, V1R3, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, V2C3, V1R3, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, V2C4, V1R3, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 1, V2C5, V1R1, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, 0}, {"", 1, V2C6, V1R1, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, 0}, {"", 1, V2C7, V1R1, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, 0}, {"", 1, V2C8, V1R1, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, 0}, /* Voice 3 - 32 */ {"", 2, V3C1, V1R1, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, V3C2, V1R1, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, V3C3, V1R1, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, V3C4, V1R1, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 0, V3C1b, V1R2, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobred.xpm", 0,0}, {"", 0, V3C2b, V1R2, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobred.xpm", 0, BRIGHTON_NOTCH}, {"", 0, V3C3b, V1R2, VBW3, VBH2, 0, 24, 0, "bitmaps/knobs/knobred.xpm",0,0}, {"", 0, V3C4b, V1R2, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobred.xpm", 0,0}, {"", 2, V3C1, V1R3, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, V3C2, V1R3, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, V3C3, V1R3, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, V3C4, V1R3, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 1, V3C5, V1R1, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, 0}, {"", 1, V3C6, V1R1, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, 0}, {"", 1, V3C7, V1R1, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, 0}, {"", 1, V3C8, V1R1, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, 0}, /* Filter - 48 */ {"", 2, FC1, V1R1, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, FC2, V1R1, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, FC3, V1R1, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 0, FC1b, V1R2-24, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobred.xpm", 0, 0}, {"", 0, FC2b, V1R2-24, VBW3, VBH2, 0, 15,0, "bitmaps/knobs/knobred.xpm", 0, 0}, {"", 0, FC3b, V1R2-24, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobred.xpm", 0, 0}, {"", 2, FC3, V1R3-50, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, FC3, V1R3+4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, /* Pan and VoiceVolume */ {"", 0, FC1b, V1R3 - 45, VBW3, VBH2, 0, 15, 0, "bitmaps/knobs/knobyellow.xpm", 0, 0}, {"", 0, FC2b, V1R3 - 45, VBW3, VBH2, 0, 15, 0, "bitmaps/knobs/knobyellow.xpm", 0, 0}, /* 58 - Polymods */ {"", 2, SRC0, S2R0-80, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, SRC1, S2R0-80, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, SRC2, S2R0-80, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, SRC3, S2R0-80, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, SRC4, S2R0-80, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, SRC5, S2R0-80, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, SRC6, S2R0-80, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, /* 65 */ {"", 0, SRC0, S2R0-0, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobgreen.xpm", 0, 0}, {"", 0, SRC1, S2R0-0, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobgreen.xpm", 0, 0}, {"", 0, SRC2, S2R0-0, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobgreen.xpm", 0, 0}, {"", 0, SRC3, S2R0-0, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobgreen.xpm", 0, 0}, {"", 0, SRC4, S2R0-0, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobgreen.xpm", 0, 0}, {"", 0, SRC5, S2R0-0, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobgreen.xpm", 0, 0}, {"", 2, SRC6, S2R0+20, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, /* 72 */ {"", 0, SRC0, S2R2+23, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobgreen.xpm", 0, 0}, {"", 0, SRC1, S2R2+23, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobgreen.xpm", 0, 0}, {"", 0, SRC2, S2R2+23, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobgreen.xpm", 0, 0}, {"", 0, SRC3, S2R2+23, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobgreen.xpm", 0, 0}, {"", 0, SRC4, S2R2+23, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobgreen.xpm", 0, 0}, {"", 0, SRC5, S2R2+23, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobgreen.xpm", 0, 0}, {"", 2, SRC6, S2R2+43, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, /* 79 */ {"", 0, SRC0, S2R4, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobgreen.xpm", 0, 0}, {"", 0, SRC1, S2R4, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobgreen.xpm", 0, 0}, {"", 0, SRC2, S2R4, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobgreen.xpm", 0, 0}, {"", 0, SRC3, S2R4, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobgreen.xpm", 0, 0}, {"", 0, SRC4, S2R4, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobgreen.xpm", 0, 0}, {"", 0, SRC5, S2R4, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobgreen.xpm", 0, 0}, {"", 2, SRC6, S2R4+20, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, 0, 0, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 2, 0, 0, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 2, 0, 0, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 2, 0, 0, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 2, 0, 0, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 2, 0, 0, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 2, 0, 0, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, /* 86 - mod routing change to 6 lots of 7 destinations */ {"", 2, SRC0, SRR1, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, SRC0, SRR2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, SRC0, SRR3, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, SRC0, SRR4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, SRC0, SRR5, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, SRC0, SRR6, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, SRC1, SRR1, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, SRC1, SRR2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, SRC1, SRR3, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, SRC1, SRR4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, SRC1, SRR5, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, SRC1, SRR6, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, SRC2, SRR1, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, SRC2, SRR2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, SRC2, SRR3, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, SRC2, SRR4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, SRC2, SRR5, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, SRC2, SRR6, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, SRC3, SRR1, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, SRC3, SRR2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, SRC3, SRR3, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, SRC3, SRR4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, SRC3, SRR5, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, SRC3, SRR6, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, SRC4, SRR1, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, SRC4, SRR2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, SRC4, SRR3, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, SRC4, SRR4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, SRC4, SRR5, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, SRC4, SRR6, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, SRC5, SRR1, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, SRC5, SRR2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, SRC5, SRR3, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, SRC5, SRR4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, SRC5, SRR5, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, SRC5, SRR6, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, SRC6, SRR1, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, SRC6, SRR2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, SRC6, SRR3, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, SRC6, SRR4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, SRC6, SRR5, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, SRC6, SRR6, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, /* * MODS: 135 * */ /* * Key Mode: * First three radio: Mono, Poly-H, Poly-V * 6 voice selectors: All/1/2/3/4/5 */ {"", 2, S3C0, S2R0, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, S3C0, S2R0+40, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, S3C0, S2R0+80, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, S3C0, S2R0+160, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, S3C1, S2R0+0, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, S3C1, S2R0+40, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, S3C1, S2R0+80, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, S3C1, S2R0+120, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, S3C1, S2R0+160, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, /* Mods - 144 */ {"", 0, S2C1, S2R1, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobgreen.xpm", 0, 0}, {"", 0, S2C3, S2R1, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobgreen.xpm", 0, 0}, {"", 2, S2C1, S2R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, S2C2, S2R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, S2C3, S2R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, S2C4, S2R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, /* 150 - bus selections */ {"", 2, S2C5, S2R0+0, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, S2C5, S2R0+35, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, S2C5, S2R0+70, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, S2C5, S2R0+105, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, S2C5, S2R0+140, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, S2C5, S2R0+175, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, /* 156 - Mod Touch control */ {"", 2, S2C2, S2R2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, S2C4, S2R2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, /* 158 - Env mods */ {"", 2, S2C7, S2R0+0, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, S2C7, S2R0+35, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, S2C7, S2R0+70, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, S2C7, S2R0+105, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, S2C7, S2R0+140, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, S2C7, S2R0+175, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, /* 166 - Mod Env */ {"", 1, S2C8b, S2R0, VBW2, VBH4, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, 0}, {"", 1, S2C9, S2R0, VBW2, VBH4, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, 0}, {"", 1, S2C10, S2R0, VBW2, VBH4, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, 0}, {"", 1, S2C11, S2R0, VBW2, VBH4, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, 0}, {"", 1, S2C12, S2R0, VBW2, VBH4, 0, 1, 0, "bitmaps/buttons/polywhiteV.xpm", 0, 0}, {"", 2, S2C8, S2R0, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, S2C8, S2R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, /* 173 - 2nd Mods */ {"", 0, S2C1, S2R6, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobgreen.xpm", 0, 0}, {"", 0, S2C3, S2R6, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobgreen.xpm", 0, 0}, {"", 2, S2C1, S2R9, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, S2C2, S2R9, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, S2C3, S2R9, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, S2C4, S2R9, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, /* 179 */ {"", 2, S2C5, S2R5+00, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, S2C5, S2R5+35, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, S2C5, S2R5+70, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, S2C5, S2R5+105, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, S2C5, S2R5+140, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, S2C5, S2R5+175, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, /* 185 - Mod Touch control */ {"", 2, S2C2, S2R5, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, S2C2, S2R7, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, S2C4, S2R5, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, S2C4, S2R7, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, /* 189 - Env mods */ {"", 2, S2C7, S2R5+00, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, S2C7, S2R5+35, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, S2C7, S2R5+70, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, S2C7, S2R5+105, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, S2C7, S2R5+140, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, S2C7, S2R5+175, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, /* 195 - Mod Env */ {"", 1, S2C8b, S2R5, VBW2, VBH4, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, 0}, {"", 1, S2C9, S2R5, VBW2, VBH4, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, 0}, {"", 1, S2C10, S2R5, VBW2, VBH4, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, 0}, {"", 1, S2C11, S2R5, VBW2, VBH4, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, 0}, {"", 1, S2C12, S2R5, VBW2, VBH4, 0, 1, 0, "bitmaps/buttons/polywhiteV.xpm", 0, 0}, {"", 2, S2C8, S2R5, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, {"", 2, S2C8, S2R9, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", 0}, /* 202 - Dummies for voice /modes, etc */ {"", 2, 0, 0, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 2, 0, 0, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 2, 0, 0, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 2, 0, 0, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 2, 0, 0, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 2, 0, 0, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 2, 0, 0, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 2, 0, 0, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, /* * This will shadow the version of the memory. Existing memories will have * a zero in here (0.40) ones saved by this release (0.40.2) will have a * 1 in there, this allows the GUI to adjust the keymode parameter. */ #warning this index has changed #define M_VERS 223 {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, /* ??? - These shadow the mod panel */ #warning this index has changed too #define M_SHAD 224 {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, /* 229 - Globals - not saved in memories */ {"", 0, S3C2, S2R0, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", 0, 0}, {"", 0, S3C2, S2R3, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", 0, 0}, {"", 0, S3C3, S2R0, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", 0, 0}, {"", 0, S3C3, S2R3, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm", 0, 0}, {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, {"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm", 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN}, /* 236 - Master Vol */ {"", 0, S3C4, S2R1+20, VBW3, VBH2+30, 0, 1, 0, "bitmaps/knobs/knob.xpm", 0, 0}, /* Memories 237 - first 8 digits */ {"", 2, S2C17, S2R8, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbongreen.xpm", 0}, {"", 2, S2C18, S2R8, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbongreen.xpm", 0}, {"", 2, S2C19, S2R8, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbongreen.xpm", 0}, {"", 2, S2C20, S2R8, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbongreen.xpm", 0}, {"", 2, S2C17, S2R9, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbongreen.xpm", 0}, {"", 2, S2C18, S2R9, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbongreen.xpm", 0}, {"", 2, S2C19, S2R9, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbongreen.xpm", 0}, {"", 2, S2C20, S2R9, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbongreen.xpm", 0}, /* Then load/save */ {"", 2, S2C16, S2R8, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, S2C16, S2R9, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", BRIGHTON_CHECKBUTTON}, /* Then Bank, down, up, find */ {"", 2, S2C21, S2R8, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, S2C22, S2R9, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, S2C22, S2R8, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, S2C21, S2R9, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", BRIGHTON_CHECKBUTTON}, /* Midi */ {"", 2, S3C5, S2R2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", BRIGHTON_CHECKBUTTON}, {"", 2, S3C5, S2R3, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm", "bitmaps/buttons/sidbon.xpm", BRIGHTON_CHECKBUTTON}, /* Done */ {"", 3, S2C17, S2R6, 175, 45, 0, 1, 0, 0, "bitmaps/images/alphadisplay3.xpm", 0} }; /* * This is a set of globals for the main window rendering. Again taken from * include/brighton.h * Hm, the bit-1 was black, and the bit 99 was in various builds including a * white one, but also a black one and a black one with wood panels. I would * like the black one with wood panels, so that will have to be the bit-1, the * bit-99 will be white with thin metal panels. */ brightonApp sid2App = { "melbourne", 0, /* no blueprint on wood background. */ "bitmaps/textures/metal1.xpm", //"bitmaps/textures/p8b.xpm", BRIGHTON_STRETCH, sid2Init, sid2Configure, /* 3 callbacks, unused? */ midiCallback, destroySynth, {1, 100, 2, 2, 5, 520, 0, 0}, 1000, 450, 0, 0, 3, /* panels */ { { "Sid800", "bitmaps/blueprints/sid2.xpm", "bitmaps/textures/metal1.xpm", BRIGHTON_STRETCH, /* flags */ 0, 0, sid2Callback, 25, 16, 950, 720, DEVICE_COUNT, locations }, { "Keyboard", 0, "bitmaps/newkeys/nkbg.xpm", 0x020|BRIGHTON_STRETCH, 0, 0, sid2KeyCallback, 90, 760, 893, 230, KEY_COUNT_5OCTAVE, keysprofile2 }, { "mods", "bitmaps/buttons/blue.xpm", "bitmaps/textures/metal1.xpm", 0, 0, 0, sid2ModCallback, 32, 780, 50, 170, 5, modwheel }, } }; /* * We really want to just use one midi channel and let the midi library decide * that we have multiple synths on the channel with their own split points. * The lower layer should define the midi channel, split point and transpose * of upper layer. */ static int sid2KeyCallback(brightonWindow *win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); if (global.libtest) return(0); /* * So we have a single key event and two MIDI channels. Just send the * event on both channels, no need to be difficult about it since if this * was a split configuration the library filters out the events. */ if (value) { bristolMidiSendMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_KEYON, 0, index + synth->transpose); } else { bristolMidiSendMsg(global.controlfd, synth->midichannel, BRISTOL_EVENT_KEYOFF, 0, index + synth->transpose); } return(0); } /* * At this point we have loaded a memory so we need to send those actual new * parameters to the engine. This is an issue for MIDI program load, perhaps * we should consid2er dual load above memory 74 as per the original? * * The path of least resistance here is to scan through the the memory table * incrementing the input selector and delivering the memory value to the * data entry pot..... */ static void loadMemoryShim(guiSynth *synth) { brightonEvent event; /* We need to force some exclusion on LFO mods and Mode */ synth->dispatch[173].other1 = synth->mem.param[173] != 0? 0: synth->mem.param[174] != 0? 1: synth->mem.param[175] != 0? 2: synth->mem.param[176] != 0? 3: 0; /* We need to force some exclusion on LFO mods and Mode */ synth->dispatch[146].other1 = synth->mem.param[146] != 0? 0: synth->mem.param[147] != 0? 1: synth->mem.param[148] != 0? 2: synth->mem.param[149] != 0? 3: 0; synth->dispatch[135].other1 = synth->mem.param[135] != 0? 0: synth->mem.param[136] != 0? 1: synth->mem.param[137] != 0? 2: 0; bristolMidiSendMsg(global.controlfd, synth->sid2, 126, 5, synth->dispatch[135].other1); /* Set up the trigger options */ /* Then we can look at the mod panel options */ event.type = BRISTOL_FLOAT; event.value = synth->mem.param[111]; brightonParamChange(synth->win, MODS_PANEL, 1, &event); event.value = synth->mem.param[112]; brightonParamChange(synth->win, MODS_PANEL, 2, &event); event.value = synth->mem.param[113]; brightonParamChange(synth->win, MODS_PANEL, 3, &event); event.value = synth->mem.param[114]; brightonParamChange(synth->win, MODS_PANEL, 4, &event); /* And we should enforce mod waveform */ bristolMidiSendMsg(global.controlfd, synth->sid2, 126, 66, synth->mem.param[146] == 0?0:1); bristolMidiSendMsg(global.controlfd, synth->sid2, 126, 67, synth->mem.param[147] == 0?0:1); bristolMidiSendMsg(global.controlfd, synth->sid2, 126, 68, synth->mem.param[149] == 0?0:1); bristolMidiSendMsg(global.controlfd, synth->sid2, 126, 69, synth->mem.param[149] == 0?0:1); if (synth->mem.param[146] != 0) bristolMidiSendMsg(global.controlfd, synth->sid2, 126, 66, 1); /* And we should enforce mod waveform */ bristolMidiSendMsg(global.controlfd, synth->sid2, 126, 66, synth->mem.param[173] == 0?0:1); bristolMidiSendMsg(global.controlfd, synth->sid2, 126, 67, synth->mem.param[174] == 0?0:1); bristolMidiSendMsg(global.controlfd, synth->sid2, 126, 68, synth->mem.param[175] == 0?0:1); bristolMidiSendMsg(global.controlfd, synth->sid2, 126, 69, synth->mem.param[176] == 0?0:1); if (synth->mem.param[173] != 0) bristolMidiSendMsg(global.controlfd, synth->sid2, 126, 66, 1); /* See if we have to force memory variables */ if (synth->mem.param[70] != 0) { int i; for (i = 0; i < 20; i++) { event.value = synth->mem.param[i]; brightonParamChange(synth->win, 0, i, &event); brightonParamChange(synth->win, 0, i + 20, &event); brightonParamChange(synth->win, 0, i + 40, &event); } } } static void loadMemoryMidiShim(guiSynth *synth, int from) { loadMemory(synth, SYNTH_NAME, 0, synth->bank * 10 + from, synth->mem.active, 0, BRISTOL_FORCE); loadMemoryShim(synth); } static int midiCallback(brightonWindow *win, int controller, int value, float n) { guiSynth *synth = findSynth(global.synths, win); switch(controller) { case MIDI_PROGRAM: if (synth->mem.param[87] == 0) return(0); /* * We should accept 0..74 as lower layer and above that as dual * loading requests. */ printf("midi program: %x, %i\n", controller, value); synth->location = value; loadMemoryMidiShim(synth, synth->location); break; case MIDI_BANK_SELECT: printf("midi banksel: %x, %i\n", controller, value); synth->bank = value; break; } return(0); } static int sid2MidiNull(void *synth, int fd, int chan, int c, int o, int v) { if (global.libtest) printf("This is a null callback on %i id %i\n", c, o); return(0); } static int vexclude = 0; /* * Typically this should just do what sid2MidiShim does, send the parameter to * the target however in mode Poly-1 all voices need to have the same set of * parameters. This really means the GUI needs to replicate the parameter * changes all voice params. There are many ways to do this, the coolest is * actually to redistribute the requests, ganging the controls. */ static void sid2VoiceShim(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; int off1 = 20, off2 = 40; if (synth->mem.param[70] != 0) { if (vexclude) return; event.value = synth->mem.param[o - 10]; vexclude = 1; /* Find out what parameters we need to use */ if (o >= 50) { off1 = -40; off2 = -20; } else if (o >= 30) { off1 = -20; off2 = 20; } /* Update the displays */ brightonParamChange(synth->win, synth->panel, o - 10 + off1, &event); brightonParamChange(synth->win, synth->panel, o - 10 + off2, &event); vexclude = 0; /* Send the messages for the other voices */ bristolMidiSendMsg(fd, synth->sid2, c, o + off1, v); bristolMidiSendMsg(fd, synth->sid2, c, o + off2, v); } bristolMidiSendMsg(fd, synth->sid2, c, o, v); } static void sid2MidiShim(guiSynth *synth, int fd, int chan, int c, int o, int v) { bristolMidiSendMsg(fd, synth->sid2, c, o, v); } static void sid2LFOWave(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; event.value = 1.0; event.type = BRISTOL_FLOAT; if (synth->flags & MEM_LOADING) return; if ((synth->flags & OPERATIONAL) == 0) return; if (synth->dispatch[146].other2) { synth->dispatch[146].other2 = 0; return; } /* * We want to make these into memory buttons. To do so we need to * know what the last active button was, and deactivate its * display, then send any message which represents the most * recently configured value. Since this is a memory button we do * not have much issue with the message, but we are concerned with * the display. */ if (synth->dispatch[146].other1 != -1) { synth->dispatch[146].other2 = 1; if (synth->dispatch[146].other1 != o) event.value = 0; else event.value = 1; brightonParamChange(synth->win, synth->panel, synth->dispatch[146].other1 + 146, &event); bristolMidiSendMsg(fd, synth->sid2, 126, 66 + synth->dispatch[146].other1, 0); } synth->dispatch[146].other1 = o; bristolMidiSendMsg(fd, synth->sid2, 126, 66 + o, 1); } static int mode = -1; static void sid2Mode(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; int i, sv; event.value = 1.0; event.type = BRISTOL_FLOAT; if (synth->flags & MEM_LOADING) return; if ((synth->flags & OPERATIONAL) == 0) return; if (synth->dispatch[135].other2) { synth->dispatch[135].other2 = 0; return; } /* * We want to make these into memory buttons. To do so we need to * know what the last active button was, and deactivate its * display, then send any message which represents the most * recently configured value. Since this is a memory button we do * not have much issue with the message, but we are concerned with * the display. */ if (synth->dispatch[135].other1 != -1) { synth->dispatch[135].other2 = 1; if (synth->dispatch[135].other1 != o) event.value = 0; else event.value = 1; brightonParamChange(synth->win, synth->panel, synth->dispatch[135].other1 + 135, &event); } synth->dispatch[135].other1 = o; bristolMidiSendMsg(fd, synth->sid2, 126, 5, o); /* * This code would sync all the voice parameters as we enter Poly-1 however * that is always desirable. We should either sync the engine parameters * to voice-3 entering Poly-1 and reset them to GUI parameters on exit, * or do nothing. */ if (synth->mem.param[70] != 0) { /* * Sync voices in engine */ if (mode != 1) for (i = 0; i < 20; i++) { if (sid2App.resources[0].devlocn[i].to == 1) sv = synth->mem.param[i+40] * C_RANGE_MIN_1; else sv = synth->mem.param[i+40]; bristolMidiSendMsg(fd, synth->sid2, 126, i + 10, sv); bristolMidiSendMsg(fd, synth->sid2, 126, i + 30, sv); } } else { if (mode == 1) for (i = 0; i < 60; i++) { event.value = synth->mem.param[i]; brightonParamChange(synth->win, synth->panel, i, &event); } } mode = o; } static void sid2Memory(guiSynth *synth, int fd, int chan, int c, int o, int v) { brightonEvent event; int bank = synth->bank; int location = synth->location; event.value = 1.0; event.type = BRISTOL_FLOAT; if (synth->flags & MEM_LOADING) return; if ((synth->flags & OPERATIONAL) == 0) return; if (synth->dispatch[MEM_START].other2) { synth->dispatch[MEM_START].other2 = 0; return; } switch (c) { default: case 0: /* * We want to make these into memory buttons. To do so we need to * know what the last active button was, and deactivate its * display, then send any message which represents the most * recently configured value. Since this is a memory button we do * not have much issue with the message, but we are concerned with * the display. */ if (synth->dispatch[MEM_START].other1 != -1) { synth->dispatch[MEM_START].other2 = 1; if (synth->dispatch[MEM_START].other1 != o) event.value = 0; else event.value = 1; brightonParamChange(synth->win, synth->panel, synth->dispatch[MEM_START].other1 + MEM_START - 1, &event); } synth->dispatch[MEM_START].other1 = o; if (synth->flags & BANK_SELECT) { if ((synth->bank * 10 + o) >= 100) { synth->location = o; synth->flags &= ~BANK_SELECT; if (loadMemory(synth, SYNTH_NAME, 0, synth->bank * 10 + synth->location, synth->mem.active, 0, BRISTOL_STAT) < 0) displayText(synth, "FREE MEM", synth->bank * 10 + synth->location, DISPLAY_DEV); else displayText(synth, "PROGRAM", synth->bank * 10 + synth->location, DISPLAY_DEV); } else { synth->bank = synth->bank * 10 + o; displayText(synth, "BANK", synth->bank * 10 + synth->location, DISPLAY_DEV); } } else { if (synth->bank < 1) synth->bank = 1; synth->location = o; if (loadMemory(synth, SYNTH_NAME, 0, synth->bank * 10 + synth->location, synth->mem.active, 0, BRISTOL_STAT) < 0) displayText(synth, "FREE MEM", synth->bank * 10 + synth->location, DISPLAY_DEV); else displayText(synth, "PROGRAM", synth->bank * 10 + synth->location, DISPLAY_DEV); } break; case 1: if (synth->bank < 1) synth->bank = 1; if (synth->location == 0) synth->location = 1; if (loadMemory(synth, SYNTH_NAME, 0, synth->bank * 10 + synth->location, synth->mem.active, 0, BRISTOL_FORCE) < 0) displayText(synth, "FREE MEM", synth->bank * 10 + synth->location, DISPLAY_DEV); else { loadMemoryShim(synth); displayText(synth, "PROGRAM", synth->bank * 10 + synth->location, DISPLAY_DEV); } synth->flags &= ~BANK_SELECT; /* Doubleclick on load will toggle debugging */ if (brightonDoubleClick(dc) != 0) bristolMidiSendMsg(fd, synth->sid2, 126, 4, 1); break; case 2: if (synth->bank < 1) synth->bank = 1; if (synth->location == 0) synth->location = 1; if (brightonDoubleClick(dc) != 0) { synth->mem.param[M_VERS] = 1.0; saveMemory(synth, SYNTH_NAME, 0, synth->bank * 10 + synth->location, 0); displayText(synth, "PROGRAM", synth->bank * 10 + synth->location, DISPLAY_DEV); synth->flags &= ~BANK_SELECT; } break; case 3: if (synth->flags & BANK_SELECT) { synth->flags &= ~BANK_SELECT; if (loadMemory(synth, SYNTH_NAME, 0, synth->bank * 10 + synth->location, synth->mem.active, 0, BRISTOL_STAT) < 0) displayText(synth, "FREE MEM", synth->bank * 10 + synth->location, DISPLAY_DEV); else displayText(synth, "PROGRAM", synth->bank * 10 + synth->location, DISPLAY_DEV); } else { synth->bank = 0; displayText(synth, "BANK", synth->bank, DISPLAY_DEV); synth->flags |= BANK_SELECT; } break; case 4: if (--location < 1) { location = 8; if (--bank < 1) bank = 88; } while (loadMemory(synth, SYNTH_NAME, 0, bank * 10 + location, synth->mem.active, 0, BRISTOL_STAT) < 0) { if (--location < 1) { location = 8; if (--bank < 1) bank = 88; } if ((bank * 10 + location) == (synth->bank * 10 + synth->location)) break; } displayText(synth, "PROGRAM", bank * 10 + location, DISPLAY_DEV); synth->bank = bank; synth->location = location; loadMemory(synth, SYNTH_NAME, 0, bank * 10 + location, synth->mem.active, 0, BRISTOL_FORCE); loadMemoryShim(synth); brightonParamChange(synth->win, 0, MEM_START - 1 + synth->location, &event); break; case 5: if (++location > 8) { location = 1; if (++bank > 88) bank = 1; } while (loadMemory(synth, SYNTH_NAME, 0, bank * 10 + location, synth->mem.active, 0, BRISTOL_STAT) < 0) { if (++location > 8) { location = 1; if (++bank > 88) bank = 1; } if ((bank * 10 + location) == (synth->bank * 10 + synth->location)) break; } displayText(synth, "PROGRAM", bank * 10 + location, DISPLAY_DEV); synth->bank = bank; synth->location = location; loadMemory(synth, SYNTH_NAME, 0, bank * 10 + location, synth->mem.active, 0, BRISTOL_FORCE); loadMemoryShim(synth); brightonParamChange(synth->win, 0, MEM_START - 1 + synth->location, &event); break; case 6: /* Find the next free mem */ if (++location > 8) { location = 1; if (++bank > 88) bank = 1; } while (loadMemory(synth, SYNTH_NAME, 0, bank * 10 + location, synth->mem.active, 0, BRISTOL_STAT) >= 0) { if (++location > 8) { location = 1; if (++bank > 88) bank = 1; } if ((bank * 10 + location) == (synth->bank * 10 + synth->location)) break; } if (loadMemory(synth, SYNTH_NAME, 0, bank * 10 + location, synth->mem.active, 0, BRISTOL_STAT) >= 0) displayText(synth, "PROGRAM", bank * 10 + location, DISPLAY_DEV); else displayText(synth, "FREE MEM", bank * 10 + location, DISPLAY_DEV); synth->bank = bank; synth->location = location; brightonParamChange(synth->win, 0, MEM_START - 1 + synth->location, &event); break; } } static int sid2ModCallback(brightonWindow *win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); brightonEvent event; event.type = BRISTOL_FLOAT; synth->mem.param[M_SHAD + index] = value; switch (index) { case 0: /* Wheel - we don't send pitch, just mod */ bristolMidiControl(global.controlfd, synth->midichannel, 0, 1, ((int) (value * (C_RANGE_MIN_1 - 1))) >> 7); break; case 1: /* Pitch select - these should actually just flag the engine */ bristolMidiSendMsg(global.controlfd, synth->sid2, 126, 100, value == 0?0:1); break; case 2: /* LFO Select - these should actually just flag the engine */ bristolMidiSendMsg(global.controlfd, synth->sid2, 126, 98, value == 0?0:1); if ((synth->mem.param[M_SHAD + index] = value) == 0) return(0); bristolMidiControl(global.controlfd, synth->midichannel, 0, 1, ((int) (synth->mem.param[M_SHAD] * (C_RANGE_MIN_1 - 1))) >> 7); break; case 3: /* ENV Select - these should actually just flag the engine */ bristolMidiSendMsg(global.controlfd, synth->sid2, 126, 99, value == 0?0:1); if ((synth->mem.param[M_SHAD + index] = value) == 0) return(0); bristolMidiControl(global.controlfd, synth->midichannel, 0, 1, ((int) (synth->mem.param[M_SHAD] * (C_RANGE_MIN_1 - 1))) >> 7); break; case 4: /* Center spring */ if (value == 0) win->app->resources[panel].devlocn[0].flags &= ~BRIGHTON_CENTER; else { win->app->resources[panel].devlocn[0].flags |= BRIGHTON_CENTER; /* And centre the control */ event.value = 0.5; brightonParamChange(synth->win, panel, 0, &event); } break; }; return(0); } /* * For the sake of ease of use, links have been placed here to be called * by any of the devices created. They would be better in some other file, * perhaps with this as a dispatch. * * Param refers to the device index in the locations table given below. */ static int sid2Callback(brightonWindow *win, int panel, int index, float value) { guiSynth *synth = findSynth(global.synths, win); int sendvalue; if (global.libtest) printf("sid2Callback(%i, %i, %f)\n", panel, index, value); if (synth == 0) return(0); if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0)) return(0); if ((index >= 111) && (index <= 114)) return(sid2ModCallback(win, MODS_PANEL, index - M_SHAD, value)); if (sid2App.resources[0].devlocn[index].to == 1) sendvalue = value * C_RANGE_MIN_1; else sendvalue = value; synth->mem.param[index] = value; // if (index < 100) synth->dispatch[index].routine(synth, global.controlfd, synth->sid2, synth->dispatch[index].controller, synth->dispatch[index].operator, sendvalue); return(0); } static void sid2MidiChannel(guiSynth *synth, int fd, int chan, int c, int o, int v) { if ((c == 0) && (++synth->midichannel > 15)) synth->midichannel = 15; else if ((c == 1) && (--synth->midichannel < 0)) synth->midichannel = 0; displayText(synth, "MIDI CHAN", synth->midichannel + 1, DISPLAY_DEV); if (global.libtest) return; bristolMidiSendMsg(global.controlfd, synth->sid2, 127, 0, BRISTOL_MIDICHANNEL|synth->midichannel); } /* * Any location initialisation required to run the callbacks. For bristol, this * will connect to the engine, and give it some base parameters. * May need to generate some application specific menus. * Will also then make specific requests to some of the devices to alter their * rendering. */ static int sid2Init(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); dispatcher *dispatch; int i; if (synth == 0) { synth = findSynth(global.synths, 0); if (synth == 0) { printf("cannot init\n"); return(0); } } synth->win = win; printf("Initialise the sid2 link to bristol: %p\n", synth->win); synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float)); synth->mem.count = DEVICE_COUNT; synth->mem.active = ACTIVE_DEVS; synth->dispatch = (dispatcher *) brightonmalloc(DEVICE_COUNT * sizeof(dispatcher)); dispatch = synth->dispatch; /* * We really want to have three connection mechanisms. These should be * 1. Unix named sockets. * 2. UDP sockets (actually implements TCP unfortunately). * 3. MIDI pipe. */ if (!global.libtest) { if ((synth->sid2 = initConnection(&global, synth)) < 0) return(-1); } for (i = 0; i < DEVICE_COUNT; i++) { synth->dispatch[i].routine = (synthRoutine) sid2MidiNull; synth->dispatch[i].controller = i; synth->dispatch[i].operator = i; } /* Voice 1 */ dispatch[0].controller = 126; dispatch[0].operator = 10; dispatch[0].routine = (synthRoutine) sid2VoiceShim; dispatch[1].controller = 126; dispatch[1].operator = 11; dispatch[1].routine = (synthRoutine) sid2VoiceShim; dispatch[2].controller = 126; dispatch[2].operator = 12; dispatch[2].routine = (synthRoutine) sid2VoiceShim; dispatch[3].controller = 126; dispatch[3].operator = 13; dispatch[3].routine = (synthRoutine) sid2VoiceShim; /* PW, tune, transpose, glide */ dispatch[4].controller = 126; dispatch[4].operator = 14; dispatch[4].routine = (synthRoutine) sid2VoiceShim; dispatch[5].controller = 126; dispatch[5].operator = 15; dispatch[5].routine = (synthRoutine) sid2VoiceShim; dispatch[6].controller = 126; dispatch[6].operator = 16; dispatch[6].routine = (synthRoutine) sid2VoiceShim; dispatch[7].controller = 126; dispatch[7].operator = 17; dispatch[7].routine = (synthRoutine) sid2VoiceShim; /* RM/sync/mute/route */ dispatch[8].controller = 126; dispatch[8].operator = 18; dispatch[8].routine = (synthRoutine) sid2VoiceShim; dispatch[9].controller = 126; dispatch[9].operator = 19; dispatch[9].routine = (synthRoutine) sid2VoiceShim; dispatch[10].controller = 126; dispatch[10].operator = 20; dispatch[10].routine = (synthRoutine) sid2VoiceShim; dispatch[11].controller = 126; dispatch[11].operator = 21; dispatch[11].routine = (synthRoutine) sid2VoiceShim; /* Env */ dispatch[12].controller = 126; dispatch[12].operator = 22; dispatch[12].routine = (synthRoutine) sid2VoiceShim; dispatch[13].controller = 126; dispatch[13].operator = 23; dispatch[13].routine = (synthRoutine) sid2VoiceShim; dispatch[14].controller = 126; dispatch[14].operator = 24; dispatch[14].routine = (synthRoutine) sid2VoiceShim; dispatch[15].controller = 126; dispatch[15].operator = 25; dispatch[15].routine = (synthRoutine) sid2VoiceShim; /* Voice 2 */ dispatch[16].controller = 126; dispatch[16].operator = 30; dispatch[16].routine = (synthRoutine) sid2VoiceShim; dispatch[17].controller = 126; dispatch[17].operator = 31; dispatch[17].routine = (synthRoutine) sid2VoiceShim; dispatch[18].controller = 126; dispatch[18].operator = 32; dispatch[18].routine = (synthRoutine) sid2VoiceShim; dispatch[19].controller = 126; dispatch[19].operator = 33; dispatch[19].routine = (synthRoutine) sid2VoiceShim; /* PW, tune, transpose, glide */ dispatch[20].controller = 126; dispatch[20].operator = 34; dispatch[20].routine = (synthRoutine) sid2VoiceShim; dispatch[21].controller = 126; dispatch[21].operator = 35; dispatch[21].routine = (synthRoutine) sid2VoiceShim; dispatch[22].controller = 126; dispatch[22].operator = 36; dispatch[22].routine = (synthRoutine) sid2VoiceShim; dispatch[23].controller = 126; dispatch[23].operator = 37; dispatch[23].routine = (synthRoutine) sid2VoiceShim; /* RM/sync/mute/route */ dispatch[24].controller = 126; dispatch[24].operator = 38; dispatch[24].routine = (synthRoutine) sid2VoiceShim; dispatch[25].controller = 126; dispatch[25].operator = 39; dispatch[25].routine = (synthRoutine) sid2VoiceShim; dispatch[26].controller = 126; dispatch[26].operator = 40; dispatch[26].routine = (synthRoutine) sid2VoiceShim; dispatch[27].controller = 126; dispatch[27].operator = 41; dispatch[27].routine = (synthRoutine) sid2VoiceShim; /* Env */ dispatch[28].controller = 126; dispatch[28].operator = 42; dispatch[28].routine = (synthRoutine) sid2VoiceShim; dispatch[29].controller = 126; dispatch[29].operator = 43; dispatch[29].routine = (synthRoutine) sid2VoiceShim; dispatch[30].controller = 126; dispatch[30].operator = 44; dispatch[30].routine = (synthRoutine) sid2VoiceShim; dispatch[31].controller = 126; dispatch[31].operator = 45; dispatch[31].routine = (synthRoutine) sid2VoiceShim; /* Voice 3 */ dispatch[32].controller = 126; dispatch[32].operator = 50; dispatch[32].routine = (synthRoutine) sid2VoiceShim; dispatch[33].controller = 126; dispatch[33].operator = 51; dispatch[33].routine = (synthRoutine) sid2VoiceShim; dispatch[34].controller = 126; dispatch[34].operator = 52; dispatch[34].routine = (synthRoutine) sid2VoiceShim; dispatch[35].controller = 126; dispatch[35].operator = 53; dispatch[35].routine = (synthRoutine) sid2VoiceShim; /* PW, tune, transpose, glide */ dispatch[36].controller = 126; dispatch[36].operator = 54; dispatch[36].routine = (synthRoutine) sid2VoiceShim; dispatch[37].controller = 126; dispatch[37].operator = 55; dispatch[37].routine = (synthRoutine) sid2VoiceShim; dispatch[38].controller = 126; dispatch[38].operator = 56; dispatch[38].routine = (synthRoutine) sid2VoiceShim; dispatch[49].controller = 126; dispatch[39].operator = 57; dispatch[39].routine = (synthRoutine) sid2VoiceShim; /* RM/sync/mute/route */ dispatch[40].controller = 126; dispatch[40].operator = 58; dispatch[40].routine = (synthRoutine) sid2VoiceShim; dispatch[41].controller = 126; dispatch[41].operator = 59; dispatch[41].routine = (synthRoutine) sid2VoiceShim; dispatch[42].controller = 126; dispatch[42].operator = 60; dispatch[42].routine = (synthRoutine) sid2VoiceShim; dispatch[43].controller = 126; dispatch[43].operator = 61; dispatch[43].routine = (synthRoutine) sid2VoiceShim; /* Env */ dispatch[44].controller = 126; dispatch[44].operator = 62; dispatch[44].routine = (synthRoutine) sid2VoiceShim; dispatch[45].controller = 126; dispatch[45].operator = 63; dispatch[45].routine = (synthRoutine) sid2VoiceShim; dispatch[46].controller = 126; dispatch[46].operator = 64; dispatch[46].routine = (synthRoutine) sid2VoiceShim; dispatch[47].controller = 126; dispatch[47].operator = 65; dispatch[47].routine = (synthRoutine) sid2VoiceShim; /* Filter */ dispatch[48].controller = 126; dispatch[48].operator = 70; dispatch[48].routine = (synthRoutine) sid2MidiShim; dispatch[49].controller = 126; dispatch[49].operator = 71; dispatch[49].routine = (synthRoutine) sid2MidiShim; dispatch[50].controller = 126; dispatch[50].operator = 72; dispatch[50].routine = (synthRoutine) sid2MidiShim; /* Cutoff/res/OBmix */ dispatch[51].controller = 126; dispatch[51].operator = 73; dispatch[51].routine = (synthRoutine) sid2MidiShim; dispatch[52].controller = 126; dispatch[52].operator = 74; dispatch[52].routine = (synthRoutine) sid2MidiShim; dispatch[53].controller = 126; dispatch[53].operator = 75; dispatch[53].routine = (synthRoutine) sid2MidiShim; dispatch[54].controller = 126; dispatch[54].operator = 76; dispatch[54].routine = (synthRoutine) sid2MidiShim; /* Multi and master vol */ dispatch[67].controller = 126; dispatch[67].operator = 2; dispatch[67].routine = (synthRoutine) sid2MidiShim; dispatch[68].controller = 126; dispatch[68].operator = 3; dispatch[68].routine = (synthRoutine) sid2MidiShim; dispatch[135].operator = 0; dispatch[136].operator = 1; dispatch[137].operator = 2; dispatch[135].routine = dispatch[136].routine = dispatch[137].routine = (synthRoutine) sid2Mode; /* Mod freq, gain and waveform */ dispatch[74].controller = 126; dispatch[74].operator = 77; dispatch[74].routine = (synthRoutine) sid2MidiShim; dispatch[75].controller = 126; dispatch[75].operator = 78; dispatch[75].routine = (synthRoutine) sid2MidiShim; dispatch[146].operator = 0; dispatch[147].operator = 1; dispatch[148].operator = 2; dispatch[149].operator = 3; dispatch[146].routine = dispatch[147].routine = dispatch[148].routine = dispatch[149].routine = (synthRoutine) sid2LFOWave; /* Then we have the routing buttons, TBD */ dispatch[80].controller = 126; dispatch[80].operator = 79; dispatch[80].routine = (synthRoutine) sid2MidiShim; dispatch[81].controller = 126; dispatch[81].operator = 80; dispatch[81].routine = (synthRoutine) sid2MidiShim; dispatch[82].controller = 126; dispatch[82].operator = 81; dispatch[82].routine = (synthRoutine) sid2MidiShim; dispatch[83].controller = 126; dispatch[83].operator = 82; dispatch[83].routine = (synthRoutine) sid2MidiShim; dispatch[84].controller = 126; dispatch[84].operator = 83; dispatch[84].routine = (synthRoutine) sid2MidiShim; dispatch[85].controller = 126; dispatch[85].operator = 84; dispatch[85].routine = (synthRoutine) sid2MidiShim; dispatch[86].controller = 126; dispatch[86].operator = 85; dispatch[86].routine = (synthRoutine) sid2MidiShim; dispatch[87].controller = 126; dispatch[87].operator = 101; dispatch[87].routine = (synthRoutine) sid2MidiShim; dispatch[88].controller = 126; dispatch[88].operator = 102; dispatch[88].routine = (synthRoutine) sid2MidiShim; dispatch[95].controller = 126; dispatch[95].operator = 89; dispatch[95].routine = (synthRoutine) sid2MidiShim; dispatch[96].controller = 126; dispatch[96].operator = 90; dispatch[96].routine = (synthRoutine) sid2MidiShim; dispatch[97].controller = 126; dispatch[97].operator = 91; dispatch[97].routine = (synthRoutine) sid2MidiShim; dispatch[98].controller = 126; dispatch[98].operator = 92; dispatch[98].routine = (synthRoutine) sid2MidiShim; dispatch[99].controller = 126; dispatch[99].operator = 86; dispatch[99].routine = (synthRoutine) sid2MidiShim; dispatch[100].controller = 126; dispatch[100].operator = 87; dispatch[100].routine = (synthRoutine) sid2MidiShim; dispatch[101].controller = 126; dispatch[101].operator = 88; dispatch[101].routine = (synthRoutine) sid2MidiShim; /* Env mod */ dispatch[102].controller = 126; dispatch[102].operator = 93; dispatch[102].routine = (synthRoutine) sid2MidiShim; dispatch[103].controller = 126; dispatch[103].operator = 94; dispatch[103].routine = (synthRoutine) sid2MidiShim; dispatch[104].controller = 126; dispatch[104].operator = 95; dispatch[104].routine = (synthRoutine) sid2MidiShim; dispatch[105].controller = 126; dispatch[105].operator = 96; dispatch[105].routine = (synthRoutine) sid2MidiShim; dispatch[106].controller = 126; dispatch[106].operator = 97; dispatch[106].routine = (synthRoutine) sid2MidiShim; dispatch[107].controller = 126; dispatch[107].operator = 103; dispatch[107].routine = (synthRoutine) sid2MidiShim; /* Arpeggiator */ dispatch[115].controller = 126; dispatch[115].operator = 6; dispatch[115].routine = (synthRoutine) sid2MidiShim; dispatch[116].controller = 126; dispatch[116].operator = 7; dispatch[116].routine = (synthRoutine) sid2MidiShim; dispatch[117].controller = 126; dispatch[117].operator = 8; dispatch[117].routine = (synthRoutine) sid2MidiShim; /* Memory and MIDI */ dispatch[MEM_START + 0].operator = 1; dispatch[MEM_START + 1].operator = 2; dispatch[MEM_START + 2].operator = 3; dispatch[MEM_START + 3].operator = 4; dispatch[MEM_START + 4].operator = 5; dispatch[MEM_START + 5].operator = 6; dispatch[MEM_START + 6].operator = 7; dispatch[MEM_START + 7].operator = 8; dispatch[MEM_START + 8].controller = 1; dispatch[MEM_START + 9].controller = 2; dispatch[MEM_START + 10].controller = 3; dispatch[MEM_START + 11].controller = 4; dispatch[MEM_START + 12].controller = 5; dispatch[MEM_START + 13].controller = 6; dispatch[MEM_START + 0].routine = dispatch[MEM_START + 1].routine = dispatch[MEM_START + 2].routine = dispatch[MEM_START + 3].routine = dispatch[MEM_START + 4].routine = dispatch[MEM_START + 5].routine = dispatch[MEM_START + 6].routine = dispatch[MEM_START + 7].routine = dispatch[MEM_START + 8].routine = dispatch[MEM_START + 9].routine = dispatch[MEM_START + 10].routine = dispatch[MEM_START + 11].routine = dispatch[MEM_START + 12].routine = dispatch[MEM_START + 13].routine = (synthRoutine) sid2Memory; dispatch[132].controller = 0; dispatch[133].controller = 1; dispatch[132].routine = dispatch[133].routine = (synthRoutine) sid2MidiChannel; /* Osc-1 settings */ /* Env settings */ /* Filter */ dispatch[MEM_START].other1 = 1; dispatch[135].other1 = 0; dispatch[146].other1 = 0; dispatch[173].other1 = 0; return(0); } /* * This will be called to make any routine specific parameters available. */ static int sid2Configure(brightonWindow *win) { guiSynth *synth = findSynth(global.synths, win); brightonEvent event; if (synth == 0) { printf("problems going operational\n"); return(-1); } if (synth->location == 0) { synth->bank = 1; synth->location = 1; } else if (synth->location > 0) { mbh = (synth->location / 100) * 100; if ((synth->bank = synth->location / 10) > 10) synth->bank = synth->bank % 10; if (((synth->location = synth->location % 10) == 0) || (synth->location > 8)) synth->location = 1; } if (synth->flags & OPERATIONAL) return(0); printf("going operational\n"); synth->flags |= OPERATIONAL; synth->keypanel = 1; synth->keypanel2 = -1; synth->transpose = 24; brightonPut(win, "bitmaps/blueprints/melbourneshade.xpm", 0, 0, win->width, win->height); /* * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only * occurs on first paint, so we suppress the first paint, and then request * an expose here. */ event.type = BRIGHTON_EXPOSE; event.intvalue = 1; brightonParamChange(synth->win, KEY_PANEL, -1, &event); /* Push some mod panel defaults */ event.type = BRISTOL_FLOAT; event.value = 1; brightonParamChange(synth->win, MODS_PANEL, 1, &event); brightonParamChange(synth->win, MODS_PANEL, 2, &event); brightonParamChange(synth->win, MODS_PANEL, 4, &event); configureGlobals(synth); /* * First memory location */ event.value = 1.0; brightonParamChange(synth->win, 0, MEM_START + synth->location-1, &event); brightonParamChange(synth->win, 0, 135, &event); brightonParamChange(synth->win, 0, 146, &event); brightonParamChange(synth->win, 0, 173, &event); loadMemory(synth, SYNTH_NAME, 0, synth->bank * 10 + synth->location, synth->mem.active, 0, BRISTOL_FORCE); loadMemoryShim(synth); event.value = 0.505; brightonParamChange(synth->win, MODS_PANEL, 0, &event); synth->dispatch[MEM_START].other1 = synth->location; dc = brightonGetDCTimer(1000000); return(0); } bristol-0.60.11/ltmain.sh0000644000175000017500000105202612073601230012076 00000000000000 # libtool (GNU libtool) 2.4.2 # Written by Gordon Matzigkeit , 1996 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, # 2007, 2008, 2009, 2010, 2011 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. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, # or obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Usage: $progname [OPTION]... [MODE-ARG]... # # Provide generalized library-building support services. # # --config show all configuration variables # --debug enable verbose shell tracing # -n, --dry-run display commands without modifying any files # --features display basic configuration information and exit # --mode=MODE use operation mode MODE # --preserve-dup-deps don't remove duplicate dependency libraries # --quiet, --silent don't print informational messages # --no-quiet, --no-silent # print informational messages (default) # --no-warn don't display warning messages # --tag=TAG use configuration variables from tag TAG # -v, --verbose print more informational messages than default # --no-verbose don't print the extra informational messages # --version print version information # -h, --help, --help-all print short, long, or detailed help message # # MODE must be one of the following: # # clean remove files from the build directory # compile compile a source file into a libtool object # execute automatically set library path, then run a program # finish complete the installation of libtool libraries # install install libraries or executables # link create a library or an executable # uninstall remove libraries from an installed directory # # MODE-ARGS vary depending on the MODE. When passed as first option, # `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that. # Try `$progname --help --mode=MODE' for a more detailed description of MODE. # # When reporting a bug, please describe a test case to reproduce it and # include the following information: # # host-triplet: $host # shell: $SHELL # compiler: $LTCC # compiler flags: $LTCFLAGS # linker: $LD (gnu? $with_gnu_ld) # $progname: (GNU libtool) 2.4.2 Debian-2.4.2-1.1 # automake: $automake_version # autoconf: $autoconf_version # # Report bugs to . # GNU libtool home page: . # General help using GNU software: . PROGRAM=libtool PACKAGE=libtool VERSION="2.4.2 Debian-2.4.2-1.1" TIMESTAMP="" package_revision=1.3337 # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } # NLS nuisances: We save the old values to restore during execute mode. lt_user_locale= lt_safe_locale= for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${$lt_var+set}\" = set; then save_$lt_var=\$$lt_var $lt_var=C export $lt_var lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\" lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\" fi" done LC_ALL=C LANGUAGE=C export LANGUAGE LC_ALL $lt_unset CDPATH # Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh # is ksh but when the shell is invoked as "sh" and the current value of # the _XPG environment variable is not equal to 1 (one), the special # positional parameter $0, within a function call, is the name of the # function. progpath="$0" : ${CP="cp -f"} test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'} : ${MAKE="make"} : ${MKDIR="mkdir"} : ${MV="mv -f"} : ${RM="rm -f"} : ${SHELL="${CONFIG_SHELL-/bin/sh}"} : ${Xsed="$SED -e 1s/^X//"} # Global variables: EXIT_SUCCESS=0 EXIT_FAILURE=1 EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. exit_status=$EXIT_SUCCESS # Make sure IFS has a sensible default lt_nl=' ' IFS=" $lt_nl" dirname="s,/[^/]*$,," basename="s,^.*/,," # func_dirname file append nondir_replacement # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. func_dirname () { func_dirname_result=`$ECHO "${1}" | $SED "$dirname"` if test "X$func_dirname_result" = "X${1}"; then func_dirname_result="${3}" else func_dirname_result="$func_dirname_result${2}" fi } # func_dirname may be replaced by extended shell implementation # func_basename file func_basename () { func_basename_result=`$ECHO "${1}" | $SED "$basename"` } # func_basename may be replaced by extended shell implementation # func_dirname_and_basename file append nondir_replacement # perform func_basename and func_dirname in a single function # call: # dirname: Compute the dirname of FILE. If nonempty, # add APPEND to the result, otherwise set result # to NONDIR_REPLACEMENT. # value returned in "$func_dirname_result" # basename: Compute filename of FILE. # value retuned in "$func_basename_result" # Implementation must be kept synchronized with func_dirname # and func_basename. For efficiency, we do not delegate to # those functions but instead duplicate the functionality here. func_dirname_and_basename () { # Extract subdirectory from the argument. func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"` if test "X$func_dirname_result" = "X${1}"; then func_dirname_result="${3}" else func_dirname_result="$func_dirname_result${2}" fi func_basename_result=`$ECHO "${1}" | $SED -e "$basename"` } # func_dirname_and_basename may be replaced by extended shell implementation # func_stripname prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # func_strip_suffix prefix name func_stripname () { case ${2} in .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; esac } # func_stripname may be replaced by extended shell implementation # These SED scripts presuppose an absolute path with a trailing slash. pathcar='s,^/\([^/]*\).*$,\1,' pathcdr='s,^/[^/]*,,' removedotparts=':dotsl s@/\./@/@g t dotsl s,/\.$,/,' collapseslashes='s@/\{1,\}@/@g' finalslash='s,/*$,/,' # func_normal_abspath PATH # Remove doubled-up and trailing slashes, "." path components, # and cancel out any ".." path components in PATH after making # it an absolute path. # value returned in "$func_normal_abspath_result" func_normal_abspath () { # Start from root dir and reassemble the path. func_normal_abspath_result= func_normal_abspath_tpath=$1 func_normal_abspath_altnamespace= case $func_normal_abspath_tpath in "") # Empty path, that just means $cwd. func_stripname '' '/' "`pwd`" func_normal_abspath_result=$func_stripname_result return ;; # The next three entries are used to spot a run of precisely # two leading slashes without using negated character classes; # we take advantage of case's first-match behaviour. ///*) # Unusual form of absolute path, do nothing. ;; //*) # Not necessarily an ordinary path; POSIX reserves leading '//' # and for example Cygwin uses it to access remote file shares # over CIFS/SMB, so we conserve a leading double slash if found. func_normal_abspath_altnamespace=/ ;; /*) # Absolute path, do nothing. ;; *) # Relative path, prepend $cwd. func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath ;; esac # Cancel out all the simple stuff to save iterations. We also want # the path to end with a slash for ease of parsing, so make sure # there is one (and only one) here. func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"` while :; do # Processed it all yet? if test "$func_normal_abspath_tpath" = / ; then # If we ascended to the root using ".." the result may be empty now. if test -z "$func_normal_abspath_result" ; then func_normal_abspath_result=/ fi break fi func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$pathcar"` func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$pathcdr"` # Figure out what to do with it case $func_normal_abspath_tcomponent in "") # Trailing empty path component, ignore it. ;; ..) # Parent dir; strip last assembled component from result. func_dirname "$func_normal_abspath_result" func_normal_abspath_result=$func_dirname_result ;; *) # Actual path component, append it. func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent ;; esac done # Restore leading double-slash if one was found on entry. func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result } # func_relative_path SRCDIR DSTDIR # generates a relative path from SRCDIR to DSTDIR, with a trailing # slash if non-empty, suitable for immediately appending a filename # without needing to append a separator. # value returned in "$func_relative_path_result" func_relative_path () { func_relative_path_result= func_normal_abspath "$1" func_relative_path_tlibdir=$func_normal_abspath_result func_normal_abspath "$2" func_relative_path_tbindir=$func_normal_abspath_result # Ascend the tree starting from libdir while :; do # check if we have found a prefix of bindir case $func_relative_path_tbindir in $func_relative_path_tlibdir) # found an exact match func_relative_path_tcancelled= break ;; $func_relative_path_tlibdir*) # found a matching prefix func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" func_relative_path_tcancelled=$func_stripname_result if test -z "$func_relative_path_result"; then func_relative_path_result=. fi break ;; *) func_dirname $func_relative_path_tlibdir func_relative_path_tlibdir=${func_dirname_result} if test "x$func_relative_path_tlibdir" = x ; then # Have to descend all the way to the root! func_relative_path_result=../$func_relative_path_result func_relative_path_tcancelled=$func_relative_path_tbindir break fi func_relative_path_result=../$func_relative_path_result ;; esac done # Now calculate path; take care to avoid doubling-up slashes. func_stripname '' '/' "$func_relative_path_result" func_relative_path_result=$func_stripname_result func_stripname '/' '/' "$func_relative_path_tcancelled" if test "x$func_stripname_result" != x ; then func_relative_path_result=${func_relative_path_result}/${func_stripname_result} fi # Normalisation. If bindir is libdir, return empty string, # else relative path ending with a slash; either way, target # file name can be directly appended. if test ! -z "$func_relative_path_result"; then func_stripname './' '' "$func_relative_path_result/" func_relative_path_result=$func_stripname_result fi } # The name of this program: func_dirname_and_basename "$progpath" progname=$func_basename_result # Make sure we have an absolute path for reexecution: case $progpath in [\\/]*|[A-Za-z]:\\*) ;; *[\\/]*) progdir=$func_dirname_result progdir=`cd "$progdir" && pwd` progpath="$progdir/$progname" ;; *) save_IFS="$IFS" IFS=${PATH_SEPARATOR-:} for progdir in $PATH; do IFS="$save_IFS" test -x "$progdir/$progname" && break done IFS="$save_IFS" test -n "$progdir" || progdir=`pwd` progpath="$progdir/$progname" ;; esac # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. Xsed="${SED}"' -e 1s/^X//' sed_quote_subst='s/\([`"$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution that turns a string into a regex matching for the # string literally. sed_make_literal_regex='s,[].[^$\\*\/],\\&,g' # Sed substitution that converts a w32 file name or path # which contains forward slashes, into one that contains # (escaped) backslashes. A very naive implementation. lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' # Re-`\' parameter expansions in output of double_quote_subst that were # `\'-ed in input to the same. If an odd number of `\' preceded a '$' # in input to double_quote_subst, that '$' was protected from expansion. # Since each input `\' is now two `\'s, look for any number of runs of # four `\'s followed by two `\'s and then a '$'. `\' that '$'. bs='\\' bs2='\\\\' bs4='\\\\\\\\' dollar='\$' sed_double_backslash="\ s/$bs4/&\\ /g s/^$bs2$dollar/$bs&/ s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g s/\n//g" # Standard options: opt_dry_run=false opt_help=false opt_quiet=false opt_verbose=false opt_warning=: # func_echo arg... # Echo program name prefixed message, along with the current mode # name if it has been set yet. func_echo () { $ECHO "$progname: ${opt_mode+$opt_mode: }$*" } # func_verbose arg... # Echo program name prefixed message in verbose mode only. func_verbose () { $opt_verbose && func_echo ${1+"$@"} # A bug in bash halts the script if the last line of a function # fails when set -e is in force, so we need another command to # work around that: : } # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } # func_error arg... # Echo program name prefixed message to standard error. func_error () { $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2 } # func_warning arg... # Echo program name prefixed warning message to standard error. func_warning () { $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2 # bash bug again: : } # func_fatal_error arg... # Echo program name prefixed message to standard error, and exit. func_fatal_error () { func_error ${1+"$@"} exit $EXIT_FAILURE } # func_fatal_help arg... # Echo program name prefixed message to standard error, followed by # a help hint, and exit. func_fatal_help () { func_error ${1+"$@"} func_fatal_error "$help" } help="Try \`$progname --help' for more information." ## default # func_grep expression filename # Check whether EXPRESSION matches any line of FILENAME, without output. func_grep () { $GREP "$1" "$2" >/dev/null 2>&1 } # func_mkdir_p directory-path # Make sure the entire path to DIRECTORY-PATH is available. func_mkdir_p () { my_directory_path="$1" my_dir_list= if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then # Protect directory names starting with `-' case $my_directory_path in -*) my_directory_path="./$my_directory_path" ;; esac # While some portion of DIR does not yet exist... while test ! -d "$my_directory_path"; do # ...make a list in topmost first order. Use a colon delimited # list incase some portion of path contains whitespace. my_dir_list="$my_directory_path:$my_dir_list" # If the last portion added has no slash in it, the list is done case $my_directory_path in */*) ;; *) break ;; esac # ...otherwise throw away the child directory and loop my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"` done my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'` save_mkdir_p_IFS="$IFS"; IFS=':' for my_dir in $my_dir_list; do IFS="$save_mkdir_p_IFS" # mkdir can fail with a `File exist' error if two processes # try to create one of the directories concurrently. Don't # stop in that case! $MKDIR "$my_dir" 2>/dev/null || : done IFS="$save_mkdir_p_IFS" # Bail out if we (or some other process) failed to create a directory. test -d "$my_directory_path" || \ func_fatal_error "Failed to create \`$1'" fi } # func_mktempdir [string] # Make a temporary directory that won't clash with other running # libtool processes, and avoids race conditions if possible. If # given, STRING is the basename for that directory. func_mktempdir () { my_template="${TMPDIR-/tmp}/${1-$progname}" if test "$opt_dry_run" = ":"; then # Return a directory name, but don't create it in dry-run mode my_tmpdir="${my_template}-$$" else # If mktemp works, use that first and foremost my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` if test ! -d "$my_tmpdir"; then # Failing that, at least try and use $RANDOM to avoid a race my_tmpdir="${my_template}-${RANDOM-0}$$" save_mktempdir_umask=`umask` umask 0077 $MKDIR "$my_tmpdir" umask $save_mktempdir_umask fi # If we're not in dry-run mode, bomb out on failure test -d "$my_tmpdir" || \ func_fatal_error "cannot create temporary directory \`$my_tmpdir'" fi $ECHO "$my_tmpdir" } # func_quote_for_eval arg # Aesthetically quote ARG to be evaled later. # This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT # is double-quoted, suitable for a subsequent eval, whereas # FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters # which are still active within double quotes backslashified. func_quote_for_eval () { case $1 in *[\\\`\"\$]*) func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;; *) func_quote_for_eval_unquoted_result="$1" ;; esac case $func_quote_for_eval_unquoted_result in # Double-quote args containing shell metacharacters to delay # word splitting, command substitution and and variable # expansion for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" ;; *) func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" esac } # func_quote_for_expand arg # Aesthetically quote ARG to be evaled later; same as above, # but do not quote variable references. func_quote_for_expand () { case $1 in *[\\\`\"]*) my_arg=`$ECHO "$1" | $SED \ -e "$double_quote_subst" -e "$sed_double_backslash"` ;; *) my_arg="$1" ;; esac case $my_arg in # Double-quote args containing shell metacharacters to delay # word splitting and command substitution for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") my_arg="\"$my_arg\"" ;; esac func_quote_for_expand_result="$my_arg" } # func_show_eval cmd [fail_exp] # Unless opt_silent is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. func_show_eval () { my_cmd="$1" my_fail_exp="${2-:}" ${opt_silent-false} || { func_quote_for_expand "$my_cmd" eval "func_echo $func_quote_for_expand_result" } if ${opt_dry_run-false}; then :; else eval "$my_cmd" my_status=$? if test "$my_status" -eq 0; then :; else eval "(exit $my_status); $my_fail_exp" fi fi } # func_show_eval_locale cmd [fail_exp] # Unless opt_silent is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. Use the saved locale for evaluation. func_show_eval_locale () { my_cmd="$1" my_fail_exp="${2-:}" ${opt_silent-false} || { func_quote_for_expand "$my_cmd" eval "func_echo $func_quote_for_expand_result" } if ${opt_dry_run-false}; then :; else eval "$lt_user_locale $my_cmd" my_status=$? eval "$lt_safe_locale" if test "$my_status" -eq 0; then :; else eval "(exit $my_status); $my_fail_exp" fi fi } # func_tr_sh # Turn $1 into a string suitable for a shell variable name. # Result is stored in $func_tr_sh_result. All characters # not in the set a-zA-Z0-9_ are replaced with '_'. Further, # if $1 begins with a digit, a '_' is prepended as well. func_tr_sh () { case $1 in [0-9]* | *[!a-zA-Z0-9_]*) func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'` ;; * ) func_tr_sh_result=$1 ;; esac } # func_version # Echo version message to standard output and exit. func_version () { $opt_debug $SED -n '/(C)/!b go :more /\./!{ N s/\n# / / b more } :go /^# '$PROGRAM' (GNU /,/# warranty; / { s/^# // s/^# *$// s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/ p }' < "$progpath" exit $? } # func_usage # Echo short help message to standard output and exit. func_usage () { $opt_debug $SED -n '/^# Usage:/,/^# *.*--help/ { s/^# // s/^# *$// s/\$progname/'$progname'/ p }' < "$progpath" echo $ECHO "run \`$progname --help | more' for full usage" exit $? } # func_help [NOEXIT] # Echo long help message to standard output and exit, # unless 'noexit' is passed as argument. func_help () { $opt_debug $SED -n '/^# Usage:/,/# Report bugs to/ { :print s/^# // s/^# *$// s*\$progname*'$progname'* s*\$host*'"$host"'* s*\$SHELL*'"$SHELL"'* s*\$LTCC*'"$LTCC"'* s*\$LTCFLAGS*'"$LTCFLAGS"'* s*\$LD*'"$LD"'* s/\$with_gnu_ld/'"$with_gnu_ld"'/ s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/ s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/ p d } /^# .* home page:/b print /^# General help using/b print ' < "$progpath" ret=$? if test -z "$1"; then exit $ret fi } # func_missing_arg argname # Echo program name prefixed message to standard error and set global # exit_cmd. func_missing_arg () { $opt_debug func_error "missing argument for $1." exit_cmd=exit } # func_split_short_opt shortopt # Set func_split_short_opt_name and func_split_short_opt_arg shell # variables after splitting SHORTOPT after the 2nd character. func_split_short_opt () { my_sed_short_opt='1s/^\(..\).*$/\1/;q' my_sed_short_rest='1s/^..\(.*\)$/\1/;q' func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"` func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"` } # func_split_short_opt may be replaced by extended shell implementation # func_split_long_opt longopt # Set func_split_long_opt_name and func_split_long_opt_arg shell # variables after splitting LONGOPT at the `=' sign. func_split_long_opt () { my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q' my_sed_long_arg='1s/^--[^=]*=//' func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"` func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"` } # func_split_long_opt may be replaced by extended shell implementation exit_cmd=: magic="%%%MAGIC variable%%%" magic_exe="%%%MAGIC EXE variable%%%" # Global variables. nonopt= preserve_args= lo2o="s/\\.lo\$/.${objext}/" o2lo="s/\\.${objext}\$/.lo/" extracted_archives= extracted_serial=0 # If this variable is set in any of the actions, the command in it # will be execed at the end. This prevents here-documents from being # left over by shells. exec_cmd= # func_append var value # Append VALUE to the end of shell variable VAR. func_append () { eval "${1}=\$${1}\${2}" } # func_append may be replaced by extended shell implementation # func_append_quoted var value # Quote VALUE and append to the end of shell variable VAR, separated # by a space. func_append_quoted () { func_quote_for_eval "${2}" eval "${1}=\$${1}\\ \$func_quote_for_eval_result" } # func_append_quoted may be replaced by extended shell implementation # func_arith arithmetic-term... func_arith () { func_arith_result=`expr "${@}"` } # func_arith may be replaced by extended shell implementation # func_len string # STRING may not start with a hyphen. func_len () { func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len` } # func_len may be replaced by extended shell implementation # func_lo2o object func_lo2o () { func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"` } # func_lo2o may be replaced by extended shell implementation # func_xform libobj-or-source func_xform () { func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'` } # func_xform may be replaced by extended shell implementation # func_fatal_configuration arg... # Echo program name prefixed message to standard error, followed by # a configuration failure hint, and exit. func_fatal_configuration () { func_error ${1+"$@"} func_error "See the $PACKAGE documentation for more information." func_fatal_error "Fatal configuration error." } # func_config # Display the configuration for all the tags in this script. func_config () { re_begincf='^# ### BEGIN LIBTOOL' re_endcf='^# ### END LIBTOOL' # Default configuration. $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" # Now print the configurations for the tags. for tagname in $taglist; do $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" done exit $? } # func_features # Display the features supported by this script. func_features () { echo "host: $host" if test "$build_libtool_libs" = yes; then echo "enable shared libraries" else echo "disable shared libraries" fi if test "$build_old_libs" = yes; then echo "enable static libraries" else echo "disable static libraries" fi exit $? } # func_enable_tag tagname # Verify that TAGNAME is valid, and either flag an error and exit, or # enable the TAGNAME tag. We also add TAGNAME to the global $taglist # variable here. func_enable_tag () { # Global variable: tagname="$1" re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" sed_extractcf="/$re_begincf/,/$re_endcf/p" # Validate tagname. case $tagname in *[!-_A-Za-z0-9,/]*) func_fatal_error "invalid tag name: $tagname" ;; esac # Don't test for the "default" C tag, as we know it's # there but not specially marked. case $tagname in CC) ;; *) if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then taglist="$taglist $tagname" # Evaluate the configuration. Be careful to quote the path # and the sed script, to avoid splitting on whitespace, but # also don't use non-portable quotes within backquotes within # quotes we have to do it in 2 steps: extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` eval "$extractedcf" else func_error "ignoring unknown tag $tagname" fi ;; esac } # func_check_version_match # Ensure that we are using m4 macros, and libtool script from the same # release of libtool. func_check_version_match () { if test "$package_revision" != "$macro_revision"; then if test "$VERSION" != "$macro_version"; then if test -z "$macro_version"; then cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from an older release. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from $PACKAGE $macro_version. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF fi else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, $progname: but the definition of this LT_INIT comes from revision $macro_revision. $progname: You should recreate aclocal.m4 with macros from revision $package_revision $progname: of $PACKAGE $VERSION and run autoconf again. _LT_EOF fi exit $EXIT_MISMATCH fi } # Shorthand for --mode=foo, only valid as the first argument case $1 in clean|clea|cle|cl) shift; set dummy --mode clean ${1+"$@"}; shift ;; compile|compil|compi|comp|com|co|c) shift; set dummy --mode compile ${1+"$@"}; shift ;; execute|execut|execu|exec|exe|ex|e) shift; set dummy --mode execute ${1+"$@"}; shift ;; finish|finis|fini|fin|fi|f) shift; set dummy --mode finish ${1+"$@"}; shift ;; install|instal|insta|inst|ins|in|i) shift; set dummy --mode install ${1+"$@"}; shift ;; link|lin|li|l) shift; set dummy --mode link ${1+"$@"}; shift ;; uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) shift; set dummy --mode uninstall ${1+"$@"}; shift ;; esac # Option defaults: opt_debug=: opt_dry_run=false opt_config=false opt_preserve_dup_deps=false opt_features=false opt_finish=false opt_help=false opt_help_all=false opt_silent=: opt_warning=: opt_verbose=: opt_silent=false opt_verbose=false # Parse options once, thoroughly. This comes as soon as possible in the # script to make things like `--version' happen as quickly as we can. { # this just eases exit handling while test $# -gt 0; do opt="$1" shift case $opt in --debug|-x) opt_debug='set -x' func_echo "enabling shell trace mode" $opt_debug ;; --dry-run|--dryrun|-n) opt_dry_run=: ;; --config) opt_config=: func_config ;; --dlopen|-dlopen) optarg="$1" opt_dlopen="${opt_dlopen+$opt_dlopen }$optarg" shift ;; --preserve-dup-deps) opt_preserve_dup_deps=: ;; --features) opt_features=: func_features ;; --finish) opt_finish=: set dummy --mode finish ${1+"$@"}; shift ;; --help) opt_help=: ;; --help-all) opt_help_all=: opt_help=': help-all' ;; --mode) test $# = 0 && func_missing_arg $opt && break optarg="$1" opt_mode="$optarg" case $optarg in # Valid mode arguments: clean|compile|execute|finish|install|link|relink|uninstall) ;; # Catch anything else as an error *) func_error "invalid argument for $opt" exit_cmd=exit break ;; esac shift ;; --no-silent|--no-quiet) opt_silent=false func_append preserve_args " $opt" ;; --no-warning|--no-warn) opt_warning=false func_append preserve_args " $opt" ;; --no-verbose) opt_verbose=false func_append preserve_args " $opt" ;; --silent|--quiet) opt_silent=: func_append preserve_args " $opt" opt_verbose=false ;; --verbose|-v) opt_verbose=: func_append preserve_args " $opt" opt_silent=false ;; --tag) test $# = 0 && func_missing_arg $opt && break optarg="$1" opt_tag="$optarg" func_append preserve_args " $opt $optarg" func_enable_tag "$optarg" shift ;; -\?|-h) func_usage ;; --help) func_help ;; --version) func_version ;; # Separate optargs to long options: --*=*) func_split_long_opt "$opt" set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"} shift ;; # Separate non-argument short options: -\?*|-h*|-n*|-v*) func_split_short_opt "$opt" set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"} shift ;; --) break ;; -*) func_fatal_help "unrecognized option \`$opt'" ;; *) set dummy "$opt" ${1+"$@"}; shift; break ;; esac done # Validate options: # save first non-option argument if test "$#" -gt 0; then nonopt="$opt" shift fi # preserve --debug test "$opt_debug" = : || func_append preserve_args " --debug" case $host in *cygwin* | *mingw* | *pw32* | *cegcc*) # don't eliminate duplications in $postdeps and $predeps opt_duplicate_compiler_generated_deps=: ;; *) opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps ;; esac $opt_help || { # Sanity checks first: func_check_version_match if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then func_fatal_configuration "not configured to build any kind of library" fi # Darwin sucks eval std_shrext=\"$shrext_cmds\" # Only execute mode is allowed to have -dlopen flags. if test -n "$opt_dlopen" && test "$opt_mode" != execute; then func_error "unrecognized option \`-dlopen'" $ECHO "$help" 1>&2 exit $EXIT_FAILURE fi # Change the help message to a mode-specific one. generic_help="$help" help="Try \`$progname --help --mode=$opt_mode' for more information." } # Bail if the options were screwed $exit_cmd $EXIT_FAILURE } ## ----------- ## ## Main. ## ## ----------- ## # func_lalib_p file # True iff FILE is a libtool `.la' library or `.lo' object file. # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_lalib_p () { test -f "$1" && $SED -e 4q "$1" 2>/dev/null \ | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 } # func_lalib_unsafe_p file # True iff FILE is a libtool `.la' library or `.lo' object file. # This function implements the same check as func_lalib_p without # resorting to external programs. To this end, it redirects stdin and # closes it afterwards, without saving the original file descriptor. # As a safety measure, use it only where a negative result would be # fatal anyway. Works if `file' does not exist. func_lalib_unsafe_p () { lalib_p=no if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then for lalib_p_l in 1 2 3 4 do read lalib_p_line case "$lalib_p_line" in \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; esac done exec 0<&5 5<&- fi test "$lalib_p" = yes } # func_ltwrapper_script_p file # True iff FILE is a libtool wrapper script # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_script_p () { func_lalib_p "$1" } # func_ltwrapper_executable_p file # True iff FILE is a libtool wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_executable_p () { func_ltwrapper_exec_suffix= case $1 in *.exe) ;; *) func_ltwrapper_exec_suffix=.exe ;; esac $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 } # func_ltwrapper_scriptname file # Assumes file is an ltwrapper_executable # uses $file to determine the appropriate filename for a # temporary ltwrapper_script. func_ltwrapper_scriptname () { func_dirname_and_basename "$1" "" "." func_stripname '' '.exe' "$func_basename_result" func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" } # func_ltwrapper_p file # True iff FILE is a libtool wrapper script or wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_p () { func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" } # func_execute_cmds commands fail_cmd # Execute tilde-delimited COMMANDS. # If FAIL_CMD is given, eval that upon failure. # FAIL_CMD may read-access the current command in variable CMD! func_execute_cmds () { $opt_debug save_ifs=$IFS; IFS='~' for cmd in $1; do IFS=$save_ifs eval cmd=\"$cmd\" func_show_eval "$cmd" "${2-:}" done IFS=$save_ifs } # func_source file # Source FILE, adding directory component if necessary. # Note that it is not necessary on cygwin/mingw to append a dot to # FILE even if both FILE and FILE.exe exist: automatic-append-.exe # behavior happens only for exec(3), not for open(2)! Also, sourcing # `FILE.' does not work on cygwin managed mounts. func_source () { $opt_debug case $1 in */* | *\\*) . "$1" ;; *) . "./$1" ;; esac } # func_resolve_sysroot PATH # Replace a leading = in PATH with a sysroot. Store the result into # func_resolve_sysroot_result func_resolve_sysroot () { func_resolve_sysroot_result=$1 case $func_resolve_sysroot_result in =*) func_stripname '=' '' "$func_resolve_sysroot_result" func_resolve_sysroot_result=$lt_sysroot$func_stripname_result ;; esac } # func_replace_sysroot PATH # If PATH begins with the sysroot, replace it with = and # store the result into func_replace_sysroot_result. func_replace_sysroot () { case "$lt_sysroot:$1" in ?*:"$lt_sysroot"*) func_stripname "$lt_sysroot" '' "$1" func_replace_sysroot_result="=$func_stripname_result" ;; *) # Including no sysroot. func_replace_sysroot_result=$1 ;; esac } # func_infer_tag arg # Infer tagged configuration to use if any are available and # if one wasn't chosen via the "--tag" command line option. # Only attempt this if the compiler in the base compile # command doesn't match the default compiler. # arg is usually of the form 'gcc ...' func_infer_tag () { $opt_debug if test -n "$available_tags" && test -z "$tagname"; then CC_quoted= for arg in $CC; do func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case $@ in # Blanks in the command may have been stripped by the calling shell, # but not from the CC environment variable when configure was run. " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; # Blanks at the start of $base_compile will cause this to fail # if we don't check for them as well. *) for z in $available_tags; do if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then # Evaluate the configuration. eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" CC_quoted= for arg in $CC; do # Double-quote args containing other shell metacharacters. func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case "$@ " in " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) # The compiler in the base compile command matches # the one in the tagged configuration. # Assume this is the tagged configuration we want. tagname=$z break ;; esac fi done # If $tagname still isn't set, then no tagged configuration # was found and let the user know that the "--tag" command # line option must be used. if test -z "$tagname"; then func_echo "unable to infer tagged configuration" func_fatal_error "specify a tag with \`--tag'" # else # func_verbose "using $tagname tagged configuration" fi ;; esac fi } # func_write_libtool_object output_name pic_name nonpic_name # Create a libtool object file (analogous to a ".la" file), # but don't create it if we're doing a dry run. func_write_libtool_object () { write_libobj=${1} if test "$build_libtool_libs" = yes; then write_lobj=\'${2}\' else write_lobj=none fi if test "$build_old_libs" = yes; then write_oldobj=\'${3}\' else write_oldobj=none fi $opt_dry_run || { cat >${write_libobj}T </dev/null` if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | $SED -e "$lt_sed_naive_backslashify"` else func_convert_core_file_wine_to_w32_result= fi fi } # end: func_convert_core_file_wine_to_w32 # func_convert_core_path_wine_to_w32 ARG # Helper function used by path conversion functions when $build is *nix, and # $host is mingw, cygwin, or some other w32 environment. Relies on a correctly # configured wine environment available, with the winepath program in $build's # $PATH. Assumes ARG has no leading or trailing path separator characters. # # ARG is path to be converted from $build format to win32. # Result is available in $func_convert_core_path_wine_to_w32_result. # Unconvertible file (directory) names in ARG are skipped; if no directory names # are convertible, then the result may be empty. func_convert_core_path_wine_to_w32 () { $opt_debug # unfortunately, winepath doesn't convert paths, only file names func_convert_core_path_wine_to_w32_result="" if test -n "$1"; then oldIFS=$IFS IFS=: for func_convert_core_path_wine_to_w32_f in $1; do IFS=$oldIFS func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" if test -n "$func_convert_core_file_wine_to_w32_result" ; then if test -z "$func_convert_core_path_wine_to_w32_result"; then func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result" else func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" fi fi done IFS=$oldIFS fi } # end: func_convert_core_path_wine_to_w32 # func_cygpath ARGS... # Wrapper around calling the cygpath program via LT_CYGPATH. This is used when # when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) # $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or # (2), returns the Cygwin file name or path in func_cygpath_result (input # file name or path is assumed to be in w32 format, as previously converted # from $build's *nix or MSYS format). In case (3), returns the w32 file name # or path in func_cygpath_result (input file name or path is assumed to be in # Cygwin format). Returns an empty string on error. # # ARGS are passed to cygpath, with the last one being the file name or path to # be converted. # # Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH # environment variable; do not put it in $PATH. func_cygpath () { $opt_debug if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` if test "$?" -ne 0; then # on failure, ensure result is empty func_cygpath_result= fi else func_cygpath_result= func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'" fi } #end: func_cygpath # func_convert_core_msys_to_w32 ARG # Convert file name or path ARG from MSYS format to w32 format. Return # result in func_convert_core_msys_to_w32_result. func_convert_core_msys_to_w32 () { $opt_debug # awkward: cmd appends spaces to result func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"` } #end: func_convert_core_msys_to_w32 # func_convert_file_check ARG1 ARG2 # Verify that ARG1 (a file name in $build format) was converted to $host # format in ARG2. Otherwise, emit an error message, but continue (resetting # func_to_host_file_result to ARG1). func_convert_file_check () { $opt_debug if test -z "$2" && test -n "$1" ; then func_error "Could not determine host file name corresponding to" func_error " \`$1'" func_error "Continuing, but uninstalled executables may not work." # Fallback: func_to_host_file_result="$1" fi } # end func_convert_file_check # func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH # Verify that FROM_PATH (a path in $build format) was converted to $host # format in TO_PATH. Otherwise, emit an error message, but continue, resetting # func_to_host_file_result to a simplistic fallback value (see below). func_convert_path_check () { $opt_debug if test -z "$4" && test -n "$3"; then func_error "Could not determine the host path corresponding to" func_error " \`$3'" func_error "Continuing, but uninstalled executables may not work." # Fallback. This is a deliberately simplistic "conversion" and # should not be "improved". See libtool.info. if test "x$1" != "x$2"; then lt_replace_pathsep_chars="s|$1|$2|g" func_to_host_path_result=`echo "$3" | $SED -e "$lt_replace_pathsep_chars"` else func_to_host_path_result="$3" fi fi } # end func_convert_path_check # func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG # Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT # and appending REPL if ORIG matches BACKPAT. func_convert_path_front_back_pathsep () { $opt_debug case $4 in $1 ) func_to_host_path_result="$3$func_to_host_path_result" ;; esac case $4 in $2 ) func_append func_to_host_path_result "$3" ;; esac } # end func_convert_path_front_back_pathsep ################################################## # $build to $host FILE NAME CONVERSION FUNCTIONS # ################################################## # invoked via `$to_host_file_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # Result will be available in $func_to_host_file_result. # func_to_host_file ARG # Converts the file name ARG from $build format to $host format. Return result # in func_to_host_file_result. func_to_host_file () { $opt_debug $to_host_file_cmd "$1" } # end func_to_host_file # func_to_tool_file ARG LAZY # converts the file name ARG from $build format to toolchain format. Return # result in func_to_tool_file_result. If the conversion in use is listed # in (the comma separated) LAZY, no conversion takes place. func_to_tool_file () { $opt_debug case ,$2, in *,"$to_tool_file_cmd",*) func_to_tool_file_result=$1 ;; *) $to_tool_file_cmd "$1" func_to_tool_file_result=$func_to_host_file_result ;; esac } # end func_to_tool_file # func_convert_file_noop ARG # Copy ARG to func_to_host_file_result. func_convert_file_noop () { func_to_host_file_result="$1" } # end func_convert_file_noop # func_convert_file_msys_to_w32 ARG # Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_file_result. func_convert_file_msys_to_w32 () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_to_host_file_result="$func_convert_core_msys_to_w32_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_w32 # func_convert_file_cygwin_to_w32 ARG # Convert file name ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_file_cygwin_to_w32 () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then # because $build is cygwin, we call "the" cygpath in $PATH; no need to use # LT_CYGPATH in this case. func_to_host_file_result=`cygpath -m "$1"` fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_cygwin_to_w32 # func_convert_file_nix_to_w32 ARG # Convert file name ARG from *nix to w32 format. Requires a wine environment # and a working winepath. Returns result in func_to_host_file_result. func_convert_file_nix_to_w32 () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then func_convert_core_file_wine_to_w32 "$1" func_to_host_file_result="$func_convert_core_file_wine_to_w32_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_w32 # func_convert_file_msys_to_cygwin ARG # Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_file_msys_to_cygwin () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_cygpath -u "$func_convert_core_msys_to_w32_result" func_to_host_file_result="$func_cygpath_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_cygwin # func_convert_file_nix_to_cygwin ARG # Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed # in a wine environment, working winepath, and LT_CYGPATH set. Returns result # in func_to_host_file_result. func_convert_file_nix_to_cygwin () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. func_convert_core_file_wine_to_w32 "$1" func_cygpath -u "$func_convert_core_file_wine_to_w32_result" func_to_host_file_result="$func_cygpath_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_cygwin ############################################# # $build to $host PATH CONVERSION FUNCTIONS # ############################################# # invoked via `$to_host_path_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # The result will be available in $func_to_host_path_result. # # Path separators are also converted from $build format to $host format. If # ARG begins or ends with a path separator character, it is preserved (but # converted to $host format) on output. # # All path conversion functions are named using the following convention: # file name conversion function : func_convert_file_X_to_Y () # path conversion function : func_convert_path_X_to_Y () # where, for any given $build/$host combination the 'X_to_Y' value is the # same. If conversion functions are added for new $build/$host combinations, # the two new functions must follow this pattern, or func_init_to_host_path_cmd # will break. # func_init_to_host_path_cmd # Ensures that function "pointer" variable $to_host_path_cmd is set to the # appropriate value, based on the value of $to_host_file_cmd. to_host_path_cmd= func_init_to_host_path_cmd () { $opt_debug if test -z "$to_host_path_cmd"; then func_stripname 'func_convert_file_' '' "$to_host_file_cmd" to_host_path_cmd="func_convert_path_${func_stripname_result}" fi } # func_to_host_path ARG # Converts the path ARG from $build format to $host format. Return result # in func_to_host_path_result. func_to_host_path () { $opt_debug func_init_to_host_path_cmd $to_host_path_cmd "$1" } # end func_to_host_path # func_convert_path_noop ARG # Copy ARG to func_to_host_path_result. func_convert_path_noop () { func_to_host_path_result="$1" } # end func_convert_path_noop # func_convert_path_msys_to_w32 ARG # Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_path_result. func_convert_path_msys_to_w32 () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # Remove leading and trailing path separator characters from ARG. MSYS # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; # and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result="$func_convert_core_msys_to_w32_result" func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_msys_to_w32 # func_convert_path_cygwin_to_w32 ARG # Convert path ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_path_cygwin_to_w32 () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_cygwin_to_w32 # func_convert_path_nix_to_w32 ARG # Convert path ARG from *nix to w32 format. Requires a wine environment and # a working winepath. Returns result in func_to_host_file_result. func_convert_path_nix_to_w32 () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result="$func_convert_core_path_wine_to_w32_result" func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_nix_to_w32 # func_convert_path_msys_to_cygwin ARG # Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_path_msys_to_cygwin () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_msys_to_w32_result" func_to_host_path_result="$func_cygpath_result" func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_msys_to_cygwin # func_convert_path_nix_to_cygwin ARG # Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a # a wine environment, working winepath, and LT_CYGPATH set. Returns result in # func_to_host_file_result. func_convert_path_nix_to_cygwin () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # Remove leading and trailing path separator characters from # ARG. msys behavior is inconsistent here, cygpath turns them # into '.;' and ';.', and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" func_to_host_path_result="$func_cygpath_result" func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_nix_to_cygwin # func_mode_compile arg... func_mode_compile () { $opt_debug # Get the compilation command and the source file. base_compile= srcfile="$nonopt" # always keep a non-empty value in "srcfile" suppress_opt=yes suppress_output= arg_mode=normal libobj= later= pie_flag= for arg do case $arg_mode in arg ) # do not "continue". Instead, add this to base_compile lastarg="$arg" arg_mode=normal ;; target ) libobj="$arg" arg_mode=normal continue ;; normal ) # Accept any command-line options. case $arg in -o) test -n "$libobj" && \ func_fatal_error "you cannot specify \`-o' more than once" arg_mode=target continue ;; -pie | -fpie | -fPIE) func_append pie_flag " $arg" continue ;; -shared | -static | -prefer-pic | -prefer-non-pic) func_append later " $arg" continue ;; -no-suppress) suppress_opt=no continue ;; -Xcompiler) arg_mode=arg # the next one goes into the "base_compile" arg list continue # The current "srcfile" will either be retained or ;; # replaced later. I would guess that would be a bug. -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result lastarg= save_ifs="$IFS"; IFS=',' for arg in $args; do IFS="$save_ifs" func_append_quoted lastarg "$arg" done IFS="$save_ifs" func_stripname ' ' '' "$lastarg" lastarg=$func_stripname_result # Add the arguments to base_compile. func_append base_compile " $lastarg" continue ;; *) # Accept the current argument as the source file. # The previous "srcfile" becomes the current argument. # lastarg="$srcfile" srcfile="$arg" ;; esac # case $arg ;; esac # case $arg_mode # Aesthetically quote the previous argument. func_append_quoted base_compile "$lastarg" done # for arg case $arg_mode in arg) func_fatal_error "you must specify an argument for -Xcompile" ;; target) func_fatal_error "you must specify a target with \`-o'" ;; *) # Get the name of the library object. test -z "$libobj" && { func_basename "$srcfile" libobj="$func_basename_result" } ;; esac # Recognize several different file suffixes. # If the user specifies -o file.o, it is replaced with file.lo case $libobj in *.[cCFSifmso] | \ *.ada | *.adb | *.ads | *.asm | \ *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) func_xform "$libobj" libobj=$func_xform_result ;; esac case $libobj in *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; *) func_fatal_error "cannot determine name of library object from \`$libobj'" ;; esac func_infer_tag $base_compile for arg in $later; do case $arg in -shared) test "$build_libtool_libs" != yes && \ func_fatal_configuration "can not build a shared library" build_old_libs=no continue ;; -static) build_libtool_libs=no build_old_libs=yes continue ;; -prefer-pic) pic_mode=yes continue ;; -prefer-non-pic) pic_mode=no continue ;; esac done func_quote_for_eval "$libobj" test "X$libobj" != "X$func_quote_for_eval_result" \ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ && func_warning "libobj name \`$libobj' may not contain shell special characters." func_dirname_and_basename "$obj" "/" "" objname="$func_basename_result" xdir="$func_dirname_result" lobj=${xdir}$objdir/$objname test -z "$base_compile" && \ func_fatal_help "you must specify a compilation command" # Delete any leftover library objects. if test "$build_old_libs" = yes; then removelist="$obj $lobj $libobj ${libobj}T" else removelist="$lobj $libobj ${libobj}T" fi # On Cygwin there's no "real" PIC flag so we must build both object types case $host_os in cygwin* | mingw* | pw32* | os2* | cegcc*) pic_mode=default ;; esac if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then # non-PIC code in shared libraries is not supported pic_mode=default fi # Calculate the filename of the output object if compiler does # not support -o with -c if test "$compiler_c_o" = no; then output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext} lockfile="$output_obj.lock" else output_obj= need_locks=no lockfile= fi # Lock this critical section if it is needed # We use this script file to make the link, it avoids creating a new file if test "$need_locks" = yes; then until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done elif test "$need_locks" = warn; then if test -f "$lockfile"; then $ECHO "\ *** ERROR, $lockfile exists and contains: `cat $lockfile 2>/dev/null` This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi func_append removelist " $output_obj" $ECHO "$srcfile" > "$lockfile" fi $opt_dry_run || $RM $removelist func_append removelist " $lockfile" trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 srcfile=$func_to_tool_file_result func_quote_for_eval "$srcfile" qsrcfile=$func_quote_for_eval_result # Only build a PIC object if we are building libtool libraries. if test "$build_libtool_libs" = yes; then # Without this assignment, base_compile gets emptied. fbsd_hideous_sh_bug=$base_compile if test "$pic_mode" != no; then command="$base_compile $qsrcfile $pic_flag" else # Don't build PIC code command="$base_compile $qsrcfile" fi func_mkdir_p "$xdir$objdir" if test -z "$output_obj"; then # Place PIC objects in $objdir func_append command " -o $lobj" fi func_show_eval_locale "$command" \ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' if test "$need_locks" = warn && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed, then go on to compile the next one if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then func_show_eval '$MV "$output_obj" "$lobj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi # Allow error messages only from the first compilation. if test "$suppress_opt" = yes; then suppress_output=' >/dev/null 2>&1' fi fi # Only build a position-dependent object if we build old libraries. if test "$build_old_libs" = yes; then if test "$pic_mode" != yes; then # Don't build PIC code command="$base_compile $qsrcfile$pie_flag" else command="$base_compile $qsrcfile $pic_flag" fi if test "$compiler_c_o" = yes; then func_append command " -o $obj" fi # Suppress compiler output if we already did a PIC compilation. func_append command "$suppress_output" func_show_eval_locale "$command" \ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' if test "$need_locks" = warn && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then func_show_eval '$MV "$output_obj" "$obj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi fi $opt_dry_run || { func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" # Unlock the critical section if it was locked if test "$need_locks" != no; then removelist=$lockfile $RM "$lockfile" fi } exit $EXIT_SUCCESS } $opt_help || { test "$opt_mode" = compile && func_mode_compile ${1+"$@"} } func_mode_help () { # We need to display help for each of the modes. case $opt_mode in "") # Generic help is extracted from the usage comments # at the start of this file. func_help ;; clean) $ECHO \ "Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... Remove files from the build directory. RM is the name of the program to use to delete files associated with each FILE (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed to RM. If FILE is a libtool library, object or program, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; compile) $ECHO \ "Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE Compile a source file into a libtool library object. This mode accepts the following additional options: -o OUTPUT-FILE set the output file name to OUTPUT-FILE -no-suppress do not suppress compiler output for multiple passes -prefer-pic try to build PIC objects only -prefer-non-pic try to build non-PIC objects only -shared do not build a \`.o' file suitable for static linking -static only build a \`.o' file suitable for static linking -Wc,FLAG pass FLAG directly to the compiler COMPILE-COMMAND is a command to be used in creating a \`standard' object file from the given SOURCEFILE. The output file name is determined by removing the directory component from SOURCEFILE, then substituting the C source code suffix \`.c' with the library object suffix, \`.lo'." ;; execute) $ECHO \ "Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... Automatically set library path, then run a program. This mode accepts the following additional options: -dlopen FILE add the directory containing FILE to the library path This mode sets the library path environment variable according to \`-dlopen' flags. If any of the ARGS are libtool executable wrappers, then they are translated into their corresponding uninstalled binary, and any of their required library directories are added to the library path. Then, COMMAND is executed, with ARGS as arguments." ;; finish) $ECHO \ "Usage: $progname [OPTION]... --mode=finish [LIBDIR]... Complete the installation of libtool libraries. Each LIBDIR is a directory that contains libtool libraries. The commands that this mode executes may require superuser privileges. Use the \`--dry-run' option if you just want to see what would be executed." ;; install) $ECHO \ "Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... Install executables or libraries. INSTALL-COMMAND is the installation command. The first component should be either the \`install' or \`cp' program. The following components of INSTALL-COMMAND are treated specially: -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation The rest of the components are interpreted as arguments to that command (only BSD-compatible install options are recognized)." ;; link) $ECHO \ "Usage: $progname [OPTION]... --mode=link LINK-COMMAND... Link object files or libraries together to form another library, or to create an executable program. LINK-COMMAND is a command using the C compiler that you would use to create a program from several object files. The following components of LINK-COMMAND are treated specially: -all-static do not do any dynamic linking at all -avoid-version do not add a version suffix if possible -bindir BINDIR specify path to binaries directory (for systems where libraries must be found in the PATH setting at runtime) -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) -export-symbols SYMFILE try to export only the symbols listed in SYMFILE -export-symbols-regex REGEX try to export only the symbols matching REGEX -LLIBDIR search LIBDIR for required installed libraries -lNAME OUTPUT-FILE requires the installed library libNAME -module build a library that can dlopened -no-fast-install disable the fast-install mode -no-install link a not-installable executable -no-undefined declare that a library does not refer to external symbols -o OUTPUT-FILE create OUTPUT-FILE from the specified objects -objectlist FILE Use a list of object files found in FILE to specify objects -precious-files-regex REGEX don't remove output files matching REGEX -release RELEASE specify package release information -rpath LIBDIR the created library will eventually be installed in LIBDIR -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries -shared only do dynamic linking of libtool libraries -shrext SUFFIX override the standard shared library file extension -static do not do any dynamic linking of uninstalled libtool libraries -static-libtool-libs do not do any dynamic linking of libtool libraries -version-info CURRENT[:REVISION[:AGE]] specify library version info [each variable defaults to 0] -weak LIBNAME declare that the target provides the LIBNAME interface -Wc,FLAG -Xcompiler FLAG pass linker-specific FLAG directly to the compiler -Wl,FLAG -Xlinker FLAG pass linker-specific FLAG directly to the linker -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) All other options (arguments beginning with \`-') are ignored. Every other argument is treated as a filename. Files ending in \`.la' are treated as uninstalled libtool libraries, other files are standard or library object files. If the OUTPUT-FILE ends in \`.la', then a libtool library is created, only library objects (\`.lo' files) may be specified, and \`-rpath' is required, except when creating a convenience library. If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created using \`ar' and \`ranlib', or on Windows using \`lib'. If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file is created, otherwise an executable program is created." ;; uninstall) $ECHO \ "Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... Remove libraries from an installation directory. RM is the name of the program to use to delete files associated with each FILE (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed to RM. If FILE is a libtool library, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; *) func_fatal_help "invalid operation mode \`$opt_mode'" ;; esac echo $ECHO "Try \`$progname --help' for more information about other modes." } # Now that we've collected a possible --mode arg, show help if necessary if $opt_help; then if test "$opt_help" = :; then func_mode_help else { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do func_mode_help done } | sed -n '1p; 2,$s/^Usage:/ or: /p' { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do echo func_mode_help done } | sed '1d /^When reporting/,/^Report/{ H d } $x /information about other modes/d /more detailed .*MODE/d s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' fi exit $? fi # func_mode_execute arg... func_mode_execute () { $opt_debug # The first argument is the command name. cmd="$nonopt" test -z "$cmd" && \ func_fatal_help "you must specify a COMMAND" # Handle -dlopen flags immediately. for file in $opt_dlopen; do test -f "$file" \ || func_fatal_help "\`$file' is not a file" dir= case $file in *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "\`$lib' is not a valid libtool archive" # Read the libtool library. dlname= library_names= func_source "$file" # Skip this library if it cannot be dlopened. if test -z "$dlname"; then # Warn if it was a shared library. test -n "$library_names" && \ func_warning "\`$file' was not linked with \`-export-dynamic'" continue fi func_dirname "$file" "" "." dir="$func_dirname_result" if test -f "$dir/$objdir/$dlname"; then func_append dir "/$objdir" else if test ! -f "$dir/$dlname"; then func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" fi fi ;; *.lo) # Just add the directory containing the .lo file. func_dirname "$file" "" "." dir="$func_dirname_result" ;; *) func_warning "\`-dlopen' is ignored for non-libtool libraries and objects" continue ;; esac # Get the absolute pathname. absdir=`cd "$dir" && pwd` test -n "$absdir" && dir="$absdir" # Now add the directory to shlibpath_var. if eval "test -z \"\$$shlibpath_var\""; then eval "$shlibpath_var=\"\$dir\"" else eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" fi done # This variable tells wrapper scripts just to set shlibpath_var # rather than running their programs. libtool_execute_magic="$magic" # Check if any of the arguments is a wrapper script. args= for file do case $file in -* | *.la | *.lo ) ;; *) # Do a test to see if this is really a libtool program. if func_ltwrapper_script_p "$file"; then func_source "$file" # Transform arg to wrapped name. file="$progdir/$program" elif func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" func_source "$func_ltwrapper_scriptname_result" # Transform arg to wrapped name. file="$progdir/$program" fi ;; esac # Quote arguments (to preserve shell metacharacters). func_append_quoted args "$file" done if test "X$opt_dry_run" = Xfalse; then if test -n "$shlibpath_var"; then # Export the shlibpath_var. eval "export $shlibpath_var" fi # Restore saved environment variables for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${save_$lt_var+set}\" = set; then $lt_var=\$save_$lt_var; export $lt_var else $lt_unset $lt_var fi" done # Now prepare to actually exec the command. exec_cmd="\$cmd$args" else # Display what would be done. if test -n "$shlibpath_var"; then eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" echo "export $shlibpath_var" fi $ECHO "$cmd$args" exit $EXIT_SUCCESS fi } test "$opt_mode" = execute && func_mode_execute ${1+"$@"} # func_mode_finish arg... func_mode_finish () { $opt_debug libs= libdirs= admincmds= for opt in "$nonopt" ${1+"$@"} do if test -d "$opt"; then func_append libdirs " $opt" elif test -f "$opt"; then if func_lalib_unsafe_p "$opt"; then func_append libs " $opt" else func_warning "\`$opt' is not a valid libtool archive" fi else func_fatal_error "invalid argument \`$opt'" fi done if test -n "$libs"; then if test -n "$lt_sysroot"; then sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" else sysroot_cmd= fi # Remove sysroot references if $opt_dry_run; then for lib in $libs; do echo "removing references to $lt_sysroot and \`=' prefixes from $lib" done else tmpdir=`func_mktempdir` for lib in $libs; do sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ > $tmpdir/tmp-la mv -f $tmpdir/tmp-la $lib done ${RM}r "$tmpdir" fi fi if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then for libdir in $libdirs; do if test -n "$finish_cmds"; then # Do each command in the finish commands. func_execute_cmds "$finish_cmds" 'admincmds="$admincmds '"$cmd"'"' fi if test -n "$finish_eval"; then # Do the single finish_eval. eval cmds=\"$finish_eval\" $opt_dry_run || eval "$cmds" || func_append admincmds " $cmds" fi done fi # Exit here if they wanted silent mode. $opt_silent && exit $EXIT_SUCCESS if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then echo "----------------------------------------------------------------------" echo "Libraries have been installed in:" for libdir in $libdirs; do $ECHO " $libdir" done echo echo "If you ever happen to want to link against installed libraries" echo "in a given directory, LIBDIR, you must either use libtool, and" echo "specify the full pathname of the library, or use the \`-LLIBDIR'" echo "flag during linking and do at least one of the following:" if test -n "$shlibpath_var"; then echo " - add LIBDIR to the \`$shlibpath_var' environment variable" echo " during execution" fi if test -n "$runpath_var"; then echo " - add LIBDIR to the \`$runpath_var' environment variable" echo " during linking" fi if test -n "$hardcode_libdir_flag_spec"; then libdir=LIBDIR eval flag=\"$hardcode_libdir_flag_spec\" $ECHO " - use the \`$flag' linker flag" fi if test -n "$admincmds"; then $ECHO " - have your system administrator run these commands:$admincmds" fi if test -f /etc/ld.so.conf; then echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" fi echo echo "See any operating system documentation about shared libraries for" case $host in solaris2.[6789]|solaris2.1[0-9]) echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" echo "pages." ;; *) echo "more information, such as the ld(1) and ld.so(8) manual pages." ;; esac echo "----------------------------------------------------------------------" fi exit $EXIT_SUCCESS } test "$opt_mode" = finish && func_mode_finish ${1+"$@"} # func_mode_install arg... func_mode_install () { $opt_debug # There may be an optional sh(1) argument at the beginning of # install_prog (especially on Windows NT). if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || # Allow the use of GNU shtool's install command. case $nonopt in *shtool*) :;; *) false;; esac; then # Aesthetically quote it. func_quote_for_eval "$nonopt" install_prog="$func_quote_for_eval_result " arg=$1 shift else install_prog= arg=$nonopt fi # The real first argument should be the name of the installation program. # Aesthetically quote it. func_quote_for_eval "$arg" func_append install_prog "$func_quote_for_eval_result" install_shared_prog=$install_prog case " $install_prog " in *[\\\ /]cp\ *) install_cp=: ;; *) install_cp=false ;; esac # We need to accept at least all the BSD install flags. dest= files= opts= prev= install_type= isdir=no stripme= no_mode=: for arg do arg2= if test -n "$dest"; then func_append files " $dest" dest=$arg continue fi case $arg in -d) isdir=yes ;; -f) if $install_cp; then :; else prev=$arg fi ;; -g | -m | -o) prev=$arg ;; -s) stripme=" -s" continue ;; -*) ;; *) # If the previous option needed an argument, then skip it. if test -n "$prev"; then if test "x$prev" = x-m && test -n "$install_override_mode"; then arg2=$install_override_mode no_mode=false fi prev= else dest=$arg continue fi ;; esac # Aesthetically quote the argument. func_quote_for_eval "$arg" func_append install_prog " $func_quote_for_eval_result" if test -n "$arg2"; then func_quote_for_eval "$arg2" fi func_append install_shared_prog " $func_quote_for_eval_result" done test -z "$install_prog" && \ func_fatal_help "you must specify an install program" test -n "$prev" && \ func_fatal_help "the \`$prev' option requires an argument" if test -n "$install_override_mode" && $no_mode; then if $install_cp; then :; else func_quote_for_eval "$install_override_mode" func_append install_shared_prog " -m $func_quote_for_eval_result" fi fi if test -z "$files"; then if test -z "$dest"; then func_fatal_help "no file or destination specified" else func_fatal_help "you must specify a destination" fi fi # Strip any trailing slash from the destination. func_stripname '' '/' "$dest" dest=$func_stripname_result # Check to see that the destination is a directory. test -d "$dest" && isdir=yes if test "$isdir" = yes; then destdir="$dest" destname= else func_dirname_and_basename "$dest" "" "." destdir="$func_dirname_result" destname="$func_basename_result" # Not a directory, so check to see that there is only one file specified. set dummy $files; shift test "$#" -gt 1 && \ func_fatal_help "\`$dest' is not a directory" fi case $destdir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) for file in $files; do case $file in *.lo) ;; *) func_fatal_help "\`$destdir' must be an absolute directory name" ;; esac done ;; esac # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic="$magic" staticlibs= future_libdirs= current_libdirs= for file in $files; do # Do each installation. case $file in *.$libext) # Do the static libraries later. func_append staticlibs " $file" ;; *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "\`$file' is not a valid libtool archive" library_names= old_library= relink_command= func_source "$file" # Add the libdir to current_libdirs if it is the destination. if test "X$destdir" = "X$libdir"; then case "$current_libdirs " in *" $libdir "*) ;; *) func_append current_libdirs " $libdir" ;; esac else # Note the libdir as a future libdir. case "$future_libdirs " in *" $libdir "*) ;; *) func_append future_libdirs " $libdir" ;; esac fi func_dirname "$file" "/" "" dir="$func_dirname_result" func_append dir "$objdir" if test -n "$relink_command"; then # Determine the prefix the user has applied to our future dir. inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` # Don't allow the user to place us outside of our expected # location b/c this prevents finding dependent libraries that # are installed to the same prefix. # At present, this check doesn't affect windows .dll's that # are installed into $libdir/../bin (currently, that works fine) # but it's something to keep an eye on. test "$inst_prefix_dir" = "$destdir" && \ func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir" if test -n "$inst_prefix_dir"; then # Stick the inst_prefix_dir data into the link command. relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` else relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` fi func_warning "relinking \`$file'" func_show_eval "$relink_command" \ 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"' fi # See the names of the shared library. set dummy $library_names; shift if test -n "$1"; then realname="$1" shift srcname="$realname" test -n "$relink_command" && srcname="$realname"T # Install the shared library and build the symlinks. func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ 'exit $?' tstripme="$stripme" case $host_os in cygwin* | mingw* | pw32* | cegcc*) case $realname in *.dll.a) tstripme="" ;; esac ;; esac if test -n "$tstripme" && test -n "$striplib"; then func_show_eval "$striplib $destdir/$realname" 'exit $?' fi if test "$#" -gt 0; then # Delete the old symlinks, and create new ones. # Try `ln -sf' first, because the `ln' binary might depend on # the symlink we replace! Solaris /bin/ln does not understand -f, # so we also need to try rm && ln -s. for linkname do test "$linkname" != "$realname" \ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" done fi # Do each command in the postinstall commands. lib="$destdir/$realname" func_execute_cmds "$postinstall_cmds" 'exit $?' fi # Install the pseudo-library for information purposes. func_basename "$file" name="$func_basename_result" instname="$dir/$name"i func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' # Maybe install the static library, too. test -n "$old_library" && func_append staticlibs " $dir/$old_library" ;; *.lo) # Install (i.e. copy) a libtool object. # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else func_basename "$file" destfile="$func_basename_result" destfile="$destdir/$destfile" fi # Deduce the name of the destination old-style object file. case $destfile in *.lo) func_lo2o "$destfile" staticdest=$func_lo2o_result ;; *.$objext) staticdest="$destfile" destfile= ;; *) func_fatal_help "cannot copy a libtool object to \`$destfile'" ;; esac # Install the libtool object if requested. test -n "$destfile" && \ func_show_eval "$install_prog $file $destfile" 'exit $?' # Install the old object if enabled. if test "$build_old_libs" = yes; then # Deduce the name of the old-style object file. func_lo2o "$file" staticobj=$func_lo2o_result func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' fi exit $EXIT_SUCCESS ;; *) # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else func_basename "$file" destfile="$func_basename_result" destfile="$destdir/$destfile" fi # If the file is missing, and there is a .exe on the end, strip it # because it is most likely a libtool script we actually want to # install stripped_ext="" case $file in *.exe) if test ! -f "$file"; then func_stripname '' '.exe' "$file" file=$func_stripname_result stripped_ext=".exe" fi ;; esac # Do a test to see if this is really a libtool program. case $host in *cygwin* | *mingw*) if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" wrapper=$func_ltwrapper_scriptname_result else func_stripname '' '.exe' "$file" wrapper=$func_stripname_result fi ;; *) wrapper=$file ;; esac if func_ltwrapper_script_p "$wrapper"; then notinst_deplibs= relink_command= func_source "$wrapper" # Check the variables that should have been set. test -z "$generated_by_libtool_version" && \ func_fatal_error "invalid libtool wrapper script \`$wrapper'" finalize=yes for lib in $notinst_deplibs; do # Check to see that each library is installed. libdir= if test -f "$lib"; then func_source "$lib" fi libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test if test -n "$libdir" && test ! -f "$libfile"; then func_warning "\`$lib' has not been installed in \`$libdir'" finalize=no fi done relink_command= func_source "$wrapper" outputname= if test "$fast_install" = no && test -n "$relink_command"; then $opt_dry_run || { if test "$finalize" = yes; then tmpdir=`func_mktempdir` func_basename "$file$stripped_ext" file="$func_basename_result" outputname="$tmpdir/$file" # Replace the output file specification. relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` $opt_silent || { func_quote_for_expand "$relink_command" eval "func_echo $func_quote_for_expand_result" } if eval "$relink_command"; then : else func_error "error: relink \`$file' with the above command before installing it" $opt_dry_run || ${RM}r "$tmpdir" continue fi file="$outputname" else func_warning "cannot relink \`$file'" fi } else # Install the binary that we compiled earlier. file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` fi fi # remove .exe since cygwin /usr/bin/install will append another # one anyway case $install_prog,$host in */usr/bin/install*,*cygwin*) case $file:$destfile in *.exe:*.exe) # this is ok ;; *.exe:*) destfile=$destfile.exe ;; *:*.exe) func_stripname '' '.exe' "$destfile" destfile=$func_stripname_result ;; esac ;; esac func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' $opt_dry_run || if test -n "$outputname"; then ${RM}r "$tmpdir" fi ;; esac done for file in $staticlibs; do func_basename "$file" name="$func_basename_result" # Set up the ranlib parameters. oldlib="$destdir/$name" func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result func_show_eval "$install_prog \$file \$oldlib" 'exit $?' if test -n "$stripme" && test -n "$old_striplib"; then func_show_eval "$old_striplib $tool_oldlib" 'exit $?' fi # Do each command in the postinstall commands. func_execute_cmds "$old_postinstall_cmds" 'exit $?' done test -n "$future_libdirs" && \ func_warning "remember to run \`$progname --finish$future_libdirs'" if test -n "$current_libdirs"; then # Maybe just do a dry run. $opt_dry_run && current_libdirs=" -n$current_libdirs" exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' else exit $EXIT_SUCCESS fi } test "$opt_mode" = install && func_mode_install ${1+"$@"} # func_generate_dlsyms outputname originator pic_p # Extract symbols from dlprefiles and create ${outputname}S.o with # a dlpreopen symbol table. func_generate_dlsyms () { $opt_debug my_outputname="$1" my_originator="$2" my_pic_p="${3-no}" my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'` my_dlsyms= if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then if test -n "$NM" && test -n "$global_symbol_pipe"; then my_dlsyms="${my_outputname}S.c" else func_error "not configured to extract global symbols from dlpreopened files" fi fi if test -n "$my_dlsyms"; then case $my_dlsyms in "") ;; *.c) # Discover the nlist of each of the dlfiles. nlist="$output_objdir/${my_outputname}.nm" func_show_eval "$RM $nlist ${nlist}S ${nlist}T" # Parse the name list into a source file. func_verbose "creating $output_objdir/$my_dlsyms" $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ /* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */ /* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */ #ifdef __cplusplus extern \"C\" { #endif #if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) #pragma GCC diagnostic ignored \"-Wstrict-prototypes\" #endif /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined(__osf__) /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif /* External symbol declarations for the compiler. */\ " if test "$dlself" = yes; then func_verbose "generating symbol list for \`$output'" $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" # Add our own program objects to the symbol list. progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` for progfile in $progfiles; do func_to_tool_file "$progfile" func_convert_file_msys_to_w32 func_verbose "extracting global C symbols from \`$func_to_tool_file_result'" $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" done if test -n "$exclude_expsyms"; then $opt_dry_run || { eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi if test -n "$export_symbols_regex"; then $opt_dry_run || { eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi # Prepare the list of exported symbols if test -z "$export_symbols"; then export_symbols="$output_objdir/$outputname.exp" $opt_dry_run || { $RM $export_symbols eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' ;; esac } else $opt_dry_run || { eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' ;; esac } fi fi for dlprefile in $dlprefiles; do func_verbose "extracting global C symbols from \`$dlprefile'" func_basename "$dlprefile" name="$func_basename_result" case $host in *cygwin* | *mingw* | *cegcc* ) # if an import library, we need to obtain dlname if func_win32_import_lib_p "$dlprefile"; then func_tr_sh "$dlprefile" eval "curr_lafile=\$libfile_$func_tr_sh_result" dlprefile_dlbasename="" if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then # Use subshell, to avoid clobbering current variable values dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` if test -n "$dlprefile_dlname" ; then func_basename "$dlprefile_dlname" dlprefile_dlbasename="$func_basename_result" else # no lafile. user explicitly requested -dlpreopen . $sharedlib_from_linklib_cmd "$dlprefile" dlprefile_dlbasename=$sharedlib_from_linklib_result fi fi $opt_dry_run || { if test -n "$dlprefile_dlbasename" ; then eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' else func_warning "Could not compute DLL name from $name" eval '$ECHO ": $name " >> "$nlist"' fi func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" } else # not an import lib $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } fi ;; *) $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } ;; esac done $opt_dry_run || { # Make sure we have at least an empty file. test -f "$nlist" || : > "$nlist" if test -n "$exclude_expsyms"; then $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T $MV "$nlist"T "$nlist" fi # Try sorting and uniquifying the output. if $GREP -v "^: " < "$nlist" | if sort -k 3 /dev/null 2>&1; then sort -k 3 else sort +2 fi | uniq > "$nlist"S; then : else $GREP -v "^: " < "$nlist" > "$nlist"S fi if test -f "$nlist"S; then eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' else echo '/* NONE */' >> "$output_objdir/$my_dlsyms" fi echo >> "$output_objdir/$my_dlsyms" "\ /* The mapping between symbol names and symbols. */ typedef struct { const char *name; void *address; } lt_dlsymlist; extern LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[]; LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[] = {\ { \"$my_originator\", (void *) 0 }," case $need_lib_prefix in no) eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; *) eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; esac echo >> "$output_objdir/$my_dlsyms" "\ {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt_${my_prefix}_LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif\ " } # !$opt_dry_run pic_flag_for_symtable= case "$compile_command " in *" -static "*) ;; *) case $host in # compiling the symbol table file with pic_flag works around # a FreeBSD bug that causes programs to crash when -lm is # linked before any other PIC object. But we must not use # pic_flag when linking with -static. The problem exists in # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; *-*-hpux*) pic_flag_for_symtable=" $pic_flag" ;; *) if test "X$my_pic_p" != Xno; then pic_flag_for_symtable=" $pic_flag" fi ;; esac ;; esac symtab_cflags= for arg in $LTCFLAGS; do case $arg in -pie | -fpie | -fPIE) ;; *) func_append symtab_cflags " $arg" ;; esac done # Now compile the dynamic symbol file. func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' # Clean up the generated files. func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"' # Transform the symbol file into the correct name. symfileobj="$output_objdir/${my_outputname}S.$objext" case $host in *cygwin* | *mingw* | *cegcc* ) if test -f "$output_objdir/$my_outputname.def"; then compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` else compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` fi ;; *) compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` ;; esac ;; *) func_fatal_error "unknown suffix for \`$my_dlsyms'" ;; esac else # We keep going just in case the user didn't refer to # lt_preloaded_symbols. The linker will fail if global_symbol_pipe # really was required. # Nullify the symbol file. compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` fi } # func_win32_libid arg # return the library type of file 'arg' # # Need a lot of goo to handle *both* DLLs and import libs # Has to be a shell function in order to 'eat' the argument # that is supplied when $file_magic_command is called. # Despite the name, also deal with 64 bit binaries. func_win32_libid () { $opt_debug win32_libid_type="unknown" win32_fileres=`file -L $1 2>/dev/null` case $win32_fileres in *ar\ archive\ import\ library*) # definitely import win32_libid_type="x86 archive import" ;; *ar\ archive*) # could be an import, or static # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then func_to_tool_file "$1" func_convert_file_msys_to_w32 win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | $SED -n -e ' 1,100{ / I /{ s,.*,import, p q } }'` case $win32_nmres in import*) win32_libid_type="x86 archive import";; *) win32_libid_type="x86 archive static";; esac fi ;; *DLL*) win32_libid_type="x86 DLL" ;; *executable*) # but shell scripts are "executable" too... case $win32_fileres in *MS\ Windows\ PE\ Intel*) win32_libid_type="x86 DLL" ;; esac ;; esac $ECHO "$win32_libid_type" } # func_cygming_dll_for_implib ARG # # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib () { $opt_debug sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` } # func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs # # The is the core of a fallback implementation of a # platform-specific function to extract the name of the # DLL associated with the specified import library LIBNAME. # # SECTION_NAME is either .idata$6 or .idata$7, depending # on the platform and compiler that created the implib. # # Echos the name of the DLL associated with the # specified import library. func_cygming_dll_for_implib_fallback_core () { $opt_debug match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` $OBJDUMP -s --section "$1" "$2" 2>/dev/null | $SED '/^Contents of section '"$match_literal"':/{ # Place marker at beginning of archive member dllname section s/.*/====MARK====/ p d } # These lines can sometimes be longer than 43 characters, but # are always uninteresting /:[ ]*file format pe[i]\{,1\}-/d /^In archive [^:]*:/d # Ensure marker is printed /^====MARK====/p # Remove all lines with less than 43 characters /^.\{43\}/!d # From remaining lines, remove first 43 characters s/^.\{43\}//' | $SED -n ' # Join marker and all lines until next marker into a single line /^====MARK====/ b para H $ b para b :para x s/\n//g # Remove the marker s/^====MARK====// # Remove trailing dots and whitespace s/[\. \t]*$// # Print /./p' | # we now have a list, one entry per line, of the stringified # contents of the appropriate section of all members of the # archive which possess that section. Heuristic: eliminate # all those which have a first or second character that is # a '.' (that is, objdump's representation of an unprintable # character.) This should work for all archives with less than # 0x302f exports -- but will fail for DLLs whose name actually # begins with a literal '.' or a single character followed by # a '.'. # # Of those that remain, print the first one. $SED -e '/^\./d;/^.\./d;q' } # func_cygming_gnu_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is a GNU/binutils-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_gnu_implib_p () { $opt_debug func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` test -n "$func_cygming_gnu_implib_tmp" } # func_cygming_ms_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is an MS-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_ms_implib_p () { $opt_debug func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` test -n "$func_cygming_ms_implib_tmp" } # func_cygming_dll_for_implib_fallback ARG # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # # This fallback implementation is for use when $DLLTOOL # does not support the --identify-strict option. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib_fallback () { $opt_debug if func_cygming_gnu_implib_p "$1" ; then # binutils import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` elif func_cygming_ms_implib_p "$1" ; then # ms-generated import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` else # unknown sharedlib_from_linklib_result="" fi } # func_extract_an_archive dir oldlib func_extract_an_archive () { $opt_debug f_ex_an_ar_dir="$1"; shift f_ex_an_ar_oldlib="$1" if test "$lock_old_archive_extraction" = yes; then lockfile=$f_ex_an_ar_oldlib.lock until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done fi func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ 'stat=$?; rm -f "$lockfile"; exit $stat' if test "$lock_old_archive_extraction" = yes; then $opt_dry_run || rm -f "$lockfile" fi if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then : else func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" fi } # func_extract_archives gentop oldlib ... func_extract_archives () { $opt_debug my_gentop="$1"; shift my_oldlibs=${1+"$@"} my_oldobjs="" my_xlib="" my_xabs="" my_xdir="" for my_xlib in $my_oldlibs; do # Extract the objects. case $my_xlib in [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; *) my_xabs=`pwd`"/$my_xlib" ;; esac func_basename "$my_xlib" my_xlib="$func_basename_result" my_xlib_u=$my_xlib while :; do case " $extracted_archives " in *" $my_xlib_u "*) func_arith $extracted_serial + 1 extracted_serial=$func_arith_result my_xlib_u=lt$extracted_serial-$my_xlib ;; *) break ;; esac done extracted_archives="$extracted_archives $my_xlib_u" my_xdir="$my_gentop/$my_xlib_u" func_mkdir_p "$my_xdir" case $host in *-darwin*) func_verbose "Extracting $my_xabs" # Do not bother doing anything if just a dry run $opt_dry_run || { darwin_orig_dir=`pwd` cd $my_xdir || exit $? darwin_archive=$my_xabs darwin_curdir=`pwd` darwin_base_archive=`basename "$darwin_archive"` darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` if test -n "$darwin_arches"; then darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` darwin_arch= func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" for darwin_arch in $darwin_arches ; do func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}" $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" func_extract_an_archive "`pwd`" "${darwin_base_archive}" cd "$darwin_curdir" $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" done # $darwin_arches ## Okay now we've a bunch of thin objects, gotta fatten them up :) darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u` darwin_file= darwin_files= for darwin_file in $darwin_filelist; do darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` $LIPO -create -output "$darwin_file" $darwin_files done # $darwin_filelist $RM -rf unfat-$$ cd "$darwin_orig_dir" else cd $darwin_orig_dir func_extract_an_archive "$my_xdir" "$my_xabs" fi # $darwin_arches } # !$opt_dry_run ;; *) func_extract_an_archive "$my_xdir" "$my_xabs" ;; esac my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` done func_extract_archives_result="$my_oldobjs" } # func_emit_wrapper [arg=no] # # Emit a libtool wrapper script on stdout. # Don't directly open a file because we may want to # incorporate the script contents within a cygwin/mingw # wrapper executable. Must ONLY be called from within # func_mode_link because it depends on a number of variables # set therein. # # ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR # variable will take. If 'yes', then the emitted script # will assume that the directory in which it is stored is # the $objdir directory. This is a cygwin/mingw-specific # behavior. func_emit_wrapper () { func_emit_wrapper_arg1=${1-no} $ECHO "\ #! $SHELL # $output - temporary wrapper script for $objdir/$outputname # Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION # # The $output program cannot be directly executed until all the libtool # libraries that it depends on are installed. # # This wrapper script should never be moved out of the build directory. # If it is, it will not operate correctly. # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='$sed_quote_subst' # Be Bourne compatible if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH relink_command=\"$relink_command\" # This environment variable determines our operation mode. if test \"\$libtool_install_magic\" = \"$magic\"; then # install mode needs the following variables: generated_by_libtool_version='$macro_version' notinst_deplibs='$notinst_deplibs' else # When we are sourced in execute mode, \$file and \$ECHO are already set. if test \"\$libtool_execute_magic\" != \"$magic\"; then file=\"\$0\"" qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` $ECHO "\ # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } ECHO=\"$qECHO\" fi # Very basic option parsing. These options are (a) specific to # the libtool wrapper, (b) are identical between the wrapper # /script/ and the wrapper /executable/ which is used only on # windows platforms, and (c) all begin with the string "--lt-" # (application programs are unlikely to have options which match # this pattern). # # There are only two supported options: --lt-debug and # --lt-dump-script. There is, deliberately, no --lt-help. # # The first argument to this parsing function should be the # script's $0 value, followed by "$@". lt_option_debug= func_parse_lt_options () { lt_script_arg0=\$0 shift for lt_opt do case \"\$lt_opt\" in --lt-debug) lt_option_debug=1 ;; --lt-dump-script) lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` cat \"\$lt_dump_D/\$lt_dump_F\" exit 0 ;; --lt-*) \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 exit 1 ;; esac done # Print the debug banner immediately: if test -n \"\$lt_option_debug\"; then echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2 fi } # Used when --lt-debug. Prints its arguments to stdout # (redirection is the responsibility of the caller) func_lt_dump_args () { lt_dump_args_N=1; for lt_arg do \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\" lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` done } # Core function for launching the target application func_exec_program_core () { " case $host in # Backslashes separate directories on plain windows *-*-mingw | *-*-os2* | *-cegcc*) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} " ;; *) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir/\$program\" \${1+\"\$@\"} " ;; esac $ECHO "\ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 exit 1 } # A function to encapsulate launching the target application # Strips options in the --lt-* namespace from \$@ and # launches target application with the remaining arguments. func_exec_program () { case \" \$* \" in *\\ --lt-*) for lt_wr_arg do case \$lt_wr_arg in --lt-*) ;; *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; esac shift done ;; esac func_exec_program_core \${1+\"\$@\"} } # Parse options func_parse_lt_options \"\$0\" \${1+\"\$@\"} # Find the directory that this script lives in. thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` test \"x\$thisdir\" = \"x\$file\" && thisdir=. # Follow symbolic links until we get to the real thisdir. file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` while test -n \"\$file\"; do destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` # If there was a directory component, then change thisdir. if test \"x\$destdir\" != \"x\$file\"; then case \"\$destdir\" in [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; *) thisdir=\"\$thisdir/\$destdir\" ;; esac fi file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` done # Usually 'no', except on cygwin/mingw when embedded into # the cwrapper. WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then # special case for '.' if test \"\$thisdir\" = \".\"; then thisdir=\`pwd\` fi # remove .libs from thisdir case \"\$thisdir\" in *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; $objdir ) thisdir=. ;; esac fi # Try to get the absolute directory name. absdir=\`cd \"\$thisdir\" && pwd\` test -n \"\$absdir\" && thisdir=\"\$absdir\" " if test "$fast_install" = yes; then $ECHO "\ program=lt-'$outputname'$exeext progdir=\"\$thisdir/$objdir\" if test ! -f \"\$progdir/\$program\" || { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ test \"X\$file\" != \"X\$progdir/\$program\"; }; then file=\"\$\$-\$program\" if test ! -d \"\$progdir\"; then $MKDIR \"\$progdir\" else $RM \"\$progdir/\$file\" fi" $ECHO "\ # relink executable if necessary if test -n \"\$relink_command\"; then if relink_command_output=\`eval \$relink_command 2>&1\`; then : else $ECHO \"\$relink_command_output\" >&2 $RM \"\$progdir/\$file\" exit 1 fi fi $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || { $RM \"\$progdir/\$program\"; $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } $RM \"\$progdir/\$file\" fi" else $ECHO "\ program='$outputname' progdir=\"\$thisdir/$objdir\" " fi $ECHO "\ if test -f \"\$progdir/\$program\"; then" # fixup the dll searchpath if we need to. # # Fix the DLL searchpath if we need to. Do this before prepending # to shlibpath, because on Windows, both are PATH and uninstalled # libraries must come first. if test -n "$dllsearchpath"; then $ECHO "\ # Add the dll search path components to the executable PATH PATH=$dllsearchpath:\$PATH " fi # Export our shlibpath_var if we have one. if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then $ECHO "\ # Add our own library path to $shlibpath_var $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" # Some systems cannot cope with colon-terminated $shlibpath_var # The second colon is a workaround for a bug in BeOS R4 sed $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` export $shlibpath_var " fi $ECHO "\ if test \"\$libtool_execute_magic\" != \"$magic\"; then # Run the actual program with our arguments. func_exec_program \${1+\"\$@\"} fi else # The program doesn't exist. \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 exit 1 fi fi\ " } # func_emit_cwrapperexe_src # emit the source code for a wrapper executable on stdout # Must ONLY be called from within func_mode_link because # it depends on a number of variable set therein. func_emit_cwrapperexe_src () { cat < #include #ifdef _MSC_VER # include # include # include #else # include # include # ifdef __CYGWIN__ # include # endif #endif #include #include #include #include #include #include #include #include /* declarations of non-ANSI functions */ #if defined(__MINGW32__) # ifdef __STRICT_ANSI__ int _putenv (const char *); # endif #elif defined(__CYGWIN__) # ifdef __STRICT_ANSI__ char *realpath (const char *, char *); int putenv (char *); int setenv (const char *, const char *, int); # endif /* #elif defined (other platforms) ... */ #endif /* portability defines, excluding path handling macros */ #if defined(_MSC_VER) # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv # define S_IXUSR _S_IEXEC # ifndef _INTPTR_T_DEFINED # define _INTPTR_T_DEFINED # define intptr_t int # endif #elif defined(__MINGW32__) # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv #elif defined(__CYGWIN__) # define HAVE_SETENV # define FOPEN_WB "wb" /* #elif defined (other platforms) ... */ #endif #if defined(PATH_MAX) # define LT_PATHMAX PATH_MAX #elif defined(MAXPATHLEN) # define LT_PATHMAX MAXPATHLEN #else # define LT_PATHMAX 1024 #endif #ifndef S_IXOTH # define S_IXOTH 0 #endif #ifndef S_IXGRP # define S_IXGRP 0 #endif /* path handling portability macros */ #ifndef DIR_SEPARATOR # define DIR_SEPARATOR '/' # define PATH_SEPARATOR ':' #endif #if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ defined (__OS2__) # define HAVE_DOS_BASED_FILE_SYSTEM # define FOPEN_WB "wb" # ifndef DIR_SEPARATOR_2 # define DIR_SEPARATOR_2 '\\' # endif # ifndef PATH_SEPARATOR_2 # define PATH_SEPARATOR_2 ';' # endif #endif #ifndef DIR_SEPARATOR_2 # define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) #else /* DIR_SEPARATOR_2 */ # define IS_DIR_SEPARATOR(ch) \ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) #endif /* DIR_SEPARATOR_2 */ #ifndef PATH_SEPARATOR_2 # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) #else /* PATH_SEPARATOR_2 */ # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) #endif /* PATH_SEPARATOR_2 */ #ifndef FOPEN_WB # define FOPEN_WB "w" #endif #ifndef _O_BINARY # define _O_BINARY 0 #endif #define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) #define XFREE(stale) do { \ if (stale) { free ((void *) stale); stale = 0; } \ } while (0) #if defined(LT_DEBUGWRAPPER) static int lt_debug = 1; #else static int lt_debug = 0; #endif const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ void *xmalloc (size_t num); char *xstrdup (const char *string); const char *base_name (const char *name); char *find_executable (const char *wrapper); char *chase_symlinks (const char *pathspec); int make_executable (const char *path); int check_executable (const char *path); char *strendzap (char *str, const char *pat); void lt_debugprintf (const char *file, int line, const char *fmt, ...); void lt_fatal (const char *file, int line, const char *message, ...); static const char *nonnull (const char *s); static const char *nonempty (const char *s); void lt_setenv (const char *name, const char *value); char *lt_extend_str (const char *orig_value, const char *add, int to_end); void lt_update_exe_path (const char *name, const char *value); void lt_update_lib_path (const char *name, const char *value); char **prepare_spawn (char **argv); void lt_dump_script (FILE *f); EOF cat <= 0) && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) return 1; else return 0; } int make_executable (const char *path) { int rval = 0; struct stat st; lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", nonempty (path)); if ((!path) || (!*path)) return 0; if (stat (path, &st) >= 0) { rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); } return rval; } /* Searches for the full path of the wrapper. Returns newly allocated full path name if found, NULL otherwise Does not chase symlinks, even on platforms that support them. */ char * find_executable (const char *wrapper) { int has_slash = 0; const char *p; const char *p_next; /* static buffer for getcwd */ char tmp[LT_PATHMAX + 1]; int tmp_len; char *concat_name; lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", nonempty (wrapper)); if ((wrapper == NULL) || (*wrapper == '\0')) return NULL; /* Absolute path? */ #if defined (HAVE_DOS_BASED_FILE_SYSTEM) if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } else { #endif if (IS_DIR_SEPARATOR (wrapper[0])) { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } #if defined (HAVE_DOS_BASED_FILE_SYSTEM) } #endif for (p = wrapper; *p; p++) if (*p == '/') { has_slash = 1; break; } if (!has_slash) { /* no slashes; search PATH */ const char *path = getenv ("PATH"); if (path != NULL) { for (p = path; *p; p = p_next) { const char *q; size_t p_len; for (q = p; *q; q++) if (IS_PATH_SEPARATOR (*q)) break; p_len = q - p; p_next = (*q == '\0' ? q : q + 1); if (p_len == 0) { /* empty path: current directory */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); } else { concat_name = XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, p, p_len); concat_name[p_len] = '/'; strcpy (concat_name + p_len + 1, wrapper); } if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } } /* not found in PATH; assume curdir */ } /* Relative path | not found in path: prepend cwd */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); return NULL; } char * chase_symlinks (const char *pathspec) { #ifndef S_ISLNK return xstrdup (pathspec); #else char buf[LT_PATHMAX]; struct stat s; char *tmp_pathspec = xstrdup (pathspec); char *p; int has_symlinks = 0; while (strlen (tmp_pathspec) && !has_symlinks) { lt_debugprintf (__FILE__, __LINE__, "checking path component for symlinks: %s\n", tmp_pathspec); if (lstat (tmp_pathspec, &s) == 0) { if (S_ISLNK (s.st_mode) != 0) { has_symlinks = 1; break; } /* search backwards for last DIR_SEPARATOR */ p = tmp_pathspec + strlen (tmp_pathspec) - 1; while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) p--; if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) { /* no more DIR_SEPARATORS left */ break; } *p = '\0'; } else { lt_fatal (__FILE__, __LINE__, "error accessing file \"%s\": %s", tmp_pathspec, nonnull (strerror (errno))); } } XFREE (tmp_pathspec); if (!has_symlinks) { return xstrdup (pathspec); } tmp_pathspec = realpath (pathspec, buf); if (tmp_pathspec == 0) { lt_fatal (__FILE__, __LINE__, "could not follow symlinks for %s", pathspec); } return xstrdup (tmp_pathspec); #endif } char * strendzap (char *str, const char *pat) { size_t len, patlen; assert (str != NULL); assert (pat != NULL); len = strlen (str); patlen = strlen (pat); if (patlen <= len) { str += len - patlen; if (strcmp (str, pat) == 0) *str = '\0'; } return str; } void lt_debugprintf (const char *file, int line, const char *fmt, ...) { va_list args; if (lt_debug) { (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); va_start (args, fmt); (void) vfprintf (stderr, fmt, args); va_end (args); } } static void lt_error_core (int exit_status, const char *file, int line, const char *mode, const char *message, va_list ap) { fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); vfprintf (stderr, message, ap); fprintf (stderr, ".\n"); if (exit_status >= 0) exit (exit_status); } void lt_fatal (const char *file, int line, const char *message, ...) { va_list ap; va_start (ap, message); lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); va_end (ap); } static const char * nonnull (const char *s) { return s ? s : "(null)"; } static const char * nonempty (const char *s) { return (s && !*s) ? "(empty)" : nonnull (s); } void lt_setenv (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_setenv) setting '%s' to '%s'\n", nonnull (name), nonnull (value)); { #ifdef HAVE_SETENV /* always make a copy, for consistency with !HAVE_SETENV */ char *str = xstrdup (value); setenv (name, str, 1); #else int len = strlen (name) + 1 + strlen (value) + 1; char *str = XMALLOC (char, len); sprintf (str, "%s=%s", name, value); if (putenv (str) != EXIT_SUCCESS) { XFREE (str); } #endif } } char * lt_extend_str (const char *orig_value, const char *add, int to_end) { char *new_value; if (orig_value && *orig_value) { int orig_value_len = strlen (orig_value); int add_len = strlen (add); new_value = XMALLOC (char, add_len + orig_value_len + 1); if (to_end) { strcpy (new_value, orig_value); strcpy (new_value + orig_value_len, add); } else { strcpy (new_value, add); strcpy (new_value + add_len, orig_value); } } else { new_value = xstrdup (add); } return new_value; } void lt_update_exe_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); /* some systems can't cope with a ':'-terminated path #' */ int len = strlen (new_value); while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1])) { new_value[len-1] = '\0'; } lt_setenv (name, new_value); XFREE (new_value); } } void lt_update_lib_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); lt_setenv (name, new_value); XFREE (new_value); } } EOF case $host_os in mingw*) cat <<"EOF" /* Prepares an argument vector before calling spawn(). Note that spawn() does not by itself call the command interpreter (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&v); v.dwPlatformId == VER_PLATFORM_WIN32_NT; }) ? "cmd.exe" : "command.com"). Instead it simply concatenates the arguments, separated by ' ', and calls CreateProcess(). We must quote the arguments since Win32 CreateProcess() interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a special way: - Space and tab are interpreted as delimiters. They are not treated as delimiters if they are surrounded by double quotes: "...". - Unescaped double quotes are removed from the input. Their only effect is that within double quotes, space and tab are treated like normal characters. - Backslashes not followed by double quotes are not special. - But 2*n+1 backslashes followed by a double quote become n backslashes followed by a double quote (n >= 0): \" -> " \\\" -> \" \\\\\" -> \\" */ #define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" #define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" char ** prepare_spawn (char **argv) { size_t argc; char **new_argv; size_t i; /* Count number of arguments. */ for (argc = 0; argv[argc] != NULL; argc++) ; /* Allocate new argument vector. */ new_argv = XMALLOC (char *, argc + 1); /* Put quoted arguments into the new argument vector. */ for (i = 0; i < argc; i++) { const char *string = argv[i]; if (string[0] == '\0') new_argv[i] = xstrdup ("\"\""); else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) { int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); size_t length; unsigned int backslashes; const char *s; char *quoted_string; char *p; length = 0; backslashes = 0; if (quote_around) length++; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') length += backslashes + 1; length++; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) length += backslashes + 1; quoted_string = XMALLOC (char, length + 1); p = quoted_string; backslashes = 0; if (quote_around) *p++ = '"'; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') { unsigned int j; for (j = backslashes + 1; j > 0; j--) *p++ = '\\'; } *p++ = c; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) { unsigned int j; for (j = backslashes; j > 0; j--) *p++ = '\\'; *p++ = '"'; } *p = '\0'; new_argv[i] = quoted_string; } else new_argv[i] = (char *) string; } new_argv[argc] = NULL; return new_argv; } EOF ;; esac cat <<"EOF" void lt_dump_script (FILE* f) { EOF func_emit_wrapper yes | $SED -n -e ' s/^\(.\{79\}\)\(..*\)/\1\ \2/ h s/\([\\"]\)/\\\1/g s/$/\\n/ s/\([^\n]*\).*/ fputs ("\1", f);/p g D' cat <<"EOF" } EOF } # end: func_emit_cwrapperexe_src # func_win32_import_lib_p ARG # True if ARG is an import lib, as indicated by $file_magic_cmd func_win32_import_lib_p () { $opt_debug case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in *import*) : ;; *) false ;; esac } # func_mode_link arg... func_mode_link () { $opt_debug case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) # It is impossible to link a dll without this setting, and # we shouldn't force the makefile maintainer to figure out # which system we are compiling for in order to pass an extra # flag for every libtool invocation. # allow_undefined=no # FIXME: Unfortunately, there are problems with the above when trying # to make a dll which has undefined symbols, in which case not # even a static library is built. For now, we need to specify # -no-undefined on the libtool link line when we can be certain # that all symbols are satisfied, otherwise we get a static library. allow_undefined=yes ;; *) allow_undefined=yes ;; esac libtool_args=$nonopt base_compile="$nonopt $@" compile_command=$nonopt finalize_command=$nonopt compile_rpath= finalize_rpath= compile_shlibpath= finalize_shlibpath= convenience= old_convenience= deplibs= old_deplibs= compiler_flags= linker_flags= dllsearchpath= lib_search_path=`pwd` inst_prefix_dir= new_inherited_linker_flags= avoid_version=no bindir= dlfiles= dlprefiles= dlself=no export_dynamic=no export_symbols= export_symbols_regex= generated= libobjs= ltlibs= module=no no_install=no objs= non_pic_objects= precious_files_regex= prefer_static_libs=no preload=no prev= prevarg= release= rpath= xrpath= perm_rpath= temp_rpath= thread_safe=no vinfo= vinfo_number=no weak_libs= single_module="${wl}-single_module" func_infer_tag $base_compile # We need to know -static, to get the right output filenames. for arg do case $arg in -shared) test "$build_libtool_libs" != yes && \ func_fatal_configuration "can not build a shared library" build_old_libs=no break ;; -all-static | -static | -static-libtool-libs) case $arg in -all-static) if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then func_warning "complete static linking is impossible in this configuration" fi if test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; -static) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=built ;; -static-libtool-libs) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; esac build_libtool_libs=no build_old_libs=yes break ;; esac done # See if our shared archives depend on static archives. test -n "$old_archive_from_new_cmds" && build_old_libs=yes # Go through the arguments, transforming them on the way. while test "$#" -gt 0; do arg="$1" shift func_quote_for_eval "$arg" qarg=$func_quote_for_eval_unquoted_result func_append libtool_args " $func_quote_for_eval_result" # If the previous option needs an argument, assign it. if test -n "$prev"; then case $prev in output) func_append compile_command " @OUTPUT@" func_append finalize_command " @OUTPUT@" ;; esac case $prev in bindir) bindir="$arg" prev= continue ;; dlfiles|dlprefiles) if test "$preload" = no; then # Add the symbol object into the linking commands. func_append compile_command " @SYMFILE@" func_append finalize_command " @SYMFILE@" preload=yes fi case $arg in *.la | *.lo) ;; # We handle these cases below. force) if test "$dlself" = no; then dlself=needless export_dynamic=yes fi prev= continue ;; self) if test "$prev" = dlprefiles; then dlself=yes elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then dlself=yes else dlself=needless export_dynamic=yes fi prev= continue ;; *) if test "$prev" = dlfiles; then func_append dlfiles " $arg" else func_append dlprefiles " $arg" fi prev= continue ;; esac ;; expsyms) export_symbols="$arg" test -f "$arg" \ || func_fatal_error "symbol file \`$arg' does not exist" prev= continue ;; expsyms_regex) export_symbols_regex="$arg" prev= continue ;; framework) case $host in *-*-darwin*) case "$deplibs " in *" $qarg.ltframework "*) ;; *) func_append deplibs " $qarg.ltframework" # this is fixed later ;; esac ;; esac prev= continue ;; inst_prefix) inst_prefix_dir="$arg" prev= continue ;; objectlist) if test -f "$arg"; then save_arg=$arg moreargs= for fil in `cat "$save_arg"` do # func_append moreargs " $fil" arg=$fil # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test "$pic_object" = none && test "$non_pic_object" = none; then func_fatal_error "cannot find name of object for \`$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" if test "$pic_object" != none; then # Prepend the subdirectory the object is found in. pic_object="$xdir$pic_object" if test "$prev" = dlfiles; then if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test "$prev" = dlprefiles; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg="$pic_object" fi # Non-PIC object. if test "$non_pic_object" != none; then # Prepend the subdirectory the object is found in. non_pic_object="$xdir$non_pic_object" # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test "$pic_object" = none ; then arg="$non_pic_object" fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object="$pic_object" func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "\`$arg' is not a valid libtool object" fi fi done else func_fatal_error "link input file \`$arg' does not exist" fi arg=$save_arg prev= continue ;; precious_regex) precious_files_regex="$arg" prev= continue ;; release) release="-$arg" prev= continue ;; rpath | xrpath) # We need an absolute path. case $arg in [\\/]* | [A-Za-z]:[\\/]*) ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac if test "$prev" = rpath; then case "$rpath " in *" $arg "*) ;; *) func_append rpath " $arg" ;; esac else case "$xrpath " in *" $arg "*) ;; *) func_append xrpath " $arg" ;; esac fi prev= continue ;; shrext) shrext_cmds="$arg" prev= continue ;; weak) func_append weak_libs " $arg" prev= continue ;; xcclinker) func_append linker_flags " $qarg" func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xcompiler) func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xlinker) func_append linker_flags " $qarg" func_append compiler_flags " $wl$qarg" prev= func_append compile_command " $wl$qarg" func_append finalize_command " $wl$qarg" continue ;; *) eval "$prev=\"\$arg\"" prev= continue ;; esac fi # test -n "$prev" prevarg="$arg" case $arg in -all-static) if test -n "$link_static_flag"; then # See comment for -static flag below, for more details. func_append compile_command " $link_static_flag" func_append finalize_command " $link_static_flag" fi continue ;; -allow-undefined) # FIXME: remove this flag sometime in the future. func_fatal_error "\`-allow-undefined' must not be used because it is the default" ;; -avoid-version) avoid_version=yes continue ;; -bindir) prev=bindir continue ;; -dlopen) prev=dlfiles continue ;; -dlpreopen) prev=dlprefiles continue ;; -export-dynamic) export_dynamic=yes continue ;; -export-symbols | -export-symbols-regex) if test -n "$export_symbols" || test -n "$export_symbols_regex"; then func_fatal_error "more than one -exported-symbols argument is not allowed" fi if test "X$arg" = "X-export-symbols"; then prev=expsyms else prev=expsyms_regex fi continue ;; -framework) prev=framework continue ;; -inst-prefix-dir) prev=inst_prefix continue ;; # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* # so, if we see these flags be careful not to treat them like -L -L[A-Z][A-Z]*:*) case $with_gcc/$host in no/*-*-irix* | /*-*-irix*) func_append compile_command " $arg" func_append finalize_command " $arg" ;; esac continue ;; -L*) func_stripname "-L" '' "$arg" if test -z "$func_stripname_result"; then if test "$#" -gt 0; then func_fatal_error "require no space between \`-L' and \`$1'" else func_fatal_error "need path for \`-L' option" fi fi func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) absdir=`cd "$dir" && pwd` test -z "$absdir" && \ func_fatal_error "cannot determine absolute directory name of \`$dir'" dir="$absdir" ;; esac case "$deplibs " in *" -L$dir "* | *" $arg "*) # Will only happen for absolute or sysroot arguments ;; *) # Preserve sysroot, but never include relative directories case $dir in [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; *) func_append deplibs " -L$dir" ;; esac func_append lib_search_path " $dir" ;; esac case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` case :$dllsearchpath: in *":$dir:"*) ;; ::) dllsearchpath=$dir;; *) func_append dllsearchpath ":$dir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac continue ;; -l*) if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) # These systems don't actually have a C or math library (as such) continue ;; *-*-os2*) # These systems don't actually have a C library (as such) test "X$arg" = "X-lc" && continue ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. test "X$arg" = "X-lc" && continue ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C and math libraries are in the System framework func_append deplibs " System.ltframework" continue ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype test "X$arg" = "X-lc" && continue ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work test "X$arg" = "X-lc" && continue ;; esac elif test "X$arg" = "X-lc_r"; then case $host in *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc_r directly, use -pthread flag. continue ;; esac fi func_append deplibs " $arg" continue ;; -module) module=yes continue ;; # Tru64 UNIX uses -model [arg] to determine the layout of C++ # classes, name mangling, and exception handling. # Darwin uses the -arch flag to determine output architecture. -model|-arch|-isysroot|--sysroot) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" prev=xcompiler continue ;; -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" case "$new_inherited_linker_flags " in *" $arg "*) ;; * ) func_append new_inherited_linker_flags " $arg" ;; esac continue ;; -multi_module) single_module="${wl}-multi_module" continue ;; -no-fast-install) fast_install=no continue ;; -no-install) case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) # The PATH hackery in wrapper scripts is required on Windows # and Darwin in order for the loader to find any dlls it needs. func_warning "\`-no-install' is ignored for $host" func_warning "assuming \`-no-fast-install' instead" fast_install=no ;; *) no_install=yes ;; esac continue ;; -no-undefined) allow_undefined=no continue ;; -objectlist) prev=objectlist continue ;; -o) prev=output ;; -precious-files-regex) prev=precious_regex continue ;; -release) prev=release continue ;; -rpath) prev=rpath continue ;; -R) prev=xrpath continue ;; -R*) func_stripname '-R' '' "$arg" dir=$func_stripname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; =*) func_stripname '=' '' "$dir" dir=$lt_sysroot$func_stripname_result ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac continue ;; -shared) # The effects of -shared are defined in a previous loop. continue ;; -shrext) prev=shrext continue ;; -static | -static-libtool-libs) # The effects of -static are defined in a previous loop. # We used to do the same as -all-static on platforms that # didn't have a PIC flag, but the assumption that the effects # would be equivalent was wrong. It would break on at least # Digital Unix and AIX. continue ;; -thread-safe) thread_safe=yes continue ;; -version-info) prev=vinfo continue ;; -version-number) prev=vinfo vinfo_number=yes continue ;; -weak) prev=weak continue ;; -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" func_quote_for_eval "$flag" func_append arg " $func_quote_for_eval_result" func_append compiler_flags " $func_quote_for_eval_result" done IFS="$save_ifs" func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Wl,*) func_stripname '-Wl,' '' "$arg" args=$func_stripname_result arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" func_quote_for_eval "$flag" func_append arg " $wl$func_quote_for_eval_result" func_append compiler_flags " $wl$func_quote_for_eval_result" func_append linker_flags " $func_quote_for_eval_result" done IFS="$save_ifs" func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Xcompiler) prev=xcompiler continue ;; -Xlinker) prev=xlinker continue ;; -XCClinker) prev=xcclinker continue ;; # -msg_* for osf cc -msg_*) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; # Flags to be passed through unchanged, with rationale: # -64, -mips[0-9] enable 64-bit mode for the SGI compiler # -r[0-9][0-9]* specify processor for the SGI compiler # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler # +DA*, +DD* enable 64-bit mode for the HP compiler # -q* compiler args for the IBM compiler # -m*, -t[45]*, -txscale* architecture-specific flags for GCC # -F/path path to uninstalled frameworks, gcc on darwin # -p, -pg, --coverage, -fprofile-* profiling flags for GCC # @file GCC response files # -tp=* Portland pgcc target processor selection # --sysroot=* for sysroot support # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ -O*|-flto*|-fwhopr*|-fuse-linker-plugin) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" func_append compile_command " $arg" func_append finalize_command " $arg" func_append compiler_flags " $arg" continue ;; # Some other compiler flag. -* | +*) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; *.$objext) # A standard object. func_append objs " $arg" ;; *.lo) # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test "$pic_object" = none && test "$non_pic_object" = none; then func_fatal_error "cannot find name of object for \`$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" if test "$pic_object" != none; then # Prepend the subdirectory the object is found in. pic_object="$xdir$pic_object" if test "$prev" = dlfiles; then if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test "$prev" = dlprefiles; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg="$pic_object" fi # Non-PIC object. if test "$non_pic_object" != none; then # Prepend the subdirectory the object is found in. non_pic_object="$xdir$non_pic_object" # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test "$pic_object" = none ; then arg="$non_pic_object" fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object="$pic_object" func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "\`$arg' is not a valid libtool object" fi fi ;; *.$libext) # An archive. func_append deplibs " $arg" func_append old_deplibs " $arg" continue ;; *.la) # A libtool-controlled library. func_resolve_sysroot "$arg" if test "$prev" = dlfiles; then # This library was specified with -dlopen. func_append dlfiles " $func_resolve_sysroot_result" prev= elif test "$prev" = dlprefiles; then # The library was specified with -dlpreopen. func_append dlprefiles " $func_resolve_sysroot_result" prev= else func_append deplibs " $func_resolve_sysroot_result" fi continue ;; # Some other compiler argument. *) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; esac # arg # Now actually substitute the argument into the commands. if test -n "$arg"; then func_append compile_command " $arg" func_append finalize_command " $arg" fi done # argument parsing loop test -n "$prev" && \ func_fatal_help "the \`$prevarg' option requires an argument" if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then eval arg=\"$export_dynamic_flag_spec\" func_append compile_command " $arg" func_append finalize_command " $arg" fi oldlibs= # calculate the name of the file, without its directory func_basename "$output" outputname="$func_basename_result" libobjs_save="$libobjs" if test -n "$shlibpath_var"; then # get the directories listed in $shlibpath_var eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\` else shlib_search_path= fi eval sys_lib_search_path=\"$sys_lib_search_path_spec\" eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" func_dirname "$output" "/" "" output_objdir="$func_dirname_result$objdir" func_to_tool_file "$output_objdir/" tool_output_objdir=$func_to_tool_file_result # Create the object directory. func_mkdir_p "$output_objdir" # Determine the type of output case $output in "") func_fatal_help "you must specify an output file" ;; *.$libext) linkmode=oldlib ;; *.lo | *.$objext) linkmode=obj ;; *.la) linkmode=lib ;; *) linkmode=prog ;; # Anything else should be a program. esac specialdeplibs= libs= # Find all interdependent deplibs by searching for libraries # that are linked more than once (e.g. -la -lb -la) for deplib in $deplibs; do if $opt_preserve_dup_deps ; then case "$libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append libs " $deplib" done if test "$linkmode" = lib; then libs="$predeps $libs $compiler_lib_search_path $postdeps" # Compute libraries that are listed more than once in $predeps # $postdeps and mark them as special (i.e., whose duplicates are # not to be eliminated). pre_post_deps= if $opt_duplicate_compiler_generated_deps; then for pre_post_dep in $predeps $postdeps; do case "$pre_post_deps " in *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; esac func_append pre_post_deps " $pre_post_dep" done fi pre_post_deps= fi deplibs= newdependency_libs= newlib_search_path= need_relink=no # whether we're linking any uninstalled libtool libraries notinst_deplibs= # not-installed libtool libraries notinst_path= # paths that contain not-installed libtool libraries case $linkmode in lib) passes="conv dlpreopen link" for file in $dlfiles $dlprefiles; do case $file in *.la) ;; *) func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file" ;; esac done ;; prog) compile_deplibs= finalize_deplibs= alldeplibs=no newdlfiles= newdlprefiles= passes="conv scan dlopen dlpreopen link" ;; *) passes="conv" ;; esac for pass in $passes; do # The preopen pass in lib mode reverses $deplibs; put it back here # so that -L comes before libs that need it for instance... if test "$linkmode,$pass" = "lib,link"; then ## FIXME: Find the place where the list is rebuilt in the wrong ## order, and fix it there properly tmp_deplibs= for deplib in $deplibs; do tmp_deplibs="$deplib $tmp_deplibs" done deplibs="$tmp_deplibs" fi if test "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan"; then libs="$deplibs" deplibs= fi if test "$linkmode" = prog; then case $pass in dlopen) libs="$dlfiles" ;; dlpreopen) libs="$dlprefiles" ;; link) libs="$deplibs %DEPLIBS%" test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs" ;; esac fi if test "$linkmode,$pass" = "lib,dlpreopen"; then # Collect and forward deplibs of preopened libtool libs for lib in $dlprefiles; do # Ignore non-libtool-libs dependency_libs= func_resolve_sysroot "$lib" case $lib in *.la) func_source "$func_resolve_sysroot_result" ;; esac # Collect preopened libtool deplibs, except any this library # has declared as weak libs for deplib in $dependency_libs; do func_basename "$deplib" deplib_base=$func_basename_result case " $weak_libs " in *" $deplib_base "*) ;; *) func_append deplibs " $deplib" ;; esac done done libs="$dlprefiles" fi if test "$pass" = dlopen; then # Collect dlpreopened libraries save_deplibs="$deplibs" deplibs= fi for deplib in $libs; do lib= found=no case $deplib in -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append compiler_flags " $deplib" if test "$linkmode" = lib ; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -l*) if test "$linkmode" != lib && test "$linkmode" != prog; then func_warning "\`-l' is ignored for archives/objects" continue fi func_stripname '-l' '' "$deplib" name=$func_stripname_result if test "$linkmode" = lib; then searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" else searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" fi for searchdir in $searchdirs; do for search_ext in .la $std_shrext .so .a; do # Search the libtool library lib="$searchdir/lib${name}${search_ext}" if test -f "$lib"; then if test "$search_ext" = ".la"; then found=yes else found=no fi break 2 fi done done if test "$found" != yes; then # deplib doesn't seem to be a libtool library if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" fi continue else # deplib is a libtool library # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, # We need to do some special things here, and not later. if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $deplib "*) if func_lalib_p "$lib"; then library_names= old_library= func_source "$lib" for l in $old_library $library_names; do ll="$l" done if test "X$ll" = "X$old_library" ; then # only static version available found=no func_dirname "$lib" "" "." ladir="$func_dirname_result" lib=$ladir/$old_library if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" fi continue fi fi ;; *) ;; esac fi fi ;; # -l *.ltframework) if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" if test "$linkmode" = lib ; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -L*) case $linkmode in lib) deplibs="$deplib $deplibs" test "$pass" = conv && continue newdependency_libs="$deplib $newdependency_libs" func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; prog) if test "$pass" = conv; then deplibs="$deplib $deplibs" continue fi if test "$pass" = scan; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; *) func_warning "\`-L' is ignored for archives/objects" ;; esac # linkmode continue ;; # -L -R*) if test "$pass" = link; then func_stripname '-R' '' "$deplib" func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # Make sure the xrpath contains only unique directories. case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac fi deplibs="$deplib $deplibs" continue ;; *.la) func_resolve_sysroot "$deplib" lib=$func_resolve_sysroot_result ;; *.$libext) if test "$pass" = conv; then deplibs="$deplib $deplibs" continue fi case $linkmode in lib) # Linking convenience modules into shared libraries is allowed, # but linking other static libraries is non-portable. case " $dlpreconveniencelibs " in *" $deplib "*) ;; *) valid_a_lib=no case $deplibs_check_method in match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ | $EGREP "$match_pattern_regex" > /dev/null; then valid_a_lib=yes fi ;; pass_all) valid_a_lib=yes ;; esac if test "$valid_a_lib" != yes; then echo $ECHO "*** Warning: Trying to link with static lib archive $deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because the file extensions .$libext of this argument makes me believe" echo "*** that it is just a static archive that I should not use here." else echo $ECHO "*** Warning: Linking the shared library $output against the" $ECHO "*** static library $deplib is not portable!" deplibs="$deplib $deplibs" fi ;; esac continue ;; prog) if test "$pass" != link; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi continue ;; esac # linkmode ;; # *.$libext *.lo | *.$objext) if test "$pass" = conv; then deplibs="$deplib $deplibs" elif test "$linkmode" = prog; then if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then # If there is no dlopen support or we're linking statically, # we need to preload. func_append newdlprefiles " $deplib" compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append newdlfiles " $deplib" fi fi continue ;; %DEPLIBS%) alldeplibs=yes continue ;; esac # case $deplib if test "$found" = yes || test -f "$lib"; then : else func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'" fi # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$lib" \ || func_fatal_error "\`$lib' is not a valid libtool archive" func_dirname "$lib" "" "." ladir="$func_dirname_result" dlname= dlopen= dlpreopen= libdir= library_names= old_library= inherited_linker_flags= # If the library was installed with an old release of libtool, # it will not redefine variables installed, or shouldnotlink installed=yes shouldnotlink=no avoidtemprpath= # Read the .la file func_source "$lib" # Convert "-framework foo" to "foo.ltframework" if test -n "$inherited_linker_flags"; then tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do case " $new_inherited_linker_flags " in *" $tmp_inherited_linker_flag "*) ;; *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; esac done fi dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` if test "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan" || { test "$linkmode" != prog && test "$linkmode" != lib; }; then test -n "$dlopen" && func_append dlfiles " $dlopen" test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" fi if test "$pass" = conv; then # Only check for convenience libraries deplibs="$lib $deplibs" if test -z "$libdir"; then if test -z "$old_library"; then func_fatal_error "cannot find name of link library for \`$lib'" fi # It is a libtool convenience library, so add in its objects. func_append convenience " $ladir/$objdir/$old_library" func_append old_convenience " $ladir/$objdir/$old_library" tmp_libs= for deplib in $dependency_libs; do deplibs="$deplib $deplibs" if $opt_preserve_dup_deps ; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done elif test "$linkmode" != prog && test "$linkmode" != lib; then func_fatal_error "\`$lib' is not a convenience library" fi continue fi # $pass = conv # Get the name of the library we link against. linklib= if test -n "$old_library" && { test "$prefer_static_libs" = yes || test "$prefer_static_libs,$installed" = "built,no"; }; then linklib=$old_library else for l in $old_library $library_names; do linklib="$l" done fi if test -z "$linklib"; then func_fatal_error "cannot find name of link library for \`$lib'" fi # This library was specified with -dlopen. if test "$pass" = dlopen; then if test -z "$libdir"; then func_fatal_error "cannot -dlopen a convenience library: \`$lib'" fi if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then # If there is no dlname, no dlopen support or we're linking # statically, we need to preload. We also need to preload any # dependent libraries so libltdl's deplib preloader doesn't # bomb out in the load deplibs phase. func_append dlprefiles " $lib $dependency_libs" else func_append newdlfiles " $lib" fi continue fi # $pass = dlopen # We need an absolute path. case $ladir in [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; *) abs_ladir=`cd "$ladir" && pwd` if test -z "$abs_ladir"; then func_warning "cannot determine absolute directory name of \`$ladir'" func_warning "passing it literally to the linker, although it might fail" abs_ladir="$ladir" fi ;; esac func_basename "$lib" laname="$func_basename_result" # Find the relevant object directory and library name. if test "X$installed" = Xyes; then if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then func_warning "library \`$lib' was moved." dir="$ladir" absdir="$abs_ladir" libdir="$abs_ladir" else dir="$lt_sysroot$libdir" absdir="$lt_sysroot$libdir" fi test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes else if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then dir="$ladir" absdir="$abs_ladir" # Remove this search path later func_append notinst_path " $abs_ladir" else dir="$ladir/$objdir" absdir="$abs_ladir/$objdir" # Remove this search path later func_append notinst_path " $abs_ladir" fi fi # $installed = yes func_stripname 'lib' '.la' "$laname" name=$func_stripname_result # This library was specified with -dlpreopen. if test "$pass" = dlpreopen; then if test -z "$libdir" && test "$linkmode" = prog; then func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'" fi case "$host" in # special handling for platforms with PE-DLLs. *cygwin* | *mingw* | *cegcc* ) # Linker will automatically link against shared library if both # static and shared are present. Therefore, ensure we extract # symbols from the import library if a shared library is present # (otherwise, the dlopen module name will be incorrect). We do # this by putting the import library name into $newdlprefiles. # We recover the dlopen module name by 'saving' the la file # name in a special purpose variable, and (later) extracting the # dlname from the la file. if test -n "$dlname"; then func_tr_sh "$dir/$linklib" eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" func_append newdlprefiles " $dir/$linklib" else func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" fi ;; * ) # Prefer using a static library (so that no silly _DYNAMIC symbols # are required to link). if test -n "$old_library"; then func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" # Otherwise, use the dlname, so that lt_dlopen finds it. elif test -n "$dlname"; then func_append newdlprefiles " $dir/$dlname" else func_append newdlprefiles " $dir/$linklib" fi ;; esac fi # $pass = dlpreopen if test -z "$libdir"; then # Link the convenience library if test "$linkmode" = lib; then deplibs="$dir/$old_library $deplibs" elif test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$dir/$old_library $compile_deplibs" finalize_deplibs="$dir/$old_library $finalize_deplibs" else deplibs="$lib $deplibs" # used for prog,scan pass fi continue fi if test "$linkmode" = prog && test "$pass" != link; then func_append newlib_search_path " $ladir" deplibs="$lib $deplibs" linkalldeplibs=no if test "$link_all_deplibs" != no || test -z "$library_names" || test "$build_libtool_libs" = no; then linkalldeplibs=yes fi tmp_libs= for deplib in $dependency_libs; do case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; esac # Need to link against all dependency_libs? if test "$linkalldeplibs" = yes; then deplibs="$deplib $deplibs" else # Need to hardcode shared library paths # or/and link against static libraries newdependency_libs="$deplib $newdependency_libs" fi if $opt_preserve_dup_deps ; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done # for deplib continue fi # $linkmode = prog... if test "$linkmode,$pass" = "prog,link"; then if test -n "$library_names" && { { test "$prefer_static_libs" = no || test "$prefer_static_libs,$installed" = "built,yes"; } || test -z "$old_library"; }; then # We need to hardcode the library path if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then # Make sure the rpath contains only unique directories. case "$temp_rpath:" in *"$absdir:"*) ;; *) func_append temp_rpath "$absdir:" ;; esac fi # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi # $linkmode,$pass = prog,link... if test "$alldeplibs" = yes && { test "$deplibs_check_method" = pass_all || { test "$build_libtool_libs" = yes && test -n "$library_names"; }; }; then # We only need to search for static libraries continue fi fi link_static=no # Whether the deplib will be linked statically use_static_libs=$prefer_static_libs if test "$use_static_libs" = built && test "$installed" = yes; then use_static_libs=no fi if test -n "$library_names" && { test "$use_static_libs" = no || test -z "$old_library"; }; then case $host in *cygwin* | *mingw* | *cegcc*) # No point in relinking DLLs because paths are not encoded func_append notinst_deplibs " $lib" need_relink=no ;; *) if test "$installed" = no; then func_append notinst_deplibs " $lib" need_relink=yes fi ;; esac # This is a shared library # Warn about portability, can't link against -module's on some # systems (darwin). Don't bleat about dlopened modules though! dlopenmodule="" for dlpremoduletest in $dlprefiles; do if test "X$dlpremoduletest" = "X$lib"; then dlopenmodule="$dlpremoduletest" break fi done if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then echo if test "$linkmode" = prog; then $ECHO "*** Warning: Linking the executable $output against the loadable module" else $ECHO "*** Warning: Linking the shared library $output against the loadable module" fi $ECHO "*** $linklib is not portable!" fi if test "$linkmode" = lib && test "$hardcode_into_libs" = yes; then # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi if test -n "$old_archive_from_expsyms_cmds"; then # figure out the soname set dummy $library_names shift realname="$1" shift libname=`eval "\\$ECHO \"$libname_spec\""` # use dlname if we got it. it's perfectly good, no? if test -n "$dlname"; then soname="$dlname" elif test -n "$soname_spec"; then # bleh windows case $host in *cygwin* | mingw* | *cegcc*) func_arith $current - $age major=$func_arith_result versuffix="-$major" ;; esac eval soname=\"$soname_spec\" else soname="$realname" fi # Make a new name for the extract_expsyms_cmds to use soroot="$soname" func_basename "$soroot" soname="$func_basename_result" func_stripname 'lib' '.dll' "$soname" newlib=libimp-$func_stripname_result.a # If the library has no export list, then create one now if test -f "$output_objdir/$soname-def"; then : else func_verbose "extracting exported symbol list from \`$soname'" func_execute_cmds "$extract_expsyms_cmds" 'exit $?' fi # Create $newlib if test -f "$output_objdir/$newlib"; then :; else func_verbose "generating import library for \`$soname'" func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' fi # make sure the library variables are pointing to the new library dir=$output_objdir linklib=$newlib fi # test -n "$old_archive_from_expsyms_cmds" if test "$linkmode" = prog || test "$opt_mode" != relink; then add_shlibpath= add_dir= add= lib_linked=yes case $hardcode_action in immediate | unsupported) if test "$hardcode_direct" = no; then add="$dir/$linklib" case $host in *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; *-*-sysv4*uw2*) add_dir="-L$dir" ;; *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ *-*-unixware7*) add_dir="-L$dir" ;; *-*-darwin* ) # if the lib is a (non-dlopened) module then we can not # link against it, someone is ignoring the earlier warnings if /usr/bin/file -L $add 2> /dev/null | $GREP ": [^:]* bundle" >/dev/null ; then if test "X$dlopenmodule" != "X$lib"; then $ECHO "*** Warning: lib $linklib is a module, not a shared library" if test -z "$old_library" ; then echo echo "*** And there doesn't seem to be a static archive available" echo "*** The link will probably fail, sorry" else add="$dir/$old_library" fi elif test -n "$old_library"; then add="$dir/$old_library" fi fi esac elif test "$hardcode_minus_L" = no; then case $host in *-*-sunos*) add_shlibpath="$dir" ;; esac add_dir="-L$dir" add="-l$name" elif test "$hardcode_shlibpath_var" = no; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; relink) if test "$hardcode_direct" = yes && test "$hardcode_direct_absolute" = no; then add="$dir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$absdir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; *) lib_linked=no ;; esac if test "$lib_linked" != yes; then func_fatal_configuration "unsupported hardcode properties" fi if test -n "$add_shlibpath"; then case :$compile_shlibpath: in *":$add_shlibpath:"*) ;; *) func_append compile_shlibpath "$add_shlibpath:" ;; esac fi if test "$linkmode" = prog; then test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" test -n "$add" && compile_deplibs="$add $compile_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" if test "$hardcode_direct" != yes && test "$hardcode_minus_L" != yes && test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac fi fi fi if test "$linkmode" = prog || test "$opt_mode" = relink; then add_shlibpath= add_dir= add= # Finalize command for both is simple: just hardcode it. if test "$hardcode_direct" = yes && test "$hardcode_direct_absolute" = no; then add="$libdir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$libdir" add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac add="-l$name" elif test "$hardcode_automatic" = yes; then if test -n "$inst_prefix_dir" && test -f "$inst_prefix_dir$libdir/$linklib" ; then add="$inst_prefix_dir$libdir/$linklib" else add="$libdir/$linklib" fi else # We cannot seem to hardcode it, guess we'll fake it. add_dir="-L$libdir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add="-l$name" fi if test "$linkmode" = prog; then test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" test -n "$add" && finalize_deplibs="$add $finalize_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" fi fi elif test "$linkmode" = prog; then # Here we assume that one of hardcode_direct or hardcode_minus_L # is not unsupported. This is valid on all known static and # shared platforms. if test "$hardcode_direct" != unsupported; then test -n "$old_library" && linklib="$old_library" compile_deplibs="$dir/$linklib $compile_deplibs" finalize_deplibs="$dir/$linklib $finalize_deplibs" else compile_deplibs="-l$name -L$dir $compile_deplibs" finalize_deplibs="-l$name -L$dir $finalize_deplibs" fi elif test "$build_libtool_libs" = yes; then # Not a shared library if test "$deplibs_check_method" != pass_all; then # We're trying link a shared library against a static one # but the system doesn't support it. # Just print a warning and add the library to dependency_libs so # that the program can be linked against the static library. echo $ECHO "*** Warning: This system can not link to static lib archive $lib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have." if test "$module" = yes; then echo "*** But as you try to build a module library, libtool will still create " echo "*** a static module, that should work as long as the dlopening application" echo "*** is linked with the -dlopen flag to resolve symbols at runtime." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using \`nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** \`nm' from GNU binutils and a full rebuild may help." fi if test "$build_old_libs" = no; then build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi else deplibs="$dir/$old_library $deplibs" link_static=yes fi fi # link shared/static library? if test "$linkmode" = lib; then if test -n "$dependency_libs" && { test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes || test "$link_static" = yes; }; then # Extract -R from dependency_libs temp_deplibs= for libdir in $dependency_libs; do case $libdir in -R*) func_stripname '-R' '' "$libdir" temp_xrpath=$func_stripname_result case " $xrpath " in *" $temp_xrpath "*) ;; *) func_append xrpath " $temp_xrpath";; esac;; *) func_append temp_deplibs " $libdir";; esac done dependency_libs="$temp_deplibs" fi func_append newlib_search_path " $absdir" # Link against this library test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" # ... and its dependency_libs tmp_libs= for deplib in $dependency_libs; do newdependency_libs="$deplib $newdependency_libs" case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result";; *) func_resolve_sysroot "$deplib" ;; esac if $opt_preserve_dup_deps ; then case "$tmp_libs " in *" $func_resolve_sysroot_result "*) func_append specialdeplibs " $func_resolve_sysroot_result" ;; esac fi func_append tmp_libs " $func_resolve_sysroot_result" done if test "$link_all_deplibs" != no; then # Add the search paths of all dependency libraries for deplib in $dependency_libs; do path= case $deplib in -L*) path="$deplib" ;; *.la) func_resolve_sysroot "$deplib" deplib=$func_resolve_sysroot_result func_dirname "$deplib" "" "." dir=$func_dirname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then func_warning "cannot determine absolute directory name of \`$dir'" absdir="$dir" fi ;; esac if $GREP "^installed=no" $deplib > /dev/null; then case $host in *-*-darwin*) depdepl= eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` if test -n "$deplibrary_names" ; then for tmp in $deplibrary_names ; do depdepl=$tmp done if test -f "$absdir/$objdir/$depdepl" ; then depdepl="$absdir/$objdir/$depdepl" darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` if test -z "$darwin_install_name"; then darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` fi func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}" path= fi fi ;; *) path="-L$absdir/$objdir" ;; esac else eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` test -z "$libdir" && \ func_fatal_error "\`$deplib' is not a valid libtool archive" test "$absdir" != "$libdir" && \ func_warning "\`$deplib' seems to be moved" path="-L$absdir" fi ;; esac case " $deplibs " in *" $path "*) ;; *) deplibs="$path $deplibs" ;; esac done fi # link_all_deplibs != no fi # linkmode = lib done # for deplib in $libs if test "$pass" = link; then if test "$linkmode" = "prog"; then compile_deplibs="$new_inherited_linker_flags $compile_deplibs" finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" else compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` fi fi dependency_libs="$newdependency_libs" if test "$pass" = dlpreopen; then # Link the dlpreopened libraries before other libraries for deplib in $save_deplibs; do deplibs="$deplib $deplibs" done fi if test "$pass" != dlopen; then if test "$pass" != conv; then # Make sure lib_search_path contains only unique directories. lib_search_path= for dir in $newlib_search_path; do case "$lib_search_path " in *" $dir "*) ;; *) func_append lib_search_path " $dir" ;; esac done newlib_search_path= fi if test "$linkmode,$pass" != "prog,link"; then vars="deplibs" else vars="compile_deplibs finalize_deplibs" fi for var in $vars dependency_libs; do # Add libraries to $var in reverse order eval tmp_libs=\"\$$var\" new_libs= for deplib in $tmp_libs; do # FIXME: Pedantically, this is the right thing to do, so # that some nasty dependency loop isn't accidentally # broken: #new_libs="$deplib $new_libs" # Pragmatically, this seems to cause very few problems in # practice: case $deplib in -L*) new_libs="$deplib $new_libs" ;; -R*) ;; *) # And here is the reason: when a library appears more # than once as an explicit dependence of a library, or # is implicitly linked in more than once by the # compiler, it is considered special, and multiple # occurrences thereof are not removed. Compare this # with having the same library being listed as a # dependency of multiple other libraries: in this case, # we know (pedantically, we assume) the library does not # need to be listed more than once, so we keep only the # last copy. This is not always right, but it is rare # enough that we require users that really mean to play # such unportable linking tricks to link the library # using -Wl,-lname, so that libtool does not consider it # for duplicate removal. case " $specialdeplibs " in *" $deplib "*) new_libs="$deplib $new_libs" ;; *) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$deplib $new_libs" ;; esac ;; esac ;; esac done tmp_libs= for deplib in $new_libs; do case $deplib in -L*) case " $tmp_libs " in *" $deplib "*) ;; *) func_append tmp_libs " $deplib" ;; esac ;; *) func_append tmp_libs " $deplib" ;; esac done eval $var=\"$tmp_libs\" done # for var fi # Last step: remove runtime libs from dependency_libs # (they stay in deplibs) tmp_libs= for i in $dependency_libs ; do case " $predeps $postdeps $compiler_lib_search_path " in *" $i "*) i="" ;; esac if test -n "$i" ; then func_append tmp_libs " $i" fi done dependency_libs=$tmp_libs done # for pass if test "$linkmode" = prog; then dlfiles="$newdlfiles" fi if test "$linkmode" = prog || test "$linkmode" = lib; then dlprefiles="$newdlprefiles" fi case $linkmode in oldlib) if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then func_warning "\`-dlopen' is ignored for archives" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "\`-l' and \`-L' are ignored for archives" ;; esac test -n "$rpath" && \ func_warning "\`-rpath' is ignored for archives" test -n "$xrpath" && \ func_warning "\`-R' is ignored for archives" test -n "$vinfo" && \ func_warning "\`-version-info/-version-number' is ignored for archives" test -n "$release" && \ func_warning "\`-release' is ignored for archives" test -n "$export_symbols$export_symbols_regex" && \ func_warning "\`-export-symbols' is ignored for archives" # Now set the variables for building old libraries. build_libtool_libs=no oldlibs="$output" func_append objs "$old_deplibs" ;; lib) # Make sure we only generate libraries of the form `libNAME.la'. case $outputname in lib*) func_stripname 'lib' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" ;; *) test "$module" = no && \ func_fatal_help "libtool library \`$output' must begin with \`lib'" if test "$need_lib_prefix" != no; then # Add the "lib" prefix for modules if required func_stripname '' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" else func_stripname '' '.la' "$outputname" libname=$func_stripname_result fi ;; esac if test -n "$objs"; then if test "$deplibs_check_method" != pass_all; then func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs" else echo $ECHO "*** Warning: Linking the shared library $output against the non-libtool" $ECHO "*** objects $objs is not portable!" func_append libobjs " $objs" fi fi test "$dlself" != no && \ func_warning "\`-dlopen self' is ignored for libtool libraries" set dummy $rpath shift test "$#" -gt 1 && \ func_warning "ignoring multiple \`-rpath's for a libtool library" install_libdir="$1" oldlibs= if test -z "$rpath"; then if test "$build_libtool_libs" = yes; then # Building a libtool convenience library. # Some compilers have problems with a `.al' extension so # convenience libraries should have the same extension an # archive normally would. oldlibs="$output_objdir/$libname.$libext $oldlibs" build_libtool_libs=convenience build_old_libs=yes fi test -n "$vinfo" && \ func_warning "\`-version-info/-version-number' is ignored for convenience libraries" test -n "$release" && \ func_warning "\`-release' is ignored for convenience libraries" else # Parse the version information argument. save_ifs="$IFS"; IFS=':' set dummy $vinfo 0 0 0 shift IFS="$save_ifs" test -n "$7" && \ func_fatal_help "too many parameters to \`-version-info'" # convert absolute version numbers to libtool ages # this retains compatibility with .la files and attempts # to make the code below a bit more comprehensible case $vinfo_number in yes) number_major="$1" number_minor="$2" number_revision="$3" # # There are really only two kinds -- those that # use the current revision as the major version # and those that subtract age and use age as # a minor version. But, then there is irix # which has an extra 1 added just for fun # case $version_type in # correct linux to gnu/linux during the next big refactor darwin|linux|osf|windows|none) func_arith $number_major + $number_minor current=$func_arith_result age="$number_minor" revision="$number_revision" ;; freebsd-aout|freebsd-elf|qnx|sunos) current="$number_major" revision="$number_minor" age="0" ;; irix|nonstopux) func_arith $number_major + $number_minor current=$func_arith_result age="$number_minor" revision="$number_minor" lt_irix_increment=no ;; *) func_fatal_configuration "$modename: unknown library version type \`$version_type'" ;; esac ;; no) current="$1" revision="$2" age="$3" ;; esac # Check that each of the things are valid numbers. case $current in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "CURRENT \`$current' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac case $revision in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "REVISION \`$revision' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac case $age in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "AGE \`$age' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac if test "$age" -gt "$current"; then func_error "AGE \`$age' is greater than the current interface number \`$current'" func_fatal_error "\`$vinfo' is not valid version information" fi # Calculate the version variables. major= versuffix= verstring= case $version_type in none) ;; darwin) # Like Linux, but with the current version available in # verstring for coding it into the library header func_arith $current - $age major=.$func_arith_result versuffix="$major.$age.$revision" # Darwin ld doesn't like 0 for these options... func_arith $current + 1 minor_current=$func_arith_result xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" ;; freebsd-aout) major=".$current" versuffix=".$current.$revision"; ;; freebsd-elf) major=".$current" versuffix=".$current" ;; irix | nonstopux) if test "X$lt_irix_increment" = "Xno"; then func_arith $current - $age else func_arith $current - $age + 1 fi major=$func_arith_result case $version_type in nonstopux) verstring_prefix=nonstopux ;; *) verstring_prefix=sgi ;; esac verstring="$verstring_prefix$major.$revision" # Add in all the interfaces that we are compatible with. loop=$revision while test "$loop" -ne 0; do func_arith $revision - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring="$verstring_prefix$major.$iface:$verstring" done # Before this point, $major must not contain `.'. major=.$major versuffix="$major.$revision" ;; linux) # correct to gnu/linux during the next big refactor func_arith $current - $age major=.$func_arith_result versuffix="$major.$age.$revision" ;; osf) func_arith $current - $age major=.$func_arith_result versuffix=".$current.$age.$revision" verstring="$current.$age.$revision" # Add in all the interfaces that we are compatible with. loop=$age while test "$loop" -ne 0; do func_arith $current - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring="$verstring:${iface}.0" done # Make executables depend on our current version. func_append verstring ":${current}.0" ;; qnx) major=".$current" versuffix=".$current" ;; sunos) major=".$current" versuffix=".$current.$revision" ;; windows) # Use '-' rather than '.', since we only want one # extension on DOS 8.3 filesystems. func_arith $current - $age major=$func_arith_result versuffix="-$major" ;; *) func_fatal_configuration "unknown library version type \`$version_type'" ;; esac # Clear the version info if we defaulted, and they specified a release. if test -z "$vinfo" && test -n "$release"; then major= case $version_type in darwin) # we can't check for "0.0" in archive_cmds due to quoting # problems, so we reset it completely verstring= ;; *) verstring="0.0" ;; esac if test "$need_version" = no; then versuffix= else versuffix=".0.0" fi fi # Remove version info from name if versioning should be avoided if test "$avoid_version" = yes && test "$need_version" = no; then major= versuffix= verstring="" fi # Check to see if the archive will have undefined symbols. if test "$allow_undefined" = yes; then if test "$allow_undefined_flag" = unsupported; then func_warning "undefined symbols not allowed in $host shared libraries" build_libtool_libs=no build_old_libs=yes fi else # Don't allow undefined symbols. allow_undefined_flag="$no_undefined_flag" fi fi func_generate_dlsyms "$libname" "$libname" "yes" func_append libobjs " $symfileobj" test "X$libobjs" = "X " && libobjs= if test "$opt_mode" != relink; then # Remove our outputs, but don't remove object files since they # may have been created when compiling PIC objects. removelist= tempremovelist=`$ECHO "$output_objdir/*"` for p in $tempremovelist; do case $p in *.$objext | *.gcno) ;; $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) if test "X$precious_files_regex" != "X"; then if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 then continue fi fi func_append removelist " $p" ;; *) ;; esac done test -n "$removelist" && \ func_show_eval "${RM}r \$removelist" fi # Now set the variables for building old libraries. if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then func_append oldlibs " $output_objdir/$libname.$libext" # Transform .lo files to .o files. oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP` fi # Eliminate all temporary directories. #for path in $notinst_path; do # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` #done if test -n "$xrpath"; then # If the user specified any rpath flags, then add them. temp_xrpath= for libdir in $xrpath; do func_replace_sysroot "$libdir" func_append temp_xrpath " -R$func_replace_sysroot_result" case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then dependency_libs="$temp_xrpath $dependency_libs" fi fi # Make sure dlfiles contains only unique files that won't be dlpreopened old_dlfiles="$dlfiles" dlfiles= for lib in $old_dlfiles; do case " $dlprefiles $dlfiles " in *" $lib "*) ;; *) func_append dlfiles " $lib" ;; esac done # Make sure dlprefiles contains only unique files old_dlprefiles="$dlprefiles" dlprefiles= for lib in $old_dlprefiles; do case "$dlprefiles " in *" $lib "*) ;; *) func_append dlprefiles " $lib" ;; esac done if test "$build_libtool_libs" = yes; then if test -n "$rpath"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) # these systems don't actually have a c library (as such)! ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C library is in the System framework func_append deplibs " System.ltframework" ;; *-*-netbsd*) # Don't link with libc until the a.out ld.so is fixed. ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work ;; *) # Add libc to deplibs on all other systems if necessary. if test "$build_libtool_need_lc" = "yes"; then func_append deplibs " -lc" fi ;; esac fi # Transform deplibs into only deplibs that can be linked in shared. name_save=$name libname_save=$libname release_save=$release versuffix_save=$versuffix major_save=$major # I'm not sure if I'm treating the release correctly. I think # release should show up in the -l (ie -lgmp5) so we don't want to # add it in twice. Is that correct? release="" versuffix="" major="" newdeplibs= droppeddeps=no case $deplibs_check_method in pass_all) # Don't check for shared/static. Everything works. # This might be a little naive. We might want to check # whether the library exists or not. But this is on # osf3 & osf4 and I'm not really sure... Just # implementing what was already the behavior. newdeplibs=$deplibs ;; test_compile) # This code stresses the "libraries are programs" paradigm to its # limits. Maybe even breaks it. We compile a program, linking it # against the deplibs as a proxy for the library. Then we can check # whether they linked in statically or dynamically with ldd. $opt_dry_run || $RM conftest.c cat > conftest.c </dev/null` $nocaseglob else potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` fi for potent_lib in $potential_libs; do # Follow soft links. if ls -lLd "$potent_lib" 2>/dev/null | $GREP " -> " >/dev/null; then continue fi # The statement above tries to avoid entering an # endless loop below, in case of cyclic links. # We might still enter an endless loop, since a link # loop can be closed while we follow links, # but so what? potlib="$potent_lib" while test -h "$potlib" 2>/dev/null; do potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` case $potliblink in [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; *) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";; esac done if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | $SED -e 10q | $EGREP "$file_magic_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib="" break 2 fi done done fi if test -n "$a_deplib" ; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib" ; then $ECHO "*** with $libname but no candidates were found. (...for file magic test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a file magic. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` for a_deplib in $deplibs; do case $a_deplib in -l*) func_stripname -l '' "$a_deplib" name=$func_stripname_result if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $a_deplib "*) func_append newdeplibs " $a_deplib" a_deplib="" ;; esac fi if test -n "$a_deplib" ; then libname=`eval "\\$ECHO \"$libname_spec\""` for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do potential_libs=`ls $i/$libname[.-]* 2>/dev/null` for potent_lib in $potential_libs; do potlib="$potent_lib" # see symlink-check above in file_magic test if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ $EGREP "$match_pattern_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib="" break 2 fi done done fi if test -n "$a_deplib" ; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib" ; then $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a regex pattern. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; none | unknown | *) newdeplibs="" tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then for i in $predeps $postdeps ; do # can't use Xsed below, because $i might contain '/' tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"` done fi case $tmp_deplibs in *[!\ \ ]*) echo if test "X$deplibs_check_method" = "Xnone"; then echo "*** Warning: inter-library dependencies are not supported in this platform." else echo "*** Warning: inter-library dependencies are not known to be supported." fi echo "*** All declared inter-library dependencies are being dropped." droppeddeps=yes ;; esac ;; esac versuffix=$versuffix_save major=$major_save release=$release_save libname=$libname_save name=$name_save case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library with the System framework newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac if test "$droppeddeps" = yes; then if test "$module" = yes; then echo echo "*** Warning: libtool could not satisfy all declared inter-library" $ECHO "*** dependencies of module $libname. Therefore, libtool will create" echo "*** a static module, that should work as long as the dlopening" echo "*** application is linked with the -dlopen flag." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using \`nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** \`nm' from GNU binutils and a full rebuild may help." fi if test "$build_old_libs" = no; then oldlibs="$output_objdir/$libname.$libext" build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi else echo "*** The inter-library dependencies that have been dropped here will be" echo "*** automatically added whenever a program is linked with this library" echo "*** or is declared to -dlopen it." if test "$allow_undefined" = no; then echo echo "*** Since this library must not contain undefined symbols," echo "*** because either the platform does not support them or" echo "*** it was explicitly requested with -no-undefined," echo "*** libtool will only create a static version of it." if test "$build_old_libs" = no; then oldlibs="$output_objdir/$libname.$libext" build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi fi fi # Done checking deplibs! deplibs=$newdeplibs fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" case $host in *-*-darwin*) newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done deplibs="$new_libs" # All the library-specific variables (install_libdir is set above). library_names= old_library= dlname= # Test again, we may have decided not to build it any more if test "$build_libtool_libs" = yes; then # Remove ${wl} instances when linking with ld. # FIXME: should test the right _cmds variable. case $archive_cmds in *\$LD\ *) wl= ;; esac if test "$hardcode_into_libs" = yes; then # Hardcode the library paths hardcode_libdirs= dep_rpath= rpath="$finalize_rpath" test "$opt_mode" != relink && rpath="$compile_rpath$rpath" for libdir in $rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then func_replace_sysroot "$libdir" libdir=$func_replace_sysroot_result if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append dep_rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" fi if test -n "$runpath_var" && test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" fi test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" fi shlibpath="$finalize_shlibpath" test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath" if test -n "$shlibpath"; then eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" fi # Get the real and link names of the library. eval shared_ext=\"$shrext_cmds\" eval library_names=\"$library_names_spec\" set dummy $library_names shift realname="$1" shift if test -n "$soname_spec"; then eval soname=\"$soname_spec\" else soname="$realname" fi if test -z "$dlname"; then dlname=$soname fi lib="$output_objdir/$realname" linknames= for link do func_append linknames " $link" done # Use standard objects if they are pic test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` test "X$libobjs" = "X " && libobjs= delfiles= if test -n "$export_symbols" && test -n "$include_expsyms"; then $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" export_symbols="$output_objdir/$libname.uexp" func_append delfiles " $export_symbols" fi orig_export_symbols= case $host_os in cygwin* | mingw* | cegcc*) if test -n "$export_symbols" && test -z "$export_symbols_regex"; then # exporting using user supplied symfile if test "x`$SED 1q $export_symbols`" != xEXPORTS; then # and it's NOT already a .def file. Must figure out # which of the given symbols are data symbols and tag # them as such. So, trigger use of export_symbols_cmds. # export_symbols gets reassigned inside the "prepare # the list of exported symbols" if statement, so the # include_expsyms logic still works. orig_export_symbols="$export_symbols" export_symbols= always_export_symbols=yes fi fi ;; esac # Prepare the list of exported symbols if test -z "$export_symbols"; then if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then func_verbose "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $opt_dry_run || $RM $export_symbols cmds=$export_symbols_cmds save_ifs="$IFS"; IFS='~' for cmd1 in $cmds; do IFS="$save_ifs" # Take the normal branch if the nm_file_list_spec branch # doesn't work or if tool conversion is not needed. case $nm_file_list_spec~$to_tool_file_cmd in *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) try_normal_branch=yes eval cmd=\"$cmd1\" func_len " $cmd" len=$func_len_result ;; *) try_normal_branch=no ;; esac if test "$try_normal_branch" = yes \ && { test "$len" -lt "$max_cmd_len" \ || test "$max_cmd_len" -le -1; } then func_show_eval "$cmd" 'exit $?' skipped_export=false elif test -n "$nm_file_list_spec"; then func_basename "$output" output_la=$func_basename_result save_libobjs=$libobjs save_output=$output output=${output_objdir}/${output_la}.nm func_to_tool_file "$output" libobjs=$nm_file_list_spec$func_to_tool_file_result func_append delfiles " $output" func_verbose "creating $NM input file list: $output" for obj in $save_libobjs; do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > "$output" eval cmd=\"$cmd1\" func_show_eval "$cmd" 'exit $?' output=$save_output libobjs=$save_libobjs skipped_export=false else # The command line is too long to execute in one step. func_verbose "using reloadable object file for export list..." skipped_export=: # Break out early, otherwise skipped_export may be # set to false by a later but shorter cmd. break fi done IFS="$save_ifs" if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi fi if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols="$export_symbols" test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi tmp_deplibs= for test_deplib in $deplibs; do case " $convenience " in *" $test_deplib "*) ;; *) func_append tmp_deplibs " $test_deplib" ;; esac done deplibs="$tmp_deplibs" if test -n "$convenience"; then if test -n "$whole_archive_flag_spec" && test "$compiler_needs_object" = yes && test -z "$libobjs"; then # extract the archives, so we have objects to list. # TODO: could optimize this to just extract one archive. whole_archive_flag_spec= fi if test -n "$whole_archive_flag_spec"; then save_libobjs=$libobjs eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= else gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $convenience func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi fi if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then eval flag=\"$thread_safe_flag_spec\" func_append linker_flags " $flag" fi # Make a backup of the uninstalled library when relinking if test "$opt_mode" = relink; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? fi # Do each of the archive commands. if test "$module" = yes && test -n "$module_cmds" ; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then eval test_cmds=\"$module_expsym_cmds\" cmds=$module_expsym_cmds else eval test_cmds=\"$module_cmds\" cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then eval test_cmds=\"$archive_expsym_cmds\" cmds=$archive_expsym_cmds else eval test_cmds=\"$archive_cmds\" cmds=$archive_cmds fi fi if test "X$skipped_export" != "X:" && func_len " $test_cmds" && len=$func_len_result && test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then : else # The command line is too long to link in one step, link piecewise # or, if using GNU ld and skipped_export is not :, use a linker # script. # Save the value of $output and $libobjs because we want to # use them later. If we have whole_archive_flag_spec, we # want to use save_libobjs as it was before # whole_archive_flag_spec was expanded, because we can't # assume the linker understands whole_archive_flag_spec. # This may have to be revisited, in case too many # convenience libraries get linked in and end up exceeding # the spec. if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then save_libobjs=$libobjs fi save_output=$output func_basename "$output" output_la=$func_basename_result # Clear the reloadable object creation command queue and # initialize k to one. test_cmds= concat_cmds= objlist= last_robj= k=1 if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then output=${output_objdir}/${output_la}.lnkscript func_verbose "creating GNU ld script: $output" echo 'INPUT (' > $output for obj in $save_libobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done echo ')' >> $output func_append delfiles " $output" func_to_tool_file "$output" output=$func_to_tool_file_result elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then output=${output_objdir}/${output_la}.lnk func_verbose "creating linker input file list: $output" : > $output set x $save_libobjs shift firstobj= if test "$compiler_needs_object" = yes; then firstobj="$1 " shift fi for obj do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done func_append delfiles " $output" func_to_tool_file "$output" output=$firstobj\"$file_list_spec$func_to_tool_file_result\" else if test -n "$save_libobjs"; then func_verbose "creating reloadable object files..." output=$output_objdir/$output_la-${k}.$objext eval test_cmds=\"$reload_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 # Loop over the list of objects to be linked. for obj in $save_libobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result if test "X$objlist" = X || test "$len" -lt "$max_cmd_len"; then func_append objlist " $obj" else # The command $test_cmds is almost too long, add a # command to the queue. if test "$k" -eq 1 ; then # The first file doesn't have a previous command to add. reload_objs=$objlist eval concat_cmds=\"$reload_cmds\" else # All subsequent reloadable object files will link in # the last one created. reload_objs="$objlist $last_robj" eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" fi last_robj=$output_objdir/$output_la-${k}.$objext func_arith $k + 1 k=$func_arith_result output=$output_objdir/$output_la-${k}.$objext objlist=" $obj" func_len " $last_robj" func_arith $len0 + $func_len_result len=$func_arith_result fi done # Handle the remaining objects by creating one last # reloadable object file. All subsequent reloadable object # files will link in the last one created. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ reload_objs="$objlist $last_robj" eval concat_cmds=\"\${concat_cmds}$reload_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" fi func_append delfiles " $output" else output= fi if ${skipped_export-false}; then func_verbose "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $opt_dry_run || $RM $export_symbols libobjs=$output # Append the command to create the export file. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi fi test -n "$save_libobjs" && func_verbose "creating a temporary reloadable object file: $output" # Loop through the commands generated above and execute them. save_ifs="$IFS"; IFS='~' for cmd in $concat_cmds; do IFS="$save_ifs" $opt_silent || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test "$opt_mode" = relink; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS="$save_ifs" if test -n "$export_symbols_regex" && ${skipped_export-false}; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi if ${skipped_export-false}; then if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols="$export_symbols" test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi fi libobjs=$output # Restore the value of output. output=$save_output if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= fi # Expand the library linking commands again to reset the # value of $libobjs for piecewise linking. # Do each of the archive commands. if test "$module" = yes && test -n "$module_cmds" ; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then cmds=$module_expsym_cmds else cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then cmds=$archive_expsym_cmds else cmds=$archive_cmds fi fi fi if test -n "$delfiles"; then # Append the command to remove temporary files to $cmds. eval cmds=\"\$cmds~\$RM $delfiles\" fi # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $opt_silent || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test "$opt_mode" = relink; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS="$save_ifs" # Restore the uninstalled library and exit if test "$opt_mode" = relink; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? if test -n "$convenience"; then if test -z "$whole_archive_flag_spec"; then func_show_eval '${RM}r "$gentop"' fi fi exit $EXIT_SUCCESS fi # Create links to the real library. for linkname in $linknames; do if test "$realname" != "$linkname"; then func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' fi done # If -module or -export-dynamic was specified, set the dlname. if test "$module" = yes || test "$export_dynamic" = yes; then # On all known operating systems, these are identical. dlname="$soname" fi fi ;; obj) if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then func_warning "\`-dlopen' is ignored for objects" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "\`-l' and \`-L' are ignored for objects" ;; esac test -n "$rpath" && \ func_warning "\`-rpath' is ignored for objects" test -n "$xrpath" && \ func_warning "\`-R' is ignored for objects" test -n "$vinfo" && \ func_warning "\`-version-info' is ignored for objects" test -n "$release" && \ func_warning "\`-release' is ignored for objects" case $output in *.lo) test -n "$objs$old_deplibs" && \ func_fatal_error "cannot build library object \`$output' from non-libtool objects" libobj=$output func_lo2o "$libobj" obj=$func_lo2o_result ;; *) libobj= obj="$output" ;; esac # Delete the old objects. $opt_dry_run || $RM $obj $libobj # Objects from convenience libraries. This assumes # single-version convenience libraries. Whenever we create # different ones for PIC/non-PIC, this we'll have to duplicate # the extraction. reload_conv_objs= gentop= # reload_cmds runs $LD directly, so let us get rid of # -Wl from whole_archive_flag_spec and hope we can get by with # turning comma into space.. wl= if test -n "$convenience"; then if test -n "$whole_archive_flag_spec"; then eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` else gentop="$output_objdir/${obj}x" func_append generated " $gentop" func_extract_archives $gentop $convenience reload_conv_objs="$reload_objs $func_extract_archives_result" fi fi # If we're not building shared, we need to use non_pic_objs test "$build_libtool_libs" != yes && libobjs="$non_pic_objects" # Create the old-style object. reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test output="$obj" func_execute_cmds "$reload_cmds" 'exit $?' # Exit if we aren't doing a library object file. if test -z "$libobj"; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS fi if test "$build_libtool_libs" != yes; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi # Create an invalid libtool object if no PIC, so that we don't # accidentally link it into a program. # $show "echo timestamp > $libobj" # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? exit $EXIT_SUCCESS fi if test -n "$pic_flag" || test "$pic_mode" != default; then # Only do commands if we really have different PIC objects. reload_objs="$libobjs $reload_conv_objs" output="$libobj" func_execute_cmds "$reload_cmds" 'exit $?' fi if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS ;; prog) case $host in *cygwin*) func_stripname '' '.exe' "$output" output=$func_stripname_result.exe;; esac test -n "$vinfo" && \ func_warning "\`-version-info' is ignored for programs" test -n "$release" && \ func_warning "\`-release' is ignored for programs" test "$preload" = yes \ && test "$dlopen_support" = unknown \ && test "$dlopen_self" = unknown \ && test "$dlopen_self_static" = unknown && \ func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support." case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library is the System framework compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac case $host in *-*-darwin*) # Don't allow lazy linking, it breaks C++ global constructors # But is supposedly fixed on 10.4 or later (yay!). if test "$tagname" = CXX ; then case ${MACOSX_DEPLOYMENT_TARGET-10.0} in 10.[0123]) func_append compile_command " ${wl}-bind_at_load" func_append finalize_command " ${wl}-bind_at_load" ;; esac fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $compile_deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $compile_deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done compile_deplibs="$new_libs" func_append compile_command " $compile_deplibs" func_append finalize_command " $finalize_deplibs" if test -n "$rpath$xrpath"; then # If the user specified any rpath flags, then add them. for libdir in $rpath $xrpath; do # This is the magic to use -rpath. case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done fi # Now hardcode the library paths rpath= hardcode_libdirs= for libdir in $compile_rpath $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` case :$dllsearchpath: in *":$libdir:"*) ;; ::) dllsearchpath=$libdir;; *) func_append dllsearchpath ":$libdir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi compile_rpath="$rpath" rpath= hardcode_libdirs= for libdir in $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$finalize_perm_rpath " in *" $libdir "*) ;; *) func_append finalize_perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi finalize_rpath="$rpath" if test -n "$libobjs" && test "$build_old_libs" = yes; then # Transform all the library objects into standard objects. compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` fi func_generate_dlsyms "$outputname" "@PROGRAM@" "no" # template prelinking step if test -n "$prelink_cmds"; then func_execute_cmds "$prelink_cmds" 'exit $?' fi wrappers_required=yes case $host in *cegcc* | *mingw32ce*) # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. wrappers_required=no ;; *cygwin* | *mingw* ) if test "$build_libtool_libs" != yes; then wrappers_required=no fi ;; *) if test "$need_relink" = no || test "$build_libtool_libs" != yes; then wrappers_required=no fi ;; esac if test "$wrappers_required" = no; then # Replace the output file specification. compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` link_command="$compile_command$compile_rpath" # We have no uninstalled library dependencies, so finalize right now. exit_status=0 func_show_eval "$link_command" 'exit_status=$?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Delete the generated files. if test -f "$output_objdir/${outputname}S.${objext}"; then func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"' fi exit $exit_status fi if test -n "$compile_shlibpath$finalize_shlibpath"; then compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" fi if test -n "$finalize_shlibpath"; then finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" fi compile_var= finalize_var= if test -n "$runpath_var"; then if test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done compile_var="$runpath_var=\"$rpath\$$runpath_var\" " fi if test -n "$finalize_perm_rpath"; then # We should set the runpath_var. rpath= for dir in $finalize_perm_rpath; do func_append rpath "$dir:" done finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " fi fi if test "$no_install" = yes; then # We don't need to create a wrapper script. link_command="$compile_var$compile_command$compile_rpath" # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` # Delete the old output file. $opt_dry_run || $RM $output # Link the executable and exit func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi exit $EXIT_SUCCESS fi if test "$hardcode_action" = relink; then # Fast installation is not supported link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" func_warning "this platform does not like uninstalled shared libraries" func_warning "\`$output' will be relinked during installation" else if test "$fast_install" != no; then link_command="$finalize_var$compile_command$finalize_rpath" if test "$fast_install" = yes; then relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` else # fast_install is set to needless relink_command= fi else link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" fi fi # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` # Delete the old output files. $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output_objdir/$outputname" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Now create the wrapper script. func_verbose "creating $output" # Quote the relink command for shipping. if test -n "$relink_command"; then # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done relink_command="(cd `pwd`; $relink_command)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` fi # Only actually do things if not in dry run mode. $opt_dry_run || { # win32 will think the script is a binary if it has # a .exe suffix, so we strip it off here. case $output in *.exe) func_stripname '' '.exe' "$output" output=$func_stripname_result ;; esac # test for cygwin because mv fails w/o .exe extensions case $host in *cygwin*) exeext=.exe func_stripname '' '.exe' "$outputname" outputname=$func_stripname_result ;; *) exeext= ;; esac case $host in *cygwin* | *mingw* ) func_dirname_and_basename "$output" "" "." output_name=$func_basename_result output_path=$func_dirname_result cwrappersource="$output_path/$objdir/lt-$output_name.c" cwrapper="$output_path/$output_name.exe" $RM $cwrappersource $cwrapper trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 func_emit_cwrapperexe_src > $cwrappersource # The wrapper executable is built using the $host compiler, # because it contains $host paths and files. If cross- # compiling, it, like the target executable, must be # executed on the $host or under an emulation environment. $opt_dry_run || { $LTCC $LTCFLAGS -o $cwrapper $cwrappersource $STRIP $cwrapper } # Now, create the wrapper script for func_source use: func_ltwrapper_scriptname $cwrapper $RM $func_ltwrapper_scriptname_result trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 $opt_dry_run || { # note: this script will not be executed, so do not chmod. if test "x$build" = "x$host" ; then $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result else func_emit_wrapper no > $func_ltwrapper_scriptname_result fi } ;; * ) $RM $output trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 func_emit_wrapper no > $output chmod +x $output ;; esac } exit $EXIT_SUCCESS ;; esac # See if we need to build an old-fashioned archive. for oldlib in $oldlibs; do if test "$build_libtool_libs" = convenience; then oldobjs="$libobjs_save $symfileobj" addlibs="$convenience" build_libtool_libs=no else if test "$build_libtool_libs" = module; then oldobjs="$libobjs_save" build_libtool_libs=no else oldobjs="$old_deplibs $non_pic_objects" if test "$preload" = yes && test -f "$symfileobj"; then func_append oldobjs " $symfileobj" fi fi addlibs="$old_convenience" fi if test -n "$addlibs"; then gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $addlibs func_append oldobjs " $func_extract_archives_result" fi # Do each command in the archive commands. if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then cmds=$old_archive_from_new_cmds else # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append oldobjs " $func_extract_archives_result" fi # POSIX demands no paths to be encoded in archives. We have # to avoid creating archives with duplicate basenames if we # might have to extract them afterwards, e.g., when creating a # static archive out of a convenience library, or when linking # the entirety of a libtool archive into another (currently # not supported by libtool). if (for obj in $oldobjs do func_basename "$obj" $ECHO "$func_basename_result" done | sort | sort -uc >/dev/null 2>&1); then : else echo "copying selected object files to avoid basename conflicts..." gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_mkdir_p "$gentop" save_oldobjs=$oldobjs oldobjs= counter=1 for obj in $save_oldobjs do func_basename "$obj" objbase="$func_basename_result" case " $oldobjs " in " ") oldobjs=$obj ;; *[\ /]"$objbase "*) while :; do # Make sure we don't pick an alternate name that also # overlaps. newobj=lt$counter-$objbase func_arith $counter + 1 counter=$func_arith_result case " $oldobjs " in *[\ /]"$newobj "*) ;; *) if test ! -f "$gentop/$newobj"; then break; fi ;; esac done func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" func_append oldobjs " $gentop/$newobj" ;; *) func_append oldobjs " $obj" ;; esac done fi func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result eval cmds=\"$old_archive_cmds\" func_len " $cmds" len=$func_len_result if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then cmds=$old_archive_cmds elif test -n "$archiver_list_spec"; then func_verbose "using command file archive linking..." for obj in $oldobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > $output_objdir/$libname.libcmd func_to_tool_file "$output_objdir/$libname.libcmd" oldobjs=" $archiver_list_spec$func_to_tool_file_result" cmds=$old_archive_cmds else # the command line is too long to link in one step, link in parts func_verbose "using piecewise archive linking..." save_RANLIB=$RANLIB RANLIB=: objlist= concat_cmds= save_oldobjs=$oldobjs oldobjs= # Is there a better way of finding the last object in the list? for obj in $save_oldobjs do last_oldobj=$obj done eval test_cmds=\"$old_archive_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 for obj in $save_oldobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result func_append objlist " $obj" if test "$len" -lt "$max_cmd_len"; then : else # the above command should be used before it gets too long oldobjs=$objlist if test "$obj" = "$last_oldobj" ; then RANLIB=$save_RANLIB fi test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" objlist= len=$len0 fi done RANLIB=$save_RANLIB oldobjs=$objlist if test "X$oldobjs" = "X" ; then eval cmds=\"\$concat_cmds\" else eval cmds=\"\$concat_cmds~\$old_archive_cmds\" fi fi fi func_execute_cmds "$cmds" 'exit $?' done test -n "$generated" && \ func_show_eval "${RM}r$generated" # Now create the libtool archive. case $output in *.la) old_library= test "$build_old_libs" = yes && old_library="$libname.$libext" func_verbose "creating $output" # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done # Quote the link command for shipping. relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` if test "$hardcode_automatic" = yes ; then relink_command= fi # Only create the output if not a dry run. $opt_dry_run || { for installed in no yes; do if test "$installed" = yes; then if test -z "$install_libdir"; then break fi output="$output_objdir/$outputname"i # Replace all uninstalled libtool libraries with the installed ones newdependency_libs= for deplib in $dependency_libs; do case $deplib in *.la) func_basename "$deplib" name="$func_basename_result" func_resolve_sysroot "$deplib" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` test -z "$libdir" && \ func_fatal_error "\`$deplib' is not a valid libtool archive" func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" ;; -L*) func_stripname -L '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -L$func_replace_sysroot_result" ;; -R*) func_stripname -R '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -R$func_replace_sysroot_result" ;; *) func_append newdependency_libs " $deplib" ;; esac done dependency_libs="$newdependency_libs" newdlfiles= for lib in $dlfiles; do case $lib in *.la) func_basename "$lib" name="$func_basename_result" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "\`$lib' is not a valid libtool archive" func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" ;; *) func_append newdlfiles " $lib" ;; esac done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do case $lib in *.la) # Only pass preopened files to the pseudo-archive (for # eventual linking with the app. that links it) if we # didn't already link the preopened objects directly into # the library: func_basename "$lib" name="$func_basename_result" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "\`$lib' is not a valid libtool archive" func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" ;; esac done dlprefiles="$newdlprefiles" else newdlfiles= for lib in $dlfiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlfiles " $abs" done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlprefiles " $abs" done dlprefiles="$newdlprefiles" fi $RM $output # place dlname in correct position for cygwin # In fact, it would be nice if we could use this code for all target # systems that can't hard-code library paths into their executables # and that have no shared library path variable independent of PATH, # but it turns out we can't easily determine that from inspecting # libtool variables, so we have to hard-code the OSs to which it # applies here; at the moment, that means platforms that use the PE # object format with DLL files. See the long comment at the top of # tests/bindir.at for full details. tdlname=$dlname case $host,$output,$installed,$module,$dlname in *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) # If a -bindir argument was supplied, place the dll there. if test "x$bindir" != x ; then func_relative_path "$install_libdir" "$bindir" tdlname=$func_relative_path_result$dlname else # Otherwise fall back on heuristic. tdlname=../bin/$dlname fi ;; esac $ECHO > $output "\ # $outputname - a libtool library file # Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION # # Please DO NOT delete this file! # It is necessary for linking the library. # The name that we can dlopen(3). dlname='$tdlname' # Names of this library. library_names='$library_names' # The name of the static archive. old_library='$old_library' # Linker flags that can not go in dependency_libs. inherited_linker_flags='$new_inherited_linker_flags' # Libraries that this one depends upon. dependency_libs='$dependency_libs' # Names of additional weak libraries provided by this library weak_library_names='$weak_libs' # Version information for $libname. current=$current age=$age revision=$revision # Is this an already installed library? installed=$installed # Should we warn about portability when linking against -modules? shouldnotlink=$module # Files to dlopen/dlpreopen dlopen='$dlfiles' dlpreopen='$dlprefiles' # Directory that this library needs to be installed in: libdir='$install_libdir'" if test "$installed" = no && test "$need_relink" = yes; then $ECHO >> $output "\ relink_command=\"$relink_command\"" fi done } # Do a symbolic link so that the libtool archive can be found in # LD_LIBRARY_PATH before the program is installed. func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' ;; esac exit $EXIT_SUCCESS } { test "$opt_mode" = link || test "$opt_mode" = relink; } && func_mode_link ${1+"$@"} # func_mode_uninstall arg... func_mode_uninstall () { $opt_debug RM="$nonopt" files= rmforce= exit_status=0 # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic="$magic" for arg do case $arg in -f) func_append RM " $arg"; rmforce=yes ;; -*) func_append RM " $arg" ;; *) func_append files " $arg" ;; esac done test -z "$RM" && \ func_fatal_help "you must specify an RM program" rmdirs= for file in $files; do func_dirname "$file" "" "." dir="$func_dirname_result" if test "X$dir" = X.; then odir="$objdir" else odir="$dir/$objdir" fi func_basename "$file" name="$func_basename_result" test "$opt_mode" = uninstall && odir="$dir" # Remember odir for removal later, being careful to avoid duplicates if test "$opt_mode" = clean; then case " $rmdirs " in *" $odir "*) ;; *) func_append rmdirs " $odir" ;; esac fi # Don't error if the file doesn't exist and rm -f was used. if { test -L "$file"; } >/dev/null 2>&1 || { test -h "$file"; } >/dev/null 2>&1 || test -f "$file"; then : elif test -d "$file"; then exit_status=1 continue elif test "$rmforce" = yes; then continue fi rmfiles="$file" case $name in *.la) # Possibly a libtool archive, so verify it. if func_lalib_p "$file"; then func_source $dir/$name # Delete the libtool libraries and symlinks. for n in $library_names; do func_append rmfiles " $odir/$n" done test -n "$old_library" && func_append rmfiles " $odir/$old_library" case "$opt_mode" in clean) case " $library_names " in *" $dlname "*) ;; *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; esac test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" ;; uninstall) if test -n "$library_names"; then # Do each command in the postuninstall commands. func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' fi if test -n "$old_library"; then # Do each command in the old_postuninstall commands. func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' fi # FIXME: should reinstall the best remaining shared library. ;; esac fi ;; *.lo) # Possibly a libtool object, so verify it. if func_lalib_p "$file"; then # Read the .lo file func_source $dir/$name # Add PIC object to the list of files to remove. if test -n "$pic_object" && test "$pic_object" != none; then func_append rmfiles " $dir/$pic_object" fi # Add non-PIC object to the list of files to remove. if test -n "$non_pic_object" && test "$non_pic_object" != none; then func_append rmfiles " $dir/$non_pic_object" fi fi ;; *) if test "$opt_mode" = clean ; then noexename=$name case $file in *.exe) func_stripname '' '.exe' "$file" file=$func_stripname_result func_stripname '' '.exe' "$name" noexename=$func_stripname_result # $file with .exe has already been added to rmfiles, # add $file without .exe func_append rmfiles " $file" ;; esac # Do a test to see if this is a libtool program. if func_ltwrapper_p "$file"; then if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" relink_command= func_source $func_ltwrapper_scriptname_result func_append rmfiles " $func_ltwrapper_scriptname_result" else relink_command= func_source $dir/$noexename fi # note $name still contains .exe if it was in $file originally # as does the version of $file that was added into $rmfiles func_append rmfiles " $odir/$name $odir/${name}S.${objext}" if test "$fast_install" = yes && test -n "$relink_command"; then func_append rmfiles " $odir/lt-$name" fi if test "X$noexename" != "X$name" ; then func_append rmfiles " $odir/lt-${noexename}.c" fi fi fi ;; esac func_show_eval "$RM $rmfiles" 'exit_status=1' done # Try to remove the ${objdir}s in the directories where we deleted files for dir in $rmdirs; do if test -d "$dir"; then func_show_eval "rmdir $dir >/dev/null 2>&1" fi done exit $exit_status } { test "$opt_mode" = uninstall || test "$opt_mode" = clean; } && func_mode_uninstall ${1+"$@"} test -z "$opt_mode" && { help="$generic_help" func_fatal_help "you must specify a MODE" } test -z "$exec_cmd" && \ func_fatal_help "invalid operation mode \`$opt_mode'" if test -n "$exec_cmd"; then eval exec "$exec_cmd" exit $EXIT_FAILURE fi exit $exit_status # The TAGs below are defined such that we never get into a situation # in which we disable both kinds of libraries. Given conflicting # choices, we go for a static library, that is the most portable, # since we can't tell whether shared libraries were disabled because # the user asked for that or because the platform doesn't support # them. This is particularly important on AIX, because we don't # support having both static and shared libraries enabled at the same # time on that platform, so we default to a shared-only configuration. # If a disable-shared tag is given, we'll fallback to a static-only # configuration. But we'll never go from static-only to shared-only. # ### BEGIN LIBTOOL TAG CONFIG: disable-shared build_libtool_libs=no build_old_libs=yes # ### END LIBTOOL TAG CONFIG: disable-shared # ### BEGIN LIBTOOL TAG CONFIG: disable-static build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` # ### END LIBTOOL TAG CONFIG: disable-static # Local Variables: # mode:shell-script # sh-indentation:2 # End: # vi:sw=2 bristol-0.60.11/COPYING.GPL0000644000175000017500000010451311325625720011741 00000000000000 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . bristol-0.60.11/AUTHORS0000755000175000017500000000110311245165066011332 00000000000000 Bristol is written and maintained by Nick Copeland, nickycopeland@hotmail.com, there have been diverse contributions for compatability with different releases and compilation options. Thanks to Dave Robillard for compilation clean up and 64bit compatability. Mike Taht for GUI code clean up and more 64bit compatability. Vasiliy Basic for the MiniMoog memory contributions. Alexis Bailler for the gentoo packaging. Andrew Coughlan for banks of PolySix sounds. Colin Fletcher for numerous bug reports, fixes and filter code optimisations. The team at www.bluesynths.com bristol-0.60.11/bristol.10000644000175000017500000011054011651317767012035 00000000000000.\" Hey, EMACS: -*- nroff -*- .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) .TH BRISTOL 1 "Oct 29, 2011" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: .\" .nh disable hyphenation .\" .hy enable hyphenation .\" .ad l left justify .\" .ad b justify to both left and right margins .\" .nf disable filling .\" .fi enable filling .\" .br insert line break .\" .sp insert n+1 empty lines .\" for manpage-specific macros, see man(7) .SH NAME bristol \- a synthesiser emulation package. .SH SYNOPSIS .B startBristol .RI -mini\ -jack\ -midi\ seq\ [ options ] .SH DESCRIPTION .PP .\" TeX users may be more comfortable with the \fB\fP and .\" \fI\fP escape sequences to invode bold face and italics, .\" respectively. \fBbristol\fP is a vintage synthesiser software emulator suite. The application consists of an engine itself called bristol and a graphical user interface called \fBbrighton\fP. The graphical interface is a bitmap manipulation library to present the diverse synth devices such as potentiometers, buttons, sliders, patch cables and which generates the messages to configure the synth emulator. The engine is an infrastructure that hosts the emulator code that couples together the different audio operators required to generate the audio. The engine and GUI are started together with the \fBstartBristol\fP script which sets up the required environment for the two to connect together. It is not generally envisaged that bristol and brighton be started outside of the script however there are options to the script to only start one or the other. Bristol also has a command line interface that can be used rather than the GUI. .PP Currently following synthesizers are emulated: .TP Emulations .br moog mini .br moog explorer (voyager) .br moog voyager electric blue .br moog memory .br moog sonic 6 .br moog/realistic mg\-1 concertmate .br hammond module (deprecated, use \-b3) .br hammond B3 (default)$ .br sequential circuits prophet\-5 .br sequential circuits prophet\-5/fx .br sequential circuits prophet\-10 .br sequential circuits pro\-one .br fender rhodes mark\-I stage 73 .br fender rhodes bass piano .br crumar roadrunner electric piano .br crumar bit 01 .br crumar bit 99 .br crumar bit + mods .br crumar stratus synth/organ combo .br crumar trilogy synth/organ/string combo .br oberheim OB\-X .br oberheim OB\-Xa .br arp axxe .br arp odyssey .br arp 2600 .br arp/solina string ensemble .br korg polysix .br korg poly\-800 .br korg mono/poly .br korg ms20 (unfinished: \-libtest only) .br vox continental .br vox continental super/300/II .br roland juno\-60 .br roland jupiter\-8 .br baumann bme\-700 .br bristol bassmaker sequencer .br yamaha dx\-7 .br yamaha cs\-80 (unfinished) .br commodore\-64 SID chip synth .br commodore\-64 SID polyphonic synth (unfinished) .br granular synthesiser (unfinished) .br ems synthi\-a (unfinished) .br 16 track mixer (unfinished: \-libtest only) .PP The default connection between the engine and GUI is a TCP socket using a SYSEX format message taken from MIDI. Optionally the code will use a unix domain socket for improved security. The GUI and engine do not need to be resident on the same system if suitable parameters are given, this feature requires the TCP domain sockets be used. The engine can also accept requests from multiple brighton interfaces and run all the emulators at the same time, multitimbraly, sharing voices between them and pre-empting where necessary. If an emulator is started in monophonic mode then it is preallocated a voice that will never be pre-empted and which runs continuously, ie, by default it will continue to run even when no piano keys are pressed. The polyphonic code will only run the voice algorithms whilst the key gate is open, the gate being derived from the voice envelope state. The engine supports minimally 32 voices per default, if an emulator requests less then its emulation is configured with a soft limit. If more are requested then more voices are created however the upper limit is imposed at 128 voices. A voice is an engine structure that allows for allocation and executing, the actual code run by a voice can be any of the emulator algorithms which is how multitimbral operation is supported. The voice allocation process is 'last note precedence' and whilst others are available for the monophonic instruments, this is the only polyphonic assignment algorithm. .PP This package should be started with the startBristol script. The script will start up the bristol synthesiser binaries, evaluating the correct library paths and executable paths. There are emulation, synthesiser and operational parameters: .SH OPTIONS .TP .B Emulation: \-mini \- moog mini .br \-explorer \- moog voyager .br \-voyager \- moog voyager electric blue .br \-memory \- moog memory .br \-sonic6 \- moog sonic 6 .br \-mg1 \- moog/realistic mg\-1 concertmate .br \-hammond \- hammond module (deprecated, use \-b3) .br \-b3 \- hammond B3 (default) .br \-prophet \- sequential circuits prophet\-5 .br \-pro52 \- sequential circuits prophet\-5/fx .br \-pro10 \- sequential circuits prophet\-10 .br \-pro1 \- sequential circuits pro\-one .br \-rhodes \- fender rhodes mark\-I stage 73 .br \-rhodesbass \- fender rhodes bass piano .br \-roadrunner \- crumar roadrunner electric piano .br \-bitone \- crumar bit 01 .br \-bit99 \- crumar bit 99 .br \-bit100 \- crumar bit + mods .br \-stratus \- crumar stratus synth/organ combo .br \-trilogy \- crumar trilogy synth/organ/string combo .br \-obx \- oberheim OB\-X .br \-obxa \- oberheim OB\-Xa .br \-axxe \- arp axxe .br \-odyssey \- arp odyssey .br \-arp2600 \- arp 2600 .br \-solina \- arp/solina string ensemble .br \-polysix \- korg polysix .br \-poly800 \- korg poly\-800 .br \-monopoly \- korg mono/poly .br \-ms20 \- korg ms20 (unfinished: \-libtest only) .br \-vox \- vox continental .br \-voxM2 \- vox continental super/300/II .br \-juno \- roland juno\-60 .br \-jupiter \- roland jupiter\-8 .br \-bme700 \- baumann bme\-700 .br \-bm \- bristol bassmaker sequencer .br \-dx \- yamaha dx\-7 .br \-cs80 \- yamaha cs\-80 (unfinished) .br \-sidney \- commodore\-64 SID chip synth .br \-melbourne \- commodore\-64 SID polysynth (unfinished) .br \-granular \- granular synthesiser (unfinished) .br \-aks \- ems synthi\-a (unfinished) .br \-mixer \- 16 track mixer (unfinished: \-libtest only) .br .PP .B Synthesiser: .TP \-voices The selected emulator will start with this number of voices. The engine will always create 32 voices but only allocate this subset to the emulator. If the selected value is greater than 32 then the greater number of voices is allocated. .TP \-mono Run the emulator in monophonic mode. This is not really an alias for '-voices 1' as it additionally configures parameters such as '-retrig -lvel -wwf -hnp'. These additional options can be overridden if desired. .TP \-lnp Select low note precedence logic. This only applies to monophonic synthesisers and all of the note precedence affect the legato playing style. .TP \-hnp Select high note precedence logic. This only applies to monophonic synthesisers. .TP \-nnp Select no note precedence, this is the default and operates as a last note precedence selection. .TP \-retrig Request a trigger event for each note that is played AND notes that are released. The trigger will cause the envelopes to cycle. They will not return to zero by default however some of the emulations have that as a GUI control. Without this flag triggers are only sent for the first pressed note of a sequence. .TP \-lvel Configure velocity inheritance for all legato notes - the first note of a sequence will have a velocity value that is applied to all subsequent notes. This option is a toggle: applying twice will disable the feature. This is important with regards to the emulators as many of the mono synths with set lvel per default. The following options may not work as expected: startBristol -mini -lvel The issue is that -mini enables legato velocity so the -lvel switch will toggle it off again. The same applies to -retrig. .TP \-channel Start the emulator to respond on this MIDI channel, default 1. .TP \-lowkey Configure the lowest note for which the emulator should respond. This defaults to '0' but can be used to define key splits and ranges for different synths. .TP \-highkey Configure the highest note for which the emulator should respond. This defaults to '127' but can be used to define key splits and ranges for different synths. .TP \-detune <%> Request the emulator run with a level of temperature sensitivity. The default value is defined by the emulator, typically 100 or 200. The detune is applied to a voice at note on only and is a random value within the range defined here. .TP \-gain Output signal gain level for the emulator. These can be used to normalise the signal levels from different synths when played together. The default value is defined by the synth itself, this is an override. .TP \-pwd Pitch wheel depth in semitones, default 2. .TP \-velocity Velocity curve for the emulator. Default is 520, an exponential curve for a hard playing style. Value '0' is flat (no touch sensitivity). Values up to 100 are linear scaled maps. The velocity map is table of points that is interpolated linearly: you may only have to define the inflexion points, however if you want smooth curves you will have to define each of the 128 velocity values that are used in noteon/noteoff events. The emulation only has a single table of gain levels for each key.velocity index, the engine by contrast has two tables, one for each on/off event however that is an integer map, not a gain map. There are several default tables if you do not want to specify your own interpolated curve. Each table is the gain for the Midi velocity value given in the note event, it has 128 entries. The following are implmented: 100-199 Convex curves for a soft touch keyboard player 200-499 Concave curves for a hard touch, linear up to quadratic function. The next set up to 525 are repeats of the above but with less granularity. In the above range the value of 200 is linear, as is 510 below: 500-509 Convex curves for a soft touch keyboard player 510 linear 511-25 Concave curves for a hard touched player. Then there are a couple of specific curves 550 logarithmic 560 parabolic The values up to 100 consists of two digit numbers. The first digit defines how late the line starts (it is linear) to ramp up, and the second digit is how late it reaches 1.0. The value of 09 is almost the linear mapping above as it starts from 0 and ends almost at the end. A value of 49 would be for a heavy player, it is zero for a large part of the velocity table, and then ramps up to max gain (1.0) close the end of the table. Note that these table could also have been defined with velocityMap definitions as they are linear interpolations. A present release will include curves to smooth things out a little. Option 520 is a squared powercurve and feels quite natural although that is very subjective. Perhaps its natural for a hard player and it could be a better default than the linear curve. The value 1000 will invert the mapping, so: 1510 - linear from 1.0 down to 0.0 as velocity increases 1520 - exponential, from 1.0 down to 0.0 as velocity increases The engine mapping is applied before the emulation mapping given here. There are reasonable arguments to make this table logarithmic - you are welcome to do so. There are no limits to the values here other than negative values are not mapped, so this table can also be used to compensate for volume levels. .TP \-glide Duration of nogte glide in seconds, default 5. .TP \-emulate Search for the named emulator and invoke it, otherwise exit. Invoking an emulation this was is currently the default, it implies extra parameters for voicecount, gain, glide, pitchwheel depth, detune, etc. The default is hammondB3. The -emulate option also implies -register to the emulator name. .TP \-register Use a specific name when registering with Jack and ALSA. By default the engine will use the name 'bristol' however this can be confusing if multiple engines are being used and this can be used to override the default. .TP \-lwf Select lightweight filters for the emulator. .TP \-nwf Select normalweight filters, the default. These are about twice as expensive as lightweight filters. .TP \-wwf Select welterweight filters, this are again about double the CPU load as the normal filters. .TP \-hwf Select heavyweight filters. These are roughly twice the welterweight filter. Whilst their is a noticable audible difference between -lwf and -nwf, it is debatable whether the difference between -nwf, -wwf and -hwf is other than visible in the CPU load. The default filter for any -mono synth is -wwf which can be overridden with something line '-mini -mono -nwf'. .TP \-blo Number of bandwidth limited harmonics to map. The value of zero will select infintite bandwidth, default is 31. .TP \-blofraction The engine uses precomputed tables for all frequencies where the maximum harmonic does not exceed this fraction of the samplerate. The default, 0.8, is already above nyquist as a tradeoff betweeen content and distortion. Values tending towards 1.0 are heavily aliased at the higher frequencies naturally. .TP \-scala The engine will read the given scala file and map it into its frequency tables. .PP .TP .B User Interface: .TP \-quality The color cache depth will affect the rendering speed. The lower values start showing loss of clarity, the higher values start using thousands of colors which is where the performance is affected, value is bpp, default is 6. .TP \-scale Each of the emulators has a default window sisze, this size can be scaled up or downwards if desired. .TP \-width The pixel width defines the smaller of two sizees that can be configured. It works with the -scale and -autozoom options for flipping between different sizes on mouse Enter/Leave of the window. .TP \-autozoom Minimise window on exit, maximise on enter. .TP \-raise Automatically raise the window on Enter. .TP \-lower Automatically lower the window on Leave. It is noted here that the use of autozoom, raise and lower may have undesirable effects with some window managers. .TP \-rud Constrain the rotary controller tracking to mouse up/down motion, not to actually track the mouse position. The value will be a fraction of the current window size. .TP \-antialias <%> For some window sizes there will be pixelation of the rendered imagas unless some antialias is applied. With large zoom values this is automatically set up. Value is a percentage, default is 30. .TP \-aliastype

There are three antialiasing options, \'pre\' will apply it to the text silkscreens,
\'texture\' will apply it to the surface bitmaps and \'all\' will apply it everywhere
including devices rendered. The default is pre however this parameter is only 
applied if -antialias has a value other than zero.
.TP
\-opacity <%>
Brighton uses a transparency layer for some features such as the ARP 2600 patch
cables. This is the default transparency. It can be adjusted later with the
^o/^O/^t control codes in the GUI. Default is 50 percent.
.TP
\-pixmap
Use the X11 pixmap interface rather than the default XImage interface to the
server.
.TP
\-dct 
Double click timeout for button events, etc, 250 ms.
.TP
\-tracking
Prevent the GUI piano keyboard image from tracking MIDI events, small reduction
in CPU overhead.
.TP
\-keytoggle
The default GUI behaviour for tuning keys on with the mouse is to latch them,
this allows for playing chords on the polyphonics. This option will disable the
latch to that keys are played only whilst held with the mousebutton.
.TP
\-neutral
Initial the emulator with a null patch, all parameters will have the value of
zero to allow for a patch to be built from the bottom up, completely from
scratch. This is equivalent to '-load -1', negative memory locations will not
be saved, ie, you cannot save to the null patch.
.TP
\-load 
Initial memory number to load at startup. Default is 0 for most emulators.
.TP
\-import 
Import a memory from a disk file to the active patch at start time. This patch
can then be saved to another location and allows for interexchange of memories.
.TP
\-mbi 
The master bank index allows for access to extra memory ID. This value times
1000 is added to the memory ID saved/loaded by the GUI so the GUI can access for
example 8 banks of 8 memories but using -mbi you can actually save multiple
sets of 64 memories.
.TP
\-activesense 
The rate at which hello messages are sent from GUI to engine to ensure it is
still active. If the transmission fails then the GUI will exit, if the engine
does not receive updates it will also exit. Zero will disable active sense.
.TP
\-ast 
The engine timeout period on active sense messages.
.TP
\-mct 
The MIDI cycle timeout is a busy waiting GUI timer for MIDI events, used when  
the GUI takes a MIDI interface for direct event tracking.
.TP
\-ar|\-aspect
All of the emulators will attempt to maintain an aspect ratio for their windows
so that they look 'normal'. This conflicts with some tiling window managers so
can be disabled. It may also cause some excessive remapping of windows when they
are resized.
.TP
\-iconify
Open the window in the iconified state.
.TP
\-window
Do not map any window.
.TP
\-cli
Enable the text based command line interface to the engine. This can be used in
connjuction with -window however if compiled without support for any windowing
system the -window option is implied.
.TP
\-libtest
Do not start the engine, nor attempt to connect to it, just post the GUI for
testing.

.PP
.TP
.B GUI Shortcuts:

 's'     \- save settings to current memory
.br
 'l'     \- (re)load current memory
.br
 'x'     \- exchange current with previous memory
.br
 '+'     \- load next memory
.br
 '\-'     \- load previous memory
.br
 '?'     \- show emulator help information
.br
 'h'     \- show emulator help information
.br
 'r'     \- show application readme information
.br
 'k'     \- show keyboard shortcuts
.br
 'p'     \- screendump to /tmp/.xpm
.br
 't'     \- toggle opacity
.br
 'o'     \- decrease opacity of patch layer
.br
 'O'     \- increase opacity of patch layer
.br
 'w'     \- display warranty
.br
 'g'     \- display GPL (copying conditions)
.br
 '+'    \- increase window size
.br
 '\-'    \- decrease window size
.br
 'Enter'\- toggle window between full screen size
.br
UpArrow        \- controller motion up (shift key accelerator)
.br
DownArrow      \- controller motion down (shift key accelerator)
.br
RightArrow     \- more control motion up (shift accelerator)
.br
LeftArrow      \- more control motion down (shift accelerator)

.TP
.B Operational options:
.TP
General:

.TP
\-engine
Do not start a new engine. The GUI will attempt to connect to an existing 
engine on the host and port configuration (cq). If the connection is built 
then the engine will operate both emulators and voice allocations will be
shared amongst them. All of the emulator outputs are folded back onto the 
same stereo output, excepting where extra Jack control inputs are used.
.TP
\-gui
Do not start the GUI, only the engine. The GUI will attempt to connect to the
engine on the configured host and port values. If it does not respond then the
GUI will exit with some rather terse messaging.
.TP
\-server
Start the engine as a permanant server that does not exit with the last 
emulator.
.TP
\-daemon
Run the engine as a daemon with disconnected controlling terminal. This does
not imply the -server option, nor does it imply the -log option for logging to
the file system, nor -syslog which might also be applicable to a daemon.
.TP
\-watchdog 
Timeout for the audio thread initialisation. If the thread does not activate
within this period then the engine will gracefully exit rather than wait around
for connections indefinitely. Default period is 30 seconds. This is not active
in -server or -daemon mode. In normal operation the audio thread will be 
launched within a couple of seconds but if the engine and GUI are started
separately then this timeout demands that a GUI be started before the timer
expires.
.TP
\-log
Redirect logging output to a file. The default file is /var/log/bristol.log and
/var/log/brighton.log and if they are not available then $HOME/.bristol/log 
directory is used. The selection of /var/log is to prevent logging to root in
the event that the engine is invoked by this user.
.TP
\-syslog
Redirect logging output to syslog.
.TP
\-console
Maintain the controlling terminal as output for logging messages, remove the
timestampes for readability purposes. This can also be configured with the
environment variable BRISTOL_LOG_CONSOLE=true.
.TP
\-rc
Do not load any bristolrc parameter file.
.TP
\-exec
The final process to be requested by the startBristol script will be called as
an exec such that it maintains amongst other things the PID of the parent. This
option will override the exec and leave the script waiting for the processes to
exit. There implications of not using this parameter, some of the cleanup code
is part of the wrapping shellscript, per default this is not called due to the
exec request. This flag is default but should only really be required for 
LADI compatibility.
.TP
\-stop
Stop all the running bristol engines. This will indirectly result in termination
of any GUI due to active sensing although that can be disabled. The use case is
to stop any -server -daemon engines running in the background. The back end to
the option is pkill.
.TP
\-exit
Stop all the running bristol engines and GUI.
.TP
\-kill <-emulator>
Stop all the running bristol engines and GUI that have been associated with the
given emulator. If bristol was started with '-mini' it can now be killed with
-mini so that other emulators are not terminated. If there are multiple mini
running they will naturally die also. If the engine is running multitimbral GUI
then the other associated GUI will also exit in addition to the mini.
.TP
\-cache 
The default location for new memories and emulator profiles, the default is
~/.bristol and it will be searched before the system/factory default directory
/usr/local/share/bristol when emulators are started and memories are loaded. If
the pathname does not exist then it is created if possible.
.TP
\-memdump  [-emulate ]
Create the target directory /memory/ and copy first the 
factory default memories for the synth, then the user private memories. This 
can be used with session management to make a copy of all synth memories in a
session. If the target directory already exists then no copy operation takes
place but the directory does replace the -cache default to make this the new
location for saved memories for that session. The -emulate option is required,
if it is not provided then the default hammondB3 is taken.
.TP
\-debug <1\-16>
Debug level, values above 12 can be very verbose and only the value 0 is 
arguably realtime safe as it avoids printf() in the engine compute thread.
.TP
\-readme [\-]
Display the program readme information. Show the readme for just a single
emulator if desired.
.TP
\-glwf
Only allow the use of '-lwf' for all emulators, no overrides.
.TP
\-host 
Connect to the engine on the hostname, default is localhost. This is used in
conjuction with -engine to distribute the GUI. The hostname accepts syntax such
as hostname:port to fix both the host and port for a remote connection to the
engine. If the host portion is the token 'unix' then a local named socket is
created rather than a TCP connection. In this instance a specific port number
can be given to create the named socket /tmp/br. and if the port is not
specified then a random numeric index is chosen.
.TP
\-port 

Connect to the given TCP port for GUI/engine messaging, default 5028. If the port is alreeady in use then the startup with fail. For starting multiple bristols with GUI then this option should be discarded and the script will look for a free port number for each invocation. It is incorrect to mix this option with -host parameters that take a value host:port or unix:port as the results will be indeterminate depending on the order the parameters are submitted. .TP \-quiet Redirect debug and diagnostic output to /dev/null. .TP \-gmc Open a MIDI interface in the GUI. Per default the engine will own the only MIDI interface for bristol and will redistribute events to the GUI. It is possible to disable the forwarding and attach both GUI and engine to midi devices if necessary. .TP \-forward Disable MIDI event forwarding globally. Per default the engine opens a MIDI interface and is connected to the physical keyboards, control surfaces and/or sequencers. It will forward MIDI events to the GUI for tracking. This option disables the feature. When disabled the GUI will not reflect the piano keybaord state, nor will it track CC motion unless the options '-gmc' is given to open a MIDI connection in the GUI and that the user connects the same control surfaces to the GUI via this alternative channel. This option is logically identical to \'-localforward -remoteforward\'. .TP \-localforward This will prevent the GUI from forwarding MIDI messages to the engine. This is not to prevent MIDI message loops as the forwarding only ever occurs from MIDI interfaces to TCP connections between GUI and engine. This option will prevent messages from any surfaces that are connected to the GUI from forwarding to the engine. .TP \-remoteforward This will prevent the engine from forwarding to the GUI but still allow the GUI to forward to the engine. If the GUI is given a MIDI connection with the -gmc option, and control surfaces are applied to both processes then the -forward option should be used to globally prevent event redistribution. Failure to do so will not result in loops, just one-for-one duplication of events. It is possible to connect the control surfaces just to the GUI when the -gmc option is used, this gives the possibility to have a local keyboard and GUI but drive an engine on a remote systems. Their is admittedly additional latency involved with handling the MIDI messages from the GUI to the remote engine over TCP. .TP \-oss Configure OSS defaults for audio and MIDI interfaces .TP \-alsa Configure ALSA defaults for audio and MIDI interfaces. The MIDI interface is an ALSA SEQ port. .TP \-jack Configure Jack defaults for audio and MIDI interfaces. At the time of writing this option causes some issues as it selects Jack MIDI which currently requires a bridging daemon to operate. The options '-jack -midi seq' would be a more typical configuration. .TP \-jackstats Do not request audio parameters from the jack server, take the bristol system defaults or the configured parameters. The bristol defaults will invariably fail however the call to bristoljackstats is sometimes superfluous and this can speed up the initial startup times. Using this parameter will typically require that the options -rate and -count are also provided. TP \-jsmuuid This is for sole use of the Jack Session Manager .TP \-jsmfile This is for sole use of the Jack Session Manager .TP \-jsmd Jack session manager delay before session events are distributed internally. Event execution is delayed in the GUI by a default of 5000ms. .TP \-session Disable all session management including JSM and LADI. .TP \-sleep Stall the initialisation process for 'n' seconds. This is to work around what appears to be race a condition when using a session manager to initialise multiple bristol clients as they all vie for the same TCP port identifier. .TP \-jdo Jack Dual Open: let the audio and midi threads register as independent clients with Jack. Per default the audio thread will open as a jack client and the MIDI connection is piggypbacked as another port rather than as another client. .TP \-o Generate a raw audio output of the final stage samples to a file. The format will be 16bit stereo interleaved. .TP \-nrp Enable support for NRP events in both GUI and engine. This is to be used with care as NRP in the engine can have unexpected results. .TP \-enrp Enable NRP support in the engine only. .TP \-gnrp Enable NRP events in the GUI. This is required to allow the GUI (and hence the engine) to be driven from some MIDI control surfaces. .TP \-nrpcc Maximum number of NRP to map. The default is 128, seen as sufficient for any of the current emulators but the mixer will require more if it is every released. .TP .B Audio driver: .TP \-audio [oss|alsa|jack] Audio driver overrides. Depending on the order of the switches it is possible to set a group of global defaults (-jack/oss/alsa) then have specific re-selection of components. .TP \-audiodev Audio device name. For Jack, this will be the name registered with the Jack daemon. .TP \-count Number of samples/frames in processing period. .TP \-outgain Output signal normalisation level, per emulator default 4. .TP \-ingain Input signal normalisation level, per emulator default 4. .TP \-preload Number of audio buffers to prewrite to the audio output on start. This is not active with the Jack drivers. .TP \-rate Sampling rate, defaults to 44100. .TP \-priority

Realtime priority requested by the engine audio thread, default 75. Zero will disable RT processing. .TP \-autoconn Automatically connect the engine input and output to the first Jack IO ports found. This can also be achieved with the environment variable BRISTOL_AUTOCONN=true .TP \-multi Multiple IO port requests, only works with Jack and currently only the ARP 2600 gives access to these ports. .TP \-migc Input signal normalisation level for the multi IO ports. .TP \-mogc Output signal normalisation level for the multi IO ports. .TP .B Midi driver: .TP \-midi [oss|[raw]alsa|jack] Audio driver overrides. Depending on the order of the switches it is possible to set a group of global defaults (-jack/oss/alsa) then have specific re-selection of components such as in \'-jack -midi seq\'. The default MIDI driver is '-midi seq' but that can be overriden with compile time options such as --enable-jack-default-midi to ./configure. .TP \-mididev MIDI device namee to be opened (OSS/ALSA). .TP \-mididbg Request MIDI level 1 debuging. .TP \-mididbg2 Request MIDI level 2 debuging. Both can be selected for level 3. .TP \-sysid <0xXXXXXXXX> Configure an alternative SYSEX identifier for the engine. The default is the value 0x534C6162 for historical reasons, this is not a free development ID but it is not assigned so should not cause conflict. .TP .br .B LADI driver (level 1 compliant): .TP \-ladi brighton Execute LADI messages in the GUI only .TP \-ladi bristol Execute LADI messages in the engine only .TP \-ladi The LADI state memory for save operations. This should be unique for each LADI session. .PP .SH EXAMPLES .TP startBristol -mini Run a minimoog using ALSA interface for audio and midi (seq). The emulator will default to monophonic, high note precedence with retrigger and legato velocity. .TP startBristol \-alsa Run a hammondB3 using ALSA interface for audio and midi. This is equivalent to all the following options: \-b3 \-audio alsa \-audiodev plughw:0,0 \-midi seq \-mididev plughw:0 \-count 256 \-preload 4 \-port 5028 \-voices 32 \-channel 1 \-rate 44100 .TP startBristol \-explorer \-voices 1 Run a moog explorer as a monophonic instrument, using ALSA interface for audio and midi. .TP startBristol \-prophet \-alsa \-channel 3 Run a prophet\-5 using ALSA for audio and midi (on channel 3). .TP startBristol \-b3 \-count 512 \-preload 2 Run a hammond b3 with a 512 samples in a period, and preload two such buffers before going active. Some Live! cards need this larger buffer size with ALSA drivers. .TP startBristol \-oss \-audiodev /dev/dsp1 \-vox \-voices 8 Run a vox continental using OSS device 1, and default midi device /dev/midi0. Operate with just 8 voices out of the 32 available. .TP startBristol \-b3 \-audio alsa \-audiodev plughw:0,0 \-seq \-mididev 128.0 Run a B3 emulation over the ALSA PCM plug interface, using the ALSA sequencer over client 128, port 0. .TP startBristol \-juno & .TP startBristol \-prophet \-channel 2 \-engine Start two synthesisers, a juno and a prophet. Both synthesisers will will be executed on one engine (multitimbral) with 32 voices between them. The juno will be on default midi channel (1), and the prophet on channel 2. Output over the same default ALSA audio device. The 32 voices will never all get used as these emulators will run per default with a lower soft limit. They can be run with more voices however that would require suitable values to the -voices option. .TP startBristol \-juno -jack -register juno -voices 32 & .TP startBristol \-prophet -jack -register prophet -channel 2 -voices 32 Start two synthesisers, a juno and a prophet5. Each synth is totally independent with its own GUI and own engine. Each engine will register separately with the jack daemon. They will respectively register the names 'juno' and 'prophet' with Jack and ALSA so that they can be differentiated in the respective control programmes such as aconnect and qjackctl. The outputs will be visible separately in these control programs and can thus be routed independently. Each synth can use up to 32 voices and there will only be CPU contention - these are separate engine process with 32 voices each. .SH FILES The \fBbristolrc\fP file can be created in the BRISTOL_CACHE directory (default value ${HOME}/.bristol/bristolrc) and the users prefered options placed as the content. The file will be read as a single line and incorporated onto the command lines for both bristol and brighton. There is an additional variable BRISTOL_RC which can point to another location if necessary. This can be used to simply the command line for all parameters that a user provides with each invocation. The parameters can be all on a single line of the file or one per line. The parameters from this file will preceed the user specified ones such that the RC defaults may be overridden on the comand line. .SH ENVIRONMENT VARIABLES .TP BRISTOL This indicates the location of the bristol installation for the binaries, bitmaps and related data reside. The default depends on the prefix used for the system build, /usr/local/share/bristol and /usr/share/bristol are typical. .TP BRISTOL_CACHE The cache is where memories and emulator profiles (keyboard maps and MIDI Continuous Controller maps) are saved. The default is ${HOME}/.bristol .TP BRISTOL_RC Location of the bristol runcom file. .TP BRISTOL_LOG_CONSOLE Force debuging output to be sent to console without timestamping, log file or syslog. .TP BRISTOL_AUTOCONN Attempt to automatically connect the bristol audio inputs and outputs when using Jack. .TP BRISTOL_AUTO_LEFT If BRISTOL_AUTOCON is set to anything other than '0' this will be the default Jack port for the bristol left channel output. There is no default, if AUTOCONN has been requested this will be the first jack playback channel. .TP BRISTOL_AUTO_RIGHT If BRISTOL_AUTOCON is set to anything other than '0' this will be the default Jack port for the bristol right channel output. There is no default, if AUTOCONN has been requested this will be the second jack playback channel. .TP BRISTOL_AUTO_IN If BRISTOL_AUTOCON is set to anything other than '0' this will be the default Jack port for the bristol (mono) input channel. There is no default, if AUTOCONN is set this will be the first jack capture channel. .SH AUTHOR Written by Nicholas Copeland .SH REPORTING BUGS Bugs and enhancement requests can be submitted to the bristol project page on SourceForge: .PP .SH COPYRIGHT Copyright © 1996,2011 Nick Copeland. License GPLv3+: GNU GPL version 3 or later . This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. bristol-0.60.11/configure.ac0000755000175000017500000003343512073601211012550 00000000000000# -*- Autoconf -*- # Process this file with autoconf to produce a configure script. #AC_PREREQ(2.60) AC_INIT(brighton/brightonhelp.h) BRISTOL_MAJOR_VERSION=0 BRISTOL_MINOR_VERSION=60 BRISTOL_MICRO_VERSION=11 BRISTOL_API_CURRENT=0 BRISTOL_API_REVISION=611 BRISTOL_API_AGE=0 AC_SUBST(BRISTOL_MAJOR_VERSION) AC_SUBST(BRISTOL_MINOR_VERSION) AC_SUBST(BRISTOL_MICRO_VERSION) BRISTOL_VERSION=${BRISTOL_MAJOR_VERSION}.${BRISTOL_MINOR_VERSION}.${BRISTOL_MICRO_VERSION} AC_SUBST(BRISTOL_VERSION) BRISTOL_SO_VERSION=${BRISTOL_API_CURRENT}:${BRISTOL_API_REVISION}:${BRISTOL_API_AGE} AC_SUBST(BRISTOL_SO_VERSION) #AM_INIT_AUTOMAKE([-Wall -Werror foreign]) AM_INIT_AUTOMAKE(bristol,${BRISTOL_VERSION}) AM_CONFIG_HEADER([config.h]) AC_CONFIG_MACRO_DIR([m4]) # Checks for libraries. AC_PROG_LIBTOOL # Checks for programs. AC_PROG_CC AC_PROG_INSTALL AC_PROG_MAKE_SET # if we have a previous version pan the build showErrMsg1() { echo echo "*************************************************************" echo "* *" echo "* A previous bristol installation exists on this system. *" echo "* *" echo "* If you have bristol installed from your package manager *" echo "* you really need to remove it first. If you have it from *" echo "* a previous bristol build then you can remove it with a *" echo "* 'make uninstall' from the previous build directory. *" echo "* *" echo "* If you understand the risks or just want to be lazy then *" echo "* you can override this test with --disable-version-check *" echo "* however the author advises against such a workaround. *" echo "* *" echo "*************************************************************" echo exit 1 } TRY_VC=yes AC_ARG_ENABLE(version_check, [ --disable-version-check ignore preinstalled versions], TRY_VC=no , TRY_VC=yes ) if test "x$TRY_VC" = 'xyes' then which startBristol > /dev/null 2>&1 if test $? == 0; then showErrMsg1; fi which bristol > /dev/null 2>&1 if test $? == 0; then showErrMsg1; fi if test -f ${prefix}/bin/bristol; then showErrMsg1; fi fi # Checks for header files. AC_ARG_ENABLE(oss, [ --disable-oss ignore OSS driver ], TRY_OSS=$enableval , TRY_OSS=yes ) if test "x$TRY_OSS" = "xyes" then HAVE_OSS=true BRISTOL_HAS_OSS=1 AC_CHECK_HEADER(sys/soundcard.h, [], [HAVE_OSS=false]) if test $HAVE_OSS = "false"; then BRISTOL_HAS_OSS=0 fi else HAVE_OSS=false BRISTOL_HAS_OSS=0 fi AC_SUBST(BRISTOL_HAS_OSS) # The brighton library requires 4 X11 header files and cannot proceed without # them. We should check here for their availability. CFLAGS="$CFLAGS -I/usr/X11R6/include" CPPFLAGS="$CPPFLAGS -I/usr/X11R6/include" HAVE_XHEADERS=true AC_CHECK_HEADER(X11/X.h, [], [HAVE_XHEADERS=false]) AC_CHECK_HEADER(X11/Xlib.h, [], [HAVE_XHEADERS=false]) AC_CHECK_HEADER(X11/Xutil.h, [], [HAVE_XHEADERS=false]) AC_CHECK_HEADER(X11/Xos.h, [], [HAVE_XHEADERS=false]) AC_CHECK_HEADER(X11/Xatom.h, [], [HAVE_XHEADERS=false]) # Checks for typedefs, structures, and compiler characteristics. # Checks for X11 library functions. BRIGHTON_HAS_X11= BRIGHTON_X11_DIR= BRIGHTON_LIBX11= BRIGHTON_LIBB11=-lC11 BRIGHTON_LIBXLIBS=-L../libbrightonC11 AC_ARG_ENABLE(x11, [ --disable-x11 disable X11 interface ], TRY_X11=$enableval , TRY_X11=yes ) if test $HAVE_XHEADERS = "false" then TRY_X11=no fi AC_CHECK_HEADERS([X11/extensions/XShm.h], [x11_shm_found="true"], [x11_shm_found="false"], [ #include #include #include ]) # Force this for now - pure build time options, no header dependency if test "x$TRY_X11" = "xyes" then BRIGHTON_HAS_X11=-DBRIGHTON_HAS_X11 BRIGHTON_X11_DIR=libbrightonX11 BRIGHTON_LIBB11=-lB11 BRIGHTON_LIBX11=-lX11 BRIGHTON_LIBXEXT= BRIGHTON_LIBXLIBS=-L../libbrightonX11 AC_ARG_ENABLE(ximage, [ --disable-ximage ignore XImage interface ], TRY_XIMAGE=$enableval , TRY_XIMAGE=yes ) if test "x$TRY_XIMAGE" = "xyes" then BRIGHTON_HAS_XIMAGE=-DBRIGHTON_XIMAGE AC_SUBST(BRIGHTON_HAS_XIMAGE) if test "x$x11_shm_found" = "xtrue" then AC_ARG_ENABLE(shmimage, [ --disable-shmimage ignore XShmImage interface ], TRY_SHMIMAGE=$enableval , TRY_SHMIMAGE=no ) if test "x$TRY_SHMIMAGE" = "xyes" then BRIGHTON_HAS_SHMIMAGE=-DBRIGHTON_SHMIMAGE BRIGHTON_LIBXEXT=-lXext AC_SUBST(BRIGHTON_HAS_SHMIMAGE) fi fi fi fi AC_SUBST(BRIGHTON_X11_DIR) AC_SUBST(BRIGHTON_HAS_X11) AC_SUBST(BRIGHTON_LIBX11) AC_SUBST(BRIGHTON_LIBB11) AC_SUBST(BRIGHTON_LIBXEXT) AC_SUBST(BRIGHTON_LIBXLIBS) BRR=${BRISTOL_RAMP_RATE:-10} AC_SUBST(BRR) _BRISTOL_VOICES=${BRISTOL_VOICECOUNT:-32} AC_SUBST(_BRISTOL_VOICES) BRISTOL_LIN_ATTACK=-DBRISTOL_LIN_ATTACK AC_ARG_ENABLE(exp-attack, [ --enable-exp-attack enable exponential attack], USE_EXP_ATTACK=yes , USE_EXP_ATTACK=no ) if test "x$USE_EXP_ATTACK" == "xyes" then BRISTOL_LIN_ATTACK= fi AC_SUBST(BRISTOL_LIN_ATTACK) BRISTOL_SEM_OPEN= BRISTOL_SEMAPHORE= AC_ARG_ENABLE(semaphore, [ --enable-semaphore enable engine semaphores ], USE_SEMAPHORE=yes , USE_SEMAPHORE=no ) if test "x$USE_SEMAPHORE" == "xyes" then BRISTOL_SEMAPHORE=-DBRISTOL_SEMAPHORE # Checks for sem_open use. AC_ARG_ENABLE(sem-open, [ --enable-sem-open use sem_open interface ], USE_SEM_OPEN=yes , USE_SEM_OPEN=no ) if test "x$USE_SEM_OPEN" = "xyes" then BRISTOL_SEM_OPEN=-DBRISTOL_SEM_OPEN fi fi AC_SUBST(BRISTOL_SEM_OPEN) AC_SUBST(BRISTOL_SEMAPHORE) BRISTOL_BARRIER= AC_ARG_ENABLE(memory-barrier, [ --enable-memory-barrier enable ringbuffer barrier], USE_BARRIER=yes , USE_BARRIER=no ) if test "x$USE_BARRIER" == "xyes" then BRISTOL_BARRIER=-DUSE_MLOCK fi AC_SUBST(BRISTOL_BARRIER) # Checks for autozoom feature requested BRIGHTON_HAS_AUTOZOOM=-DBRIGHTON_HAS_ZOOM=1 AC_ARG_ENABLE(autozoom, [ --disable-autozoom disable window autozoom on Enter], TRY_AZ=no , TRY_AZ=yes ) if test "x$TRY_AZ" = "xno" then BRIGHTON_HAS_AUTOZOOM=-DBRIGHTON_HAS_ZOOM=0 fi AC_SUBST(BRIGHTON_HAS_AUTOZOOM) # Checks for old audio device close/open on error. AC_ARG_ENABLE(drain, [ --disable-drain no reopen of audio dev on error ], TRY_DRAIN=$enableval , TRY_DRAIN=yes ) if test "x$TRY_DRAIN" = "xyes" then BRISTOL_HAS_DRAIN=-D_BRISTOL_DRAIN AC_SUBST(BRISTOL_HAS_DRAIN) fi PKG_PROG_PKG_CONFIG # Checks for library functions. AC_ARG_ENABLE(alsa, [ --disable-alsa ignore ALSA driver ], TRY_ALSA=$enableval , TRY_ALSA=yes ) AC_CHECK_HEADER(alsa/asoundlib.h, alsa_found="true", alsa_found="false") HAVE_ALSA=false BRISTOL_HAS_ALSA=0 if test "x$TRY_ALSA" = "xyes" -a "x$alsa_found" = "xtrue"; then # check for ALSA >= 1.0.0 PKG_CHECK_MODULES(ALSA, alsa >= 1.0.0, [HAVE_ALSA=true BRISTOL_HAS_ALSA=1 ], [true] ) else ALSA_CFLAGS= ALSA_LIBS= AC_SUBST(ALSA_CFLAGS) AC_SUBST(ALSA_LIBS) fi AC_SUBST(BRISTOL_HAS_ALSA) AC_ARG_ENABLE(liblo, [ --disable-liblo ignore LIBLO driver ], TRY_LIBLO=$enableval , TRY_LIBLO=yes ) # needs liblo and liblo-dev to work - have to see the header files anyway. HAVE_LIBLO=false BRISTOL_HAS_LIBLO=0 if test "x$TRY_LIBLO" = "xyes" ; then # check for LIBLO >= 1.0.0 PKG_CHECK_MODULES(LIBLO, liblo >= 0.22.0, [HAVE_LIBLO=true BRISTOL_HAS_LIBLO=1 ], [true] ) else LIBLO_CFLAGS= LIBLO_LIBS= AC_SUBST(LIBLO_CFLAGS) AC_SUBST(LIBLO_LIBS) fi AC_SUBST(BRISTOL_HAS_LIBLO) jack_session_found="false" HAVE_JACK_MIDI="false" AC_ARG_ENABLE(jack, [ --disable-jack ignore JACK driver ], TRY_JACK=$enableval , TRY_JACK=yes ) AC_CHECK_HEADER(jack/jack.h, jack_found="true", jack_found="false") DEFAULT_AUDIO_FLAG=-alsa DEFAULT_JACK=no DEFAULT_JACK_MIDI=no BRISTOL_JACK_DEFAULT= BRISTOL_JACK_DEFAULT_MIDI= BRISTOL_JACK_MULTI_CLOSE=-DBRISTOL_JACK_MULTI_CLOSE HAVE_JACK="false" JACK_SC=yes if test "x$TRY_JACK" = "xyes" -a "x$jack_found" = "xtrue"; then # check for JACK >= 0.99.0 PKG_CHECK_MODULES(JACK, jack >= 0.99.0, [HAVE_JACK="true" JACK_DEFAULT_DRIVER="jack" BRISTOL_HAS_JACK=-D_BRISTOL_JACK ], [true] ) AC_SUBST(JACK_LIBS) AC_SUBST(BRISTOL_HAS_JACK) AC_CHECK_HEADER(jack/session.h, jack_session_found="true", jack_session_found="false") if test "$jack_session_found" = "true"; then AC_DEFINE(JACK_SESSION, 1, [Define to enable jack session support]) BRISTOL_HAS_JACK_SESSION=-D_BRISTOL_JACK_SESSION AC_SUBST(BRISTOL_HAS_JACK_SESSION) fi AC_ARG_ENABLE(jack-midi, [ --disable-jack-midi ignore JACK MIDI driver ], TRY_JACK_MIDI=$enableval , TRY_JACK_MIDI=yes ) if test "x$TRY_JACK_MIDI" = "xyes" ; then # check for JACK >= 0.99.0 PKG_CHECK_MODULES(JACK, jack >= 0.109.0, [HAVE_JACK_MIDI="true" BRISTOL_HAS_JACK_MIDI=-D_BRISTOL_JACK_MIDI ], [true] ) AC_SUBST(BRISTOL_HAS_JACK_MIDI) else HAVE_JACK_MIDI="false" fi AM_CONDITIONAL(HAVE_JACK_MIDI, $HAVE_JACK_MIDI) AC_ARG_ENABLE(jack-single-close, [ --disable-jack-single-close disable Jack selective closedown], JACK_SC=$enableval , JACK_SC=yes ) if test "x$JACK_SC" = "xyes" then BRISTOL_JACK_MULTI_CLOSE= fi AC_ARG_ENABLE(jack-default-audio, [ --enable-jack-default-audio enable Jack as default Audio driver], DEFAULT_JACK=$enableval , DEFAULT_JACK=no ) if test "x$DEFAULT_JACK" = "xyes" then DEFAULT_AUDIO_FLAG=-jack BRISTOL_JACK_DEFAULT=-DBRISTOL_JACK_DEFAULT AC_SUBST(BRISTOL_JACK_DEFAULT) fi AC_ARG_ENABLE(jack-default-midi, [ --enable-jack-default-midi enable Jack as default Midi driver], DEFAULT_JACK_MIDI=$enableval , DEFAULT_JACK_MIDI=no ) if test "x$DEFAULT_JACK_MIDI" = "xyes" then BRISTOL_JACK_DEFAULT_MIDI=-DBRISTOL_JACK_DEFAULT_MIDI AC_SUBST(BRISTOL_JACK_DEFAULT_MIDI) fi else JACK_CFLAGS= JACK_LIBS= AC_SUBST(JACK_CFLAGS) AC_SUBST(JACK_LIBS) fi AM_CONDITIONAL(HAVE_JACK, $HAVE_JACK) AM_CONDITIONAL(HAVE_JACK_MIDI, $HAVE_JACK_MIDI) AC_SUBST(DEFAULT_AUDIO_FLAG) AC_SUBST(BRISTOL_JACK_MULTI_CLOSE) ## See about pulse audio TRY_PA=no BRISTOL_HAS_PA= BRISTOL_PA_DIR= BRISTOL_LIB_PA= BRISTOL_LIBPALIBS= AC_ARG_ENABLE(pulseaudio, [ --enable-pulseaudio enable pulse audio drivers], TRY_PA=yes , TRY_PA=no ) AC_CHECK_HEADER(pulse/pulseaudio.h, [HAVE_PA_HEADERS=true], [HAVE_PA_HEADERS=false]) if test x$TRY_PA = 'xyes' then if test $HAVE_PA_HEADERS = 'true' then BRISTOL_HAS_PA=-DBRISTOL_PA BRISTOL_PA_DIR=libbristolpulse BRISTOL_LIB_PA='-lbristolpulse -lpulse -lpulse-simple' BRISTOL_LIBPALIBS=-L$BPALIBS else $TRY_PA=no fi fi AC_SUBST(BRISTOL_HAS_PA) AC_SUBST(BRISTOL_PA_DIR) AC_SUBST(BRISTOL_LIB_PA) AC_SUBST(BRISTOL_LIBPALIBS) if test $prefix = "NONE"; then prefix=$ac_default_prefix fi BRISTOL_DIR=$prefix/share/bristol AC_SUBST(BRISTOL_DIR) AC_CONFIG_FILES([Makefile libbrightonC11/Makefile libbrightonX11/Makefile libbrighton/Makefile libbvg/Makefile libbristolaudio/Makefile libbristolmidi/Makefile libbristolic/Makefile libbristol/Makefile brighton/Makefile bristol/Makefile bin/startBristol bin/Makefile]) AC_OUTPUT echo echo $PACKAGE $VERSION : echo echo \| Build with OSS support ......................... : $HAVE_OSS echo \| Build with ALSA support ........................ : $HAVE_ALSA if test $HAVE_ALSA = "false" && test $TRY_ALSA = "yes" ; then echo \| Bristol needs libasound2-dev to be installed for ALSA support. fi echo \| Build with JACK support ........................ : $HAVE_JACK if test $HAVE_JACK = "false" && test $TRY_JACK = "yes" ; then echo \| Bristol needs jackd and libjack-dev to be installed for JACK support. fi echo \| Build with JACK MIDI support ................... : $HAVE_JACK_MIDI # # This will be 0.50.5 echo \| Build with JACK Session support ................ : $jack_session_found if test x$TRY_PA = 'xyes' ; then echo \| Build with PA support .......................... : true fi if test $DEFAULT_JACK = "yes"; then echo \| Default audio drivers .......................... : jack else echo \| Default audio drivers .......................... : alsa fi if test $DEFAULT_JACK_MIDI = "yes"; then echo \| Default MIDI drivers ........................... : jack else echo \| Default MIDI drivers ........................... : alsa fi if test $USE_SEMAPHORE = "yes"; then echo \| Build with semaphore support.................... : true if test $USE_SEM_OPEN = "yes"; then echo \| Build with sem_open ............................ : true fi fi if test $USE_BARRIER == "yes"; then echo \| Build with jrb memory barrier .................. : true fi echo \| Build with Graphical Interface ................. : $HAVE_XHEADERS if test "x$TRY_X11" = "xyes"; then echo \| Compile with GUI support ....................... : true if test "x$TRY_SHMIMAGE" = "xyes"; then echo \| Build with XShmImage support ................... : true fi if test $TRY_XIMAGE != "yes"; then echo \| Build with XImage support ...................... : false else if test $HAVE_XHEADERS = "false"; then echo \| Bristol needs libX11-dev installed to support a grpahical interface fi fi else echo \| Compile with X11 support ....................... : false fi echo \| Bin directory .................................. : ${prefix}/bin echo \| Lib directory .................................. : ${prefix}/lib echo \| Data directory ................................. : $BRISTOL_DIR echo \| Default voicecount ............................. : BRISTOL_VOICECOUNT=$_BRISTOL_VOICES if test $BRR != 10; then echo \| Envelope max ramp time ......................... : $BRR seconds fi if test x$USE_EXP_ATTACK == "xyes"; then echo \| Envelope attack type ........................... : exponential fi echo \| author ......................................... : Nick Copeland echo \| email .......................................... : nickycopeland@hotmail.com echo \| web ............................................ : http://bristol.sf.net echo echo execute \'make install\' then \'startBristol\' echo if test -f ${BRISTOL_DIR}/bitmaps/blueprints/mini.xpm ; then echo To get the benefits of the compressed bitmaps you are advised to run a echo \'make uninstall\' before building this release. echo fi bristol-0.60.11/libbristolaudio/0000755000175000017500000000000012100257364013525 500000000000000bristol-0.60.11/libbristolaudio/Makefile.in0000644000175000017500000004275612073601233015525 00000000000000# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = libbristolaudio DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LIBRARIES = $(noinst_LIBRARIES) ARFLAGS = cru libbristolaudio_a_AR = $(AR) $(ARFLAGS) libbristolaudio_a_LIBADD = am_libbristolaudio_a_OBJECTS = audioEngineALSA.$(OBJEXT) \ audioGUIALSA.$(OBJEXT) audioMastering.$(OBJEXT) \ audioEngine.$(OBJEXT) audioGUI.$(OBJEXT) \ audioEngineOSS.$(OBJEXT) audioGUIOSS.$(OBJEXT) \ audioEngineJack.$(OBJEXT) libbristolaudio_a_OBJECTS = $(am_libbristolaudio_a_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libbristolaudio_a_SOURCES) DIST_SOURCES = $(libbristolaudio_a_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALSA_CFLAGS = @ALSA_CFLAGS@ ALSA_LIBS = @ALSA_LIBS@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BRIGHTON_HAS_AUTOZOOM = @BRIGHTON_HAS_AUTOZOOM@ BRIGHTON_HAS_SHMIMAGE = @BRIGHTON_HAS_SHMIMAGE@ BRIGHTON_HAS_X11 = @BRIGHTON_HAS_X11@ BRIGHTON_HAS_XIMAGE = @BRIGHTON_HAS_XIMAGE@ BRIGHTON_LIBB11 = @BRIGHTON_LIBB11@ BRIGHTON_LIBX11 = @BRIGHTON_LIBX11@ BRIGHTON_LIBXEXT = @BRIGHTON_LIBXEXT@ BRIGHTON_LIBXLIBS = @BRIGHTON_LIBXLIBS@ BRIGHTON_X11_DIR = @BRIGHTON_X11_DIR@ BRISTOL_BARRIER = @BRISTOL_BARRIER@ BRISTOL_DIR = @BRISTOL_DIR@ BRISTOL_HAS_ALSA = @BRISTOL_HAS_ALSA@ BRISTOL_HAS_DRAIN = @BRISTOL_HAS_DRAIN@ BRISTOL_HAS_JACK = @BRISTOL_HAS_JACK@ BRISTOL_HAS_JACK_MIDI = @BRISTOL_HAS_JACK_MIDI@ BRISTOL_HAS_JACK_SESSION = @BRISTOL_HAS_JACK_SESSION@ BRISTOL_HAS_LIBLO = @BRISTOL_HAS_LIBLO@ BRISTOL_HAS_OSS = @BRISTOL_HAS_OSS@ BRISTOL_HAS_PA = @BRISTOL_HAS_PA@ BRISTOL_JACK_DEFAULT = @BRISTOL_JACK_DEFAULT@ BRISTOL_JACK_DEFAULT_MIDI = @BRISTOL_JACK_DEFAULT_MIDI@ BRISTOL_JACK_MULTI_CLOSE = @BRISTOL_JACK_MULTI_CLOSE@ BRISTOL_LIBPALIBS = @BRISTOL_LIBPALIBS@ BRISTOL_LIB_PA = @BRISTOL_LIB_PA@ BRISTOL_LIN_ATTACK = @BRISTOL_LIN_ATTACK@ BRISTOL_MAJOR_VERSION = @BRISTOL_MAJOR_VERSION@ BRISTOL_MICRO_VERSION = @BRISTOL_MICRO_VERSION@ BRISTOL_MINOR_VERSION = @BRISTOL_MINOR_VERSION@ BRISTOL_PA_DIR = @BRISTOL_PA_DIR@ BRISTOL_SEMAPHORE = @BRISTOL_SEMAPHORE@ BRISTOL_SEM_OPEN = @BRISTOL_SEM_OPEN@ BRISTOL_SO_VERSION = @BRISTOL_SO_VERSION@ BRISTOL_VERSION = @BRISTOL_VERSION@ BRR = @BRR@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFAULT_AUDIO_FLAG = @DEFAULT_AUDIO_FLAG@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JACK_CFLAGS = @JACK_CFLAGS@ JACK_LIBS = @JACK_LIBS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBLO_CFLAGS = @LIBLO_CFLAGS@ LIBLO_LIBS = @LIBLO_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ _BRISTOL_VOICES = @_BRISTOL_VOICES@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = foreign AM_CFLAGS = -pthread -Wall -g -I$(srcdir)/../include/slab -I$(srcdir)/../include/bristol -DBRISTOL_HAS_OSS=@BRISTOL_HAS_OSS@ @BRISTOL_HAS_DRAIN@ -DBRISTOL_HAS_ALSA=@BRISTOL_HAS_ALSA@ @BRISTOL_HAS_JACK@ @BRISTOL_HAS_JACK_MIDI@ @BRISTOL_HAS_JACK_SESSION@ @ALSA_CFLAGS@ @JACK_CFLAGS@ @BRISTOL_HAS_PA@ #libbristolaudio_la_LDFLAGS=-export-dynamic -version-info @BRISTOL_SO_VERSION@ #libbristolaudio_la_LIBADD=@ALSA_LIBS@ @JACK_LIBS@ noinst_LIBRARIES = libbristolaudio.a libbristolaudio_a_SOURCES = audioEngineALSA.c audioGUIALSA.c audioMastering.c audioEngine.c audioGUI.c audioEngineOSS.c audioGUIOSS.c audioEngineJack.c all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign libbristolaudio/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign libbristolaudio/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libbristolaudio.a: $(libbristolaudio_a_OBJECTS) $(libbristolaudio_a_DEPENDENCIES) $(EXTRA_libbristolaudio_a_DEPENDENCIES) -rm -f libbristolaudio.a $(libbristolaudio_a_AR) libbristolaudio.a $(libbristolaudio_a_OBJECTS) $(libbristolaudio_a_LIBADD) $(RANLIB) libbristolaudio.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audioEngine.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audioEngineALSA.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audioEngineJack.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audioEngineOSS.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audioGUI.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audioGUIALSA.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audioGUIOSS.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audioMastering.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLIBRARIES ctags distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am tags uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: bristol-0.60.11/libbristolaudio/audioEngineALSA.c0000644000175000017500000003512311746476475016532 00000000000000 /* * Diverse SLab audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* * FILE: * audioEngineALSA.c * * NOTES: * This was taken from latency.c, and tweaked to be the device configurator * for the SLab audio interface. This file will only contain the code used by * the SLab audio daemon - configures the desired resolutions, fragments, etc. * * The code for the GUI, which is only concerned with the sound source mixing * interface, is separate, in audioGUIALSA.c * * CALLS: * asoundlib routines. * * IS CALLED BY: * If it remains as clean as I intend, it should only come from audioEngine.c * if the ALSA flags are configured on this device. Oops, there ended * up with two exceptions, which I could remove. audioWrite()/audioRead() are * called from libslabadiod. Yes, I should change this, but I do not want yet * another level of indirection for the read/write calls. * * As of 14/12/99 this uses a single duplex channel. Going to change it to use * up to two channels: record channel if not WRONLY, playback channel if not * RDONLY device. This is a fair bit of work. * * 1/3/00 - incorporated alterations for ALSA Rev 0.5.X, with lots of #ifdef's. * 27/11/00 - ALSA still not operational. Going back to single duplex dev. * 1/1/1 - ALSA operational, but issues with IO Errors after recording period. */ #include #include "slabrevisions.h" #include "slabcdefs.h" #include "slabaudiodev.h" #include "bristol.h" #if (BRISTOL_HAS_ALSA == 1) #include "slabalsadev.h" #include #include #include #include #include #if defined(linux) #include #endif #ifdef SUBFRAGMENT #if (MACHINE == LINUX) #include #endif #endif #define DEF_FRAGSIZE 1024 #define DEF_FRAGCNT 32 #include static int adInit = 1, dummycapture = 0; static struct adev alsaDev[MAX_DEVICES + 1]; #define SND_PCM_OPEN_PLAYBACK SND_PCM_STREAM_PLAYBACK #define SND_PCM_OPEN_CAPTURE SND_PCM_STREAM_CAPTURE snd_output_t *output = NULL; /* * This assumes the API will manage the memory blocks allocated to the handles, * so will only reset them to NULL, not free them. */ int alsaDevClose(duplexDev *audioDev) { /* if (audioDev->cflags & SLAB_AUDIODBG printf(" alsaDevClose(%08x): %08x, %08x\n", audioDev, &alsaDev[audioDev->devID].chandle, &alsaDev[audioDev->devID].phandle); */ if (dummycapture == 0) { if (alsaDev[audioDev->devID].chandle != (snd_pcm_t *) NULL) { if (audioDev->cflags & SLAB_AUDIODBG) printf("closing alsa capture channel\n"); /* snd_pcm_unlink((void *) alsaDev[audioDev->devID].chandle); */ snd_pcm_drop((void *) alsaDev[audioDev->devID].chandle); snd_pcm_hw_free((void *) alsaDev[audioDev->devID].chandle); snd_pcm_close((void *) alsaDev[audioDev->devID].chandle); alsaDev[audioDev->devID].chandle = (snd_pcm_t *) NULL; } } if (alsaDev[audioDev->devID].phandle != (snd_pcm_t *) NULL) { if (audioDev->cflags & SLAB_AUDIODBG) printf("closing alsa playback channel\n"); snd_pcm_drain((void *) alsaDev[audioDev->devID].phandle); snd_pcm_hw_free((void *) alsaDev[audioDev->devID].phandle); snd_pcm_close((void *) alsaDev[audioDev->devID].phandle); alsaDev[audioDev->devID].phandle = (snd_pcm_t *) NULL; } audioDev->fd = audioDev->fd2 = -1; bristolfree(output); output = NULL; return(0); } int alsaChannelConfigure(duplexDev *audioDev, snd_pcm_t **handle, snd_pcm_hw_params_t **h_params, snd_pcm_sw_params_t **s_params, char *dir) { char *devicename; int err, stream; snd_pcm_uframes_t count; unsigned long fragsize; int nfds; struct pollfd *pfds; snd_pcm_hw_params_alloca(h_params); memset(*h_params, 0, sizeof(snd_pcm_hw_params)); snd_pcm_sw_params_alloca(s_params); memset(*s_params, 0, sizeof(snd_pcm_hw_params)); if (audioDev->fragSize == 0) audioDev->fragSize = DEF_FRAGSIZE; devicename = strdup(audioDev->devName); if (strcmp(dir, "capture") == 0) stream = SND_PCM_STREAM_CAPTURE; else stream = SND_PCM_STREAM_PLAYBACK; /* * Open the device. This use of handle may cause a small memory leak when * the audio interface is restarted, I don't know if I own the memory or * if the library does. */ bristolfree(*handle); if (snd_pcm_open(handle, devicename, stream, 0) < 0) { fprintf(stderr, "Error opening PCM device %s\n", devicename); bristolfree(devicename); return(-1); } bristolfree(devicename); if (snd_pcm_hw_params_any(*handle, *h_params) < 0) { printf("Cound not get %s any params\n", dir); return(-1); } if (snd_pcm_hw_params_set_access(*handle, *h_params, SND_PCM_ACCESS_RW_INTERLEAVED) < 0) { printf("Could not set %s access methods\n", dir); return(-1); } if (snd_pcm_hw_params_set_format(*handle, *h_params, SND_PCM_FORMAT_S16_LE) < 0) { printf("Could not set %s format\n", dir); return(-1); } if (snd_pcm_hw_params_set_channels(*handle, *h_params, audioDev->channels) < 0) { printf("Could not set channels\n"); return(-1); } if (snd_pcm_hw_params_set_rate_near(*handle, *h_params, (unsigned int *) &audioDev->writeSampleRate, 0) <0) { printf("Could not set %s rate to %i\n", dir, audioDev->writeSampleRate); return(-1); } /* * For bristol only supporting stereo synths this interface is fine. More * generally with 'n' channels this will fail however that is for future * study anyway * * The following only works for 16bit stereo samples. * * Can this warning, we are going to use Jack for multichannel stuff #warning Not compatible with alternative sample sizes or channel counts */ count = audioDev->fragSize >> 2; fragsize = count * audioDev->preLoad; if (snd_pcm_hw_params_set_period_size(*handle, *h_params, count, 0) < 0) { snd_pcm_uframes_t frames; printf("Could not configure %s period size\n", dir); snd_pcm_hw_params_get_period_size(*h_params, &frames, &stream); printf("period size is %i\n", (int) frames); return(-1); } if (snd_pcm_hw_params_set_periods( *handle, *h_params, audioDev->preLoad, 0) < 0) { printf("Could not configure %s periods\n", dir); return(-1); } if ((err = snd_pcm_hw_params(*handle, *h_params)) < 0) { printf("Could not set %s hardware parameters: %s\n", dir, snd_strerror(err)); return(-1); } if (snd_pcm_hw_params_set_buffer_size( *handle, *h_params, count * audioDev->preLoad) < 0) { printf("Could not configure %s buffer size\n", dir); return(-1); } if (snd_pcm_sw_params_current(*handle, *s_params) < 0) { printf("Could not get %s current configuration\n", dir); return(-1); } if (snd_pcm_sw_params_set_start_threshold(*handle, /* *s_params, 0U) < 0) */ *s_params, 0x7fffffff) < 0) /* *s_params, audioDev->fragSize * 1024) < 0) */ { printf("Could not set %s start threshold\n", dir); return(-1); } if (snd_pcm_sw_params_set_stop_threshold(*handle, *s_params, count * audioDev->preLoad) < 0) { printf("Could not set %s stop threshold\n", dir); return(-1); } if (snd_pcm_sw_params_set_silence_threshold(*handle, *s_params, 0) < 0) { printf("Could not set %s stop threshold\n", dir); return(-1); } if (snd_pcm_sw_params_set_avail_min(*handle, *s_params, count) < 0) { printf("Could not set %s avail min\n", dir); return(-1); } if (snd_pcm_sw_params(*handle, *s_params) < 0) { printf("Could not configure %s software parameters\n", dir); return(-1); } snd_pcm_dump(*handle, output); nfds = snd_pcm_poll_descriptors_count(*handle); pfds = (struct pollfd *) bristolmalloc(sizeof (struct pollfd) * nfds); snd_pcm_poll_descriptors(*handle, pfds, nfds); if (strcmp(dir, "capture") == 0) { audioDev->fd2 = pfds[0].fd; if (snd_pcm_prepare(*handle) < 0) printf("prepare failure on capture channel\n"); } else { audioDev->fd = pfds[0].fd; if (snd_pcm_prepare(*handle) < 0) printf("prepare failure on playback channel\n"); } bristolfree(pfds); return(0); } /* * The rest of this code is for ALSA 0.9, and hopefully greater. Each new * minor revision introduces some serious redefinition of the interfaces. */ int alsaDevOpen(duplexDev *audioDev, int devID, int flags, int fragSize) { int err; /* * This is now a function of the engine, since it is using thread priority * rather than process priority scheduling. */ if (audioDev->cflags & SLAB_AUDIODBG) printf("opening device %s, flags %08x\n", audioDev->devName, audioDev->flags); if (adInit) { printf("init %i bytes of device structure\n", (int) sizeof(alsaDev)); bzero(alsaDev, sizeof(alsaDev)); adInit = 0; } if (audioDev->channels == 0) audioDev->channels = 2; if (audioDev->writeSampleRate == 0) audioDev->writeSampleRate = 44100; if (audioDev->readSampleRate == 0) audioDev->readSampleRate = 44100; if (flags == SLAB_OWRONLY) flags = SLAB_OWRONLY; else if (flags == SLAB_ORDONLY) flags = SLAB_RDONLY; else if (flags == SLAB_ORDWR) flags = SLAB_OWRONLY|SLAB_RDONLY; bristolfree(output); output = NULL; err = snd_output_stdio_attach(&output, stdout, 0); /* * Open and configure the playback channel. */ if (flags & SLAB_OWRONLY) { if (audioDev->cflags & SLAB_AUDIODBG) printf("open playback on %s, pre %i\n", audioDev->devName, audioDev->preLoad); if (alsaChannelConfigure(audioDev, &alsaDev[audioDev->devID].phandle, &alsaDev[audioDev->devID].p_params, &alsaDev[audioDev->devID].p_swparams, "playback") < 0) return(-1); } /* * And do the same for the capture channel */ if ((flags & SLAB_RDONLY) && (strcmp(audioDev->devName, "plug:dmix") != 0)) { if (audioDev->cflags & SLAB_AUDIODBG) printf("open capture on %s: pre %i\n", audioDev->devName, audioDev->preLoad); if (alsaChannelConfigure(audioDev, &alsaDev[audioDev->devID].chandle, &alsaDev[audioDev->devID].c_params, &alsaDev[audioDev->devID].c_swparams, "capture") < 0) return(-1); } else dummycapture = 1; bristolfree(audioDev->fragBuf); audioDev->fragBuf = (char *) bristolmalloc(audioDev->fragSize); /*printf(" alsaDevOpen(%08x): %08x, %08x\n", */ /* audioDev, */ /* &alsaDev[audioDev->devID].chandle, */ /* &alsaDev[audioDev->devID].phandle); */ // snd_pcm_link(alsaDev[audioDev->devID].chandle, // alsaDev[audioDev->devID].phandle); return(0); } int alsaDevAudioStart(duplexDev *audioDev) { #ifdef _BRISTOL_DRAIN int err, i; printf("restart audio interface %i %i\n", audioDev->samplecount, audioDev->preLoad); snd_pcm_drop(alsaDev[audioDev->devID].phandle); snd_pcm_prepare(alsaDev[audioDev->devID].phandle); for (i = 0; i < audioDev->preLoad; i++) snd_pcm_writei(alsaDev[audioDev->devID].phandle, audioDev->fragBuf, audioDev->samplecount); if (dummycapture == 0) { snd_pcm_drop(alsaDev[audioDev->devID].chandle); snd_pcm_prepare(alsaDev[audioDev->devID].chandle); } if ((err = snd_pcm_start(alsaDev[audioDev->devID].phandle)) < 0) { printf("Playback start error: %s\n", snd_strerror(err)); return(-1); } if (dummycapture == 0) { if ((err = snd_pcm_start(alsaDev[audioDev->devID].chandle)) < 0) { printf("Record start error: %s\n", snd_strerror(err)); return(-1); } } #else if ((audioDev->flags == ADIOD_OUTPUT) || (audioDev->flags == ADIOD_DUPLEX)) { printf("Start playback %i\n", audioDev->preLoad); if ((err = snd_pcm_start(alsaDev[audioDev->devID].phandle)) < 0) { printf("Playback start error: %s\n", snd_strerror(err)); return(-1); } } if ((audioDev->flags == ADIOD_INPUT) || (audioDev->flags == ADIOD_DUPLEX)) { if (dummycapture == 0) { printf("Start capture\n"); if ((err = snd_pcm_start(alsaDev[audioDev->devID].chandle)) < 0) { printf("Record start error: %s\n", snd_strerror(err)); return(-1); } } } #endif return(0); } void showstat(snd_pcm_t *handle, size_t frames) { int err; snd_pcm_status_t *status; snd_pcm_status_alloca(&status); if ((err = snd_pcm_status(handle, status)) < 0) { printf("Stream status error: %s\n", snd_strerror(err)); exit(0); } printf("*** frames = %li ***\n", (long)frames); snd_pcm_status_dump(status, output); } #endif /* BRISTOL_HAS_ALSA */ int audioWrite(audioDev, buffer, count) duplexDev *audioDev; char *buffer; int count; { if (audioDev->flags & AUDIO_DUMMY) return(count); if (audioDev->flags & SLAB_AUDIODBG2) printf("audioWrite(%i)\n", count); #if (BRISTOL_HAS_ALSA == 1) /* * This if for ALSA 0.9 and 1.0 */ if (audioDev->siflags & AUDIO_ALSA) { long r; /* * Slab historically used byte buffer sizes. ALSA 0.9 uses frames, so * we now work in samples. */ while((r = snd_pcm_writei(alsaDev[audioDev->devID].phandle, buffer, count)) == EAGAIN) printf("Do again\n"); if (r < 0) { printf(" Write Error: %s %i\n", snd_strerror(r), (int) r); return(r); } return(count); } #endif /* BRISTOL_HAS_ALSA */ #ifdef BRISTOL_PA if (audioDev->siflags & AUDIO_PULSE) return(pulseDevWrite(audioDev->fd, buffer, count)); #endif /* * Otherwise just to a normal OSS fd write operation. Since bristol release * went to 1.0 started using sample counts rather than bytes, so OSS has to * calculate the actual buffer size. Going to be lazy for now, and assume * short samples..... Hm. */ return(write(audioDev->fd, buffer, count * 2 * audioDev->channels)); } int audioRead(audioDev, buffer, count) duplexDev *audioDev; char *buffer; int count; { int result; if (audioDev->flags & SLAB_AUDIODBG2) printf("audioRead(%i)\n", count); if (audioDev->flags & AUDIO_DUMMY) { usleep(100000); return(count * 2 * audioDev->channels); } #if (BRISTOL_HAS_ALSA == 1) /* * This if for ALSA 0.9 and 1.0 printf("audioRead(%x, %i)\n", buffer, count); */ if (dummycapture) { memset(buffer, 0, audioDev->fragSize); return(count); } if (audioDev->siflags & AUDIO_ALSA) return(snd_pcm_readi(alsaDev[audioDev->devID].chandle, buffer, count)); #endif #ifdef BRISTOL_PA if (audioDev->siflags & AUDIO_PULSE) return(pulseDevRead(audioDev->fd2, buffer, count)); #endif /* * If this is not an ALSA dev, do a normal OSS fd read operation. */ result = read(audioDev->fd2, buffer, count * 2 * audioDev->channels); return(result / 2 / audioDev->channels); } bristol-0.60.11/libbristolaudio/Makefile.am0000755000175000017500000000121012073330071015472 00000000000000AUTOMAKE_OPTIONS = foreign AM_CFLAGS = -pthread -Wall -g -I$(srcdir)/../include/slab -I$(srcdir)/../include/bristol -DBRISTOL_HAS_OSS=@BRISTOL_HAS_OSS@ @BRISTOL_HAS_DRAIN@ -DBRISTOL_HAS_ALSA=@BRISTOL_HAS_ALSA@ @BRISTOL_HAS_JACK@ @BRISTOL_HAS_JACK_MIDI@ @BRISTOL_HAS_JACK_SESSION@ @ALSA_CFLAGS@ @JACK_CFLAGS@ @BRISTOL_HAS_PA@ #libbristolaudio_la_LDFLAGS=-export-dynamic -version-info @BRISTOL_SO_VERSION@ #libbristolaudio_la_LIBADD=@ALSA_LIBS@ @JACK_LIBS@ noinst_LIBRARIES = libbristolaudio.a libbristolaudio_a_SOURCES = audioEngineALSA.c audioGUIALSA.c audioMastering.c audioEngine.c audioGUI.c audioEngineOSS.c audioGUIOSS.c audioEngineJack.c bristol-0.60.11/libbristolaudio/audioEngineOSS.c0000644000175000017500000001675211746476475016465 00000000000000 /* * Diverse SLab audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #if (BRISTOL_HAS_OSS == 1) /* * This may want to be /usr/lib/oss/include/sys/soundcard.h if someone has * purchased the 4Front drivers? */ #include #endif #include #include #include #include #include #include /* * Audio device structure format definitions. */ #include "slabrevisions.h" #include "slabaudiodev.h" #include "bristol.h" int newInitAudioDevice2(duplexDev *, int, int); static void checkAudioCaps2(duplexDev *, int, int); int ossAudioInit(audioDev, devID, fragSize) duplexDev *audioDev; int devID; { #if (BRISTOL_HAS_OSS == 1) int results, data = 0, mode; //audioDev->cflags |= SLAB_AUDIODBG; printf("ossAudioInit(%p, %i, %i)\n", audioDev, devID, fragSize); /* * This is what we are going to go for. */ fragSize = 1024; /* * Clear out this buffer. */ if (audioDev->fragBuf != (char *) NULL) { bristolfree(audioDev->fragBuf); audioDev->fragBuf = (char *) NULL; } checkAudioCaps2(audioDev, devID, audioDev->fd); if (fragSize != 0) { int data; switch(fragSize) { case 1024: data = 0x0040000a; break; case 2048: data = 0x0020000b; break; case 4096: data = 0x0010000c; break; case 8192: data = 0x0008000d; break; case 16384: data = 0x0004000e; break; /* * This is 8192 blockSampleSize, where internally we deal with * ints or floats, but the IO buffer is in shorts. */ case 32768: default: data = 0x0004000f; break; } if ((results = ioctl(audioDev->fd, SNDCTL_DSP_SETFRAGMENT, &data)) == 0) { if (audioDev->cflags & SLAB_AUDIODBG) printf("ioctl(%i, SNDCTL_DSP_SETFRAGMENT, %x)\n", audioDev->fd, data); } else printf("ioctl(%i, SNDCTL_DSP_SETFRAGMENT, %x): failed\n", audioDev->fd, data); } /* * Check capabilities. */ if (audioDev->cflags & SLAB_AUDIODBG) printf("ioctl(%i, SNDCTL_DSP_GETCAPS, &0x%x)\n", audioDev->fd, data); if ((results = ioctl(audioDev->fd, SNDCTL_DSP_GETCAPS, &data)) == 0) { audioDev->genCaps = data; if (audioDev->cflags & SLAB_AUDIODBG) { if ((audioDev->genCaps & SNDCTL_DSP_SETTRIGGER) != 0) printf("Device %s does support SNDCTL_SET_TRIGGER\n", audioDev->devName); else printf("Device %s does NOT support SNDCTL_SET_TRIGGER\n", audioDev->devName); } /* * Take this out, we only need to check the options here. */ if (data & DSP_CAP_DUPLEX) { if (audioDev->cflags & SLAB_AUDIODBG) printf("ioctl(%i, SNDCTL_DSP_SETDUPLEX, &0x%x)\n", audioDev->fd, data); if (ioctl(audioDev->fd, SNDCTL_DSP_SETDUPLEX, &data) < 0) printf("Failed to set Duplex\n"); else printf("Set to Duplex\n"); } } if ((audioDev->cflags & SLAB_FDUP) == 0) audioDev->fd2 = audioDev->fd; else audioDev->fd2 = fcntl(audioDev->fd, F_DUPFD, audioDev->fd); /* * Set to required resolution. */ if (audioDev->cflags & (SLAB_8_BIT_OUT|SLAB_8_BIT_IN)) { data = 8; /* THIS SHOULD USE THE soundcard.h DEFINITION */ } else data = 16; if (audioDev->cflags & SLAB_AUDIODBG) printf("ioctl(%i, SNDCTL_DSP_SETFMT, &%i)\n", audioDev->fd, data); if ((results = ioctl(audioDev->fd, SNDCTL_DSP_SETFMT, &data)) == 0) { if (audioDev->cflags & SLAB_AUDIODBG) printf("Set audio format: %i\n", data); } else printf("Set resolution failed: %i\n", results); /* * Set to stereo */ data = 1; if (audioDev->cflags & SLAB_AUDIODBG) printf("ioctl(%i, SNDCTL_DSP_STEREO, &%i)\n", audioDev->fd, data); mode = SNDCTL_DSP_STEREO; if ((results = ioctl(audioDev->fd, mode, &data)) == 0) { if (audioDev->cflags & SLAB_AUDIODBG) printf("Set to stereo: %i\n", data); } else printf("Set stereo failed: %i\n", results); /* * Set to AUDIO_RATE Hz */ data = audioDev->writeSampleRate; if (audioDev->cflags & SLAB_AUDIODBG) printf("ioctl(%i, SNDCTL_DSP_SPEED, &%i)\n", audioDev->fd, data); if ((results = ioctl(audioDev->fd, SNDCTL_DSP_SPEED, &data)) == 0) { if (audioDev->cflags & SLAB_AUDIODBG) printf("Set audio readwrite rate to %i\n", data); } else printf("Set line frequency failed: %i\n", results); /* * Save the actual physical line rate for conversions later */ audioDev->writeSampleRate = data; /* * Save the actual physical line rate for conversions later */ audioDev->readSampleRate = data; /* * Finally get the output fragment size. We can have an awkward problem if * this fragment size is not the same as the primary device - with sync IO * where we readBuffer/writeBuffer, having different sizes very soon puts * the audio daemon in to a lock state. To overcome this, and to support * eventual realtime mixing (where we will specify a small buffersize * anyway) we should add a "desired buffer size" param, or have the adiod * routines cater for differences. */ data = 0; if ((results = ioctl(audioDev->fd, SNDCTL_DSP_GETBLKSIZE, &data)) == 0) { audioDev->fragSize = data; if (audioDev->cflags & SLAB_AUDIODBG) printf("ioctl(%i, SNDCTL_DSP_GETBLKSIZE, &0): %i bytes\n", audioDev->fd, audioDev->fragSize); audioDev->fragBuf = (char *) bristolmalloc(audioDev->fragSize); } else printf("Get frag size failed: %i\n", results); #ifdef _BRISTOL_DRAIN for (data = 0; data < audioDev->preLoad; data++) results = write(audioDev->fd, audioDev->fragBuf, audioDev->samplecount * 2 * audioDev->channels); #endif #endif /* BRISTOL_HAS_OSS */ return(0); } /* * Needs to be ALSAfied - ie, binned if we have alsa - this is GUI stuff. */ static void checkAudioCaps2(audioDev, devID, fd) duplexDev *audioDev; int devID, fd; { int i, stereodevs = 0; #if (BRISTOL_HAS_OSS == 1) printf("checkAudioCaps2(%i, %i)\n", devID, fd); if (ioctl(fd, SOUND_MIXER_READ_STEREODEVS, &stereodevs) == -1) { if (audioDev->cflags & SLAB_AUDIODBG) printf("Failed to get stereo capabilities: %08x\n", stereodevs); } else { if (audioDev->cflags & SLAB_AUDIODBG) printf("Capabilities: %08x\n", stereodevs); audioDev->stereoCaps = stereodevs; } for (i = 1; i < 131072; i = i << 1) { if (i & stereodevs) printf("Found stereo dev %08x\n", i); } stereodevs = 0; if (ioctl(fd, SOUND_MIXER_READ_DEVMASK, &stereodevs) == -1) { if (audioDev->cflags & SLAB_AUDIODBG) printf("Failed to get audio capabilities: %08x\n", stereodevs); } else { if (audioDev->cflags & SLAB_AUDIODBG) printf("Mono Capabilities: %08x\n", stereodevs); audioDev->monoCaps = stereodevs; } stereodevs = 0; if (ioctl(fd, SOUND_MIXER_READ_RECMASK, &stereodevs) == -1) { if (audioDev->cflags & SLAB_AUDIODBG) printf("Failed to get record capabilities: %08x\n", stereodevs); } else { if (audioDev->cflags & SLAB_AUDIODBG) printf("Record Caps: %08x\n", stereodevs); audioDev->recordCaps = stereodevs; } #endif /* BRISTOL_HAS_OSS */ } bristol-0.60.11/libbristolaudio/audioGUIALSA.c0000644000175000017500000003153211746476475015751 00000000000000 /* * Diverse SLab audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* * These are largely device specific operations for the audio devices. Some of * the calls are general, but may eventually be used by several of the SLab * applications. * * This file contains the ALSA specific calls. */ #ifdef DEBUG #include #endif #include #include #ifdef SUBFRAGMENT #include #endif #include /* * Audio device structure format definitions. */ #include "slabaudiodev.h" #if (BRISTOL_HAS_ALSA == 1) #include "slabalsadev.h" static struct adev alsaDev[MAX_DEVICES + 1]; int checkAudioALSAcaps(audioDev, devID, fd) duplexDev *audioDev; int devID, fd; { return(0); } const char * getAlsaName(duplexDev *audioDev, int cont) { snd_mixer_selem_id_t *sid; sid = (snd_mixer_selem_id_t *)(((char *) alsaDev[audioDev->devID].mixer_sid) + snd_mixer_selem_id_sizeof() * cont); if (audioDev->cflags & SLAB_AUDIODBG) printf("getAlsaName(%i): \"%s\"\n", cont, snd_mixer_selem_id_get_name(sid)); return(snd_mixer_selem_id_get_name(sid)); } int getAlsaStereoStatus(duplexDev *audioDev, int cont) { /* * Cannot find a stereo status switch, so for now assume that only * Master Mono and Mic are mono. */ if (strcmp(getAlsaName(audioDev, cont), "Master Mono") == 0) return(1); if (strcmp(getAlsaName(audioDev, cont), "Mic") == 0) return(1); if (strcmp(getAlsaName(audioDev, cont), "Center") == 0) return(1); if (strcmp(getAlsaName(audioDev, cont), "LFE") == 0) return(1); if (strcmp(getAlsaName(audioDev, cont), "Wave Center") == 0) return(1); if (strcmp(getAlsaName(audioDev, cont), "Wave LFE") == 0) return(1); if (strcmp(getAlsaName(audioDev, cont), "Phone") == 0) return(1); if (strcmp(getAlsaName(audioDev, cont), "PC Speaker") == 0) return(1); if (strcmp(getAlsaName(audioDev, cont), "Headphone LFE") == 0) return(1); if (strcmp(getAlsaName(audioDev, cont), "Headphone Center") == 0) return(1); if (strcmp(getAlsaName(audioDev, cont), "3D Control - Switch") == 0) return(1); if (strcmp(getAlsaName(audioDev, cont), "Mic Boost (+20dB)") == 0) return(1); if (strcmp(getAlsaName(audioDev, cont), "External Amplifier Power Down") == 0) return(1); if (strcmp(getAlsaName(audioDev, cont), "3D Control Sigmatel - Depth") == 0) return(1); return(2); } int setAlsaValue(duplexDev *audioDev, int cont, int side, int value) { snd_mixer_elem_t *elem; snd_mixer_selem_id_t *sid; long vmin, vmax, vol; if ((--side == 1) && (getAlsaStereoStatus(audioDev, cont) < 2)) return(0); sid = (snd_mixer_selem_id_t *)(((char *) alsaDev[audioDev->devID].mixer_sid) + snd_mixer_selem_id_sizeof() * cont); elem = snd_mixer_find_selem(alsaDev[audioDev->devID].mh, sid); if (audioDev->cflags & SLAB_AUDIODBG) printf("setAlsaValue(%i, %i, %i)\n", cont, side, value); if (snd_mixer_selem_has_playback_volume(elem)) { if (audioDev->cflags & SLAB_AUDIODBG) printf("HAS PLAYBACK FOUND\n"); snd_mixer_selem_get_playback_volume_range(elem, &vmin, &vmax); } else { if (audioDev->cflags & SLAB_AUDIODBG) printf("HAS CAPTURE FOUND\n"); snd_mixer_selem_get_capture_volume_range(elem, &vmin, &vmax); } vol = value * (vmax - vmin) / 100; /* * If you get violations in this code, with assert failures in the sound * library then it is likely this controller is either mono, or does not * support continuous control (is a switch). I should work on the correct * way to determine the capabilities of a device */ if (snd_mixer_selem_has_playback_volume(elem)) { if (audioDev->cflags & SLAB_AUDIODBG) printf("PLAYBACK VOLUME\n"); if (snd_mixer_selem_set_playback_volume(elem, side, vol) < -1) printf("failed to set value\n"); } else if (snd_mixer_selem_has_capture_volume(elem)) { if (audioDev->cflags & SLAB_AUDIODBG) printf("CAPTURE VOLUME\n"); if (snd_mixer_selem_set_capture_volume(elem, side, vol) < -1) printf("failed to set value\n"); } return(0); } /* * This is for ALSA 0.9, there were such massive alterations to the audio * interface definitions that a general rewrite was required. * This is always painful stuff, hopefully after this release things will * be a bit more stable. */ int validAlsaDev(duplexDev *audioDev, int cont) { if (cont >= alsaDev[audioDev->devID].elem_count) return(0); return(1); } int getAlsaRecordability(duplexDev *audioDev, int cont) { snd_mixer_elem_t *elem; snd_mixer_selem_id_t *sid; if (audioDev->cflags & SLAB_AUDIODBG) printf("getRecordability\n"); sid = (snd_mixer_selem_id_t *)(((char *) alsaDev[audioDev->devID].mixer_sid) + snd_mixer_selem_id_sizeof() * cont); elem = snd_mixer_find_selem(alsaDev[audioDev->devID].mh, sid); if (snd_mixer_selem_has_capture_switch(elem)) return(0); return(-2); } int getAlsaMutability(duplexDev *audioDev, int cont) { snd_mixer_elem_t *elem; snd_mixer_selem_id_t *sid; if (audioDev->cflags & SLAB_AUDIODBG) printf("getMutability\n"); sid = (snd_mixer_selem_id_t *)(((char *) alsaDev[audioDev->devID].mixer_sid) + snd_mixer_selem_id_sizeof() * cont); elem = snd_mixer_find_selem(alsaDev[audioDev->devID].mh, sid); /* * If we have playback capability then we also have mutability. */ if (snd_mixer_selem_has_playback_switch(elem)) return(1); return(0); } int getAlsaCapability(duplexDev *audioDev, int cont) { if (audioDev->cflags & SLAB_AUDIODBG) printf("getAlsaCapability(%i)\n", cont); if (cont >= alsaDev[audioDev->devID].elem_count) return(-1); return(cont); } int getAlsaCapByName(duplexDev *audioDev, char *name) { snd_mixer_selem_id_t *sid; int cont; if (name[strlen(name) - 1] == ' ') name[strlen(name) - 1] = '\0'; if (audioDev->cflags & SLAB_AUDIODBG) printf("getAlsaCapByName(%s)\n", name); for (cont = 0; cont < alsaDev[audioDev->devID].elem_count; cont++) { sid = (snd_mixer_selem_id_t *)(((char *) alsaDev[audioDev->devID].mixer_sid) + snd_mixer_selem_id_sizeof() * cont); if (strcmp(snd_mixer_selem_id_get_name(sid), name) == 0) return(cont); } return(-1); } int getAlsaValue(duplexDev *audioDev, int cont, int side) { snd_mixer_elem_t *elem; snd_mixer_selem_id_t *sid; long vmin, vmax, vol; sid = (snd_mixer_selem_id_t *)(((char *) alsaDev[audioDev->devID].mixer_sid) + snd_mixer_selem_id_sizeof() * cont); elem = snd_mixer_find_selem(alsaDev[audioDev->devID].mh, sid); if (audioDev->cflags & SLAB_AUDIODBG) printf("getAlsaValue\n"); if (snd_mixer_selem_has_playback_volume(elem)) { snd_mixer_selem_get_playback_volume_range(elem, &vmin, &vmax); snd_mixer_selem_get_playback_volume(elem, side, &vol); } else { snd_mixer_selem_get_capture_volume_range(elem, &vmin, &vmax); snd_mixer_selem_get_capture_volume(elem, side, &vol); } return(vol * 100 / (vmax - vmin)); } int setAudioALSAparam(duplexDev *audioDev, int devID, char *param, short left, short right) { int cont; if (audioDev->cflags & SLAB_AUDIODBG) printf("setAudioALSAparam(%i)\n", devID); if ((cont = getAlsaCapability(audioDev, devID)) == -1) { if (audioDev->cflags & SLAB_AUDIODBG) printf("could not find capability \"%s\"\n", param); return(0); } setAlsaValue(audioDev, cont, 1, left); if (getAlsaStereoStatus(audioDev, cont) > 1) setAlsaValue(audioDev, cont, 2, right); return(0); } int setAlsaRecordSource(duplexDev *audioDev, int cont, int position) { snd_mixer_elem_t *elem; snd_mixer_selem_id_t *sid; if (audioDev->cflags & SLAB_AUDIODBG) printf("setAlsaRecordSource\n"); sid = (snd_mixer_selem_id_t *)(((char *) alsaDev[audioDev->devID].mixer_sid) + snd_mixer_selem_id_sizeof() * cont); elem = snd_mixer_find_selem(alsaDev[audioDev->devID].mh, sid); if (snd_mixer_selem_has_capture_switch(elem)) { snd_mixer_selem_set_capture_switch(elem, 0, position); snd_mixer_selem_set_capture_switch(elem, 1, position); } return(0); } const char * getAlsaDeviceName(duplexDev *audioDev) { if (audioDev->cflags & SLAB_AUDIODBG) printf("setDeviceName(%s)\n", alsaDev[audioDev->devID].name); return(alsaDev[audioDev->devID].name); } int closeALSAmixer(audioDev) duplexDev *audioDev; { if (audioDev->cflags & SLAB_AUDIODBG) printf("closeALSAmixer(): %p\n", alsaDev[audioDev->devID].mh); if (alsaDev[audioDev->devID].mh != (snd_mixer_t *) NULL) { int err; if (audioDev->cflags & SLAB_AUDIODBG) printf("real closeALSAmixer(): %p\n", alsaDev[audioDev->devID].mh); if ((err = snd_mixer_close((void *) alsaDev[audioDev->devID].mh)) < 0) { if (audioDev->cflags & SLAB_AUDIODBG) printf("SND Mixer Close error: %s\n", snd_strerror(err)); } if ((err = snd_ctl_close(alsaDev[audioDev->devID].ch)) < 0) { if (audioDev->cflags & SLAB_AUDIODBG) printf("SND CTL Close error: %s\n", snd_strerror(err)); } } alsaDev[audioDev->devID].mh = NULL; alsaDev[audioDev->devID].ch = NULL; return(0); } int setAlsaMute(duplexDev *audioDev, int cont, int onoff) { snd_mixer_elem_t *elem; snd_mixer_selem_id_t *sid; int join; if (audioDev->cflags & SLAB_AUDIODBG) printf("setAlsaMute(%i, %i)\n", cont, onoff); sid = (snd_mixer_selem_id_t *)(((char *) alsaDev[audioDev->devID].mixer_sid) + snd_mixer_selem_id_sizeof() * cont); elem = snd_mixer_find_selem(alsaDev[audioDev->devID].mh, sid); join = snd_mixer_selem_has_playback_volume_joined(elem); if (audioDev->cflags & SLAB_AUDIODBG) printf("joined on device %i is %i\n", cont, join); if (snd_mixer_selem_has_playback_switch(elem)) { snd_mixer_selem_set_playback_switch(elem, 0, 1 - onoff); if (getAlsaStereoStatus(audioDev, cont) > 1) snd_mixer_selem_set_playback_switch(elem, 1, 1 - onoff); } return(1); } int openALSAmixer(duplexDev *audioDev) { int err, selem_count, elem_index = 0, mixer_n_selems = 0; snd_mixer_selem_id_t *sid; snd_ctl_card_info_alloca(&alsaDev[audioDev->devID].hwInfo); if (alsaDev[audioDev->devID].ch != NULL) return(0); if ((err = snd_ctl_open(&alsaDev[audioDev->devID].ch, &audioDev->mixerName[0], 0)) < 0) { printf("Could not open control interface\n"); return(-1); } if ((err = snd_ctl_card_info(alsaDev[audioDev->devID].ch, alsaDev[audioDev->devID].hwInfo)) < 0) { printf("Could not get hardware info\n"); return(-1); } alsaDev[audioDev->devID].name = strdup(snd_ctl_card_info_get_name(alsaDev[audioDev->devID].hwInfo)); if (audioDev->cflags & SLAB_AUDIODBG) { printf("Found: %s\n", alsaDev[audioDev->devID].name); printf("Hardware: %s\n", snd_ctl_card_info_get_mixername(alsaDev[audioDev->devID].hwInfo)); } if ((err = snd_mixer_open(&alsaDev[audioDev->devID].mh, 0)) < 0) { printf("Could not get mixer\n"); return(-1); } if ((err = snd_mixer_attach(alsaDev[audioDev->devID].mh, &audioDev->mixerName[0])) < 0) { printf("Could not attach to mixer %s\n", audioDev->mixerName); return(-1); } if ((err = snd_mixer_selem_register(alsaDev[audioDev->devID].mh, NULL, NULL)) < 0) { printf("Could not get mixer\n"); return(-1); } /* snd_mixer_set_callback(alsaDev[audioDev->devID].mh, mixer_event); */ if ((err = snd_mixer_load (alsaDev[audioDev->devID].mh)) < 0) { printf("Could not get mixer\n"); return(-1); } selem_count = snd_mixer_get_count(alsaDev[audioDev->devID].mh); alsaDev[audioDev->devID].mixer_sid = malloc(snd_mixer_selem_id_sizeof() * selem_count); for (alsaDev[audioDev->devID].eInfo[mixer_n_selems] = snd_mixer_first_elem(alsaDev[audioDev->devID].mh); alsaDev[audioDev->devID].eInfo[mixer_n_selems]; alsaDev[audioDev->devID].eInfo[mixer_n_selems] = snd_mixer_elem_next( alsaDev[audioDev->devID].eInfo[mixer_n_selems - 1])) { sid = (snd_mixer_selem_id_t *)(((char *) alsaDev[audioDev->devID].mixer_sid) + snd_mixer_selem_id_sizeof() * mixer_n_selems); snd_mixer_selem_get_id(alsaDev[audioDev->devID].eInfo[mixer_n_selems], sid); if (!snd_mixer_selem_is_active(alsaDev[audioDev->devID].eInfo[ mixer_n_selems])) break; mixer_n_selems++; } if (audioDev->cflags & SLAB_AUDIODBG) printf("found %i elements\n", mixer_n_selems); alsaDev[audioDev->devID].elem_count = mixer_n_selems; for (elem_index = 0; elem_index < mixer_n_selems; elem_index++) { sid = (snd_mixer_selem_id_t *)(((char *) alsaDev[audioDev->devID].mixer_sid) + snd_mixer_selem_id_sizeof() * elem_index); if (audioDev->cflags & SLAB_AUDIODBG) printf(" %s\n", snd_mixer_selem_id_get_name(sid)); } return(0); } #endif /* ALSA VERSION */ bristol-0.60.11/libbristolaudio/audioEngineJack.c0000644000175000017500000006314011746476475016662 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* * This file was taken out of the engine and moved to the audio library where * it correctly lies however it incorporates a few flags from bristol.h header * file that should really be removed to keep them independent. That is for * later study. */ /*#define DEBUG */ #include #include #include #include #include #include #include #include #ifdef _BRISTOL_JACK #if (BRISTOL_HAS_ALSA == 1) #include #endif /* * Drop this atomic stuff, it comes from the ALSA library and it not present on * a lot of systems. It is failing the Debian hurdles on some pretty wild host * architectures admittedly. Now the benefits of a real atomic access here are * small: there is one writer changing a value from 1 to zero. There is one * reader waiting for it to be zero, even as a non-atomic operation the worst * this can do is delay detection by a period. */ #ifdef DONT_USE_THIS //IATOMIC_DEFINED // Not very portable atomic_t closedown = ATOMIC_INIT(1); #else int closedown = 1; #endif #include "bristol.h" #include "bristoljack.h" #ifdef _BRISTOL_JACK_SESSION #include char sessionfile[1024]; char commandline[1024]; #endif extern int dupfd; static char defreg[8] = "bristol"; static char *regname = defreg; static jackDev jackdev; static float *outbuf, *inbuf; static int fsize = sizeof(jack_default_audio_sample_t); #ifdef _BRISTOL_JACK_MIDI extern void bristolJackSetMidiHandle(jack_client_t *); extern int jackMidiRoutine(jack_nframes_t, void *); #endif static void jack_shutdown(void *jackdev) { ((jackDev *) jackdev)->audiomain->atReq = BRISTOL_REQSTOP; } #ifdef _BRISTOL_JACK_SESSION /* * This is polled by the GUI to see if any session events need handling. It is * called fromm the idle loop of the engine parent thread. */ int bristolJackSessionCheck(audioMain *audiomain) { int rval = 0; if ((jackdev.sEvent == NULL) || (jack_set_session_callback == NULL)) return(0); snprintf(sessionfile, 1024, "%s%s", jackdev.sEvent->session_dir, regname); audiomain->sessionfile = sessionfile; snprintf(commandline, 1024, "%s -jsmfile \"${SESSION_DIR}%s\" -jsmuuid %s", audiomain->cmdline, regname, jackdev.sEvent->client_uuid); jackdev.sEvent->command_line = bristolmalloc(strlen(commandline) + 1); sprintf(jackdev.sEvent->command_line, "%s", commandline); /* * Need to flag the event for outside handling */ if (audiomain->debuglevel > 1) { if (jackdev.audiomain->jackUUID[0] != '\0') printf("jack session callback: %s %s\n", jackdev.sEvent->client_uuid, jackdev.audiomain->jackUUID); else printf("jack session callback: %s\n", jackdev.sEvent->client_uuid); printf("session file is %s\n", audiomain->sessionfile); printf("command line is %s\n", jackdev.sEvent->command_line); } rval = jackdev.sEvent->type; jack_session_reply(jackdev.handle, jackdev.sEvent); /* This was not malloc'ed do does not belong to jack session manager */ jack_session_event_free(jackdev.sEvent); jackdev.sEvent = NULL; return(rval); } void jack_session_callback(jack_session_event_t *event, void *arg) { if (jack_set_session_callback == NULL) return; if (jackdev.sEvent != NULL) jack_session_event_free(jackdev.sEvent); /* This is not a very good signaling method, it has race conditions */ jackdev.sEvent = event; } #endif static void bufstats(float *buf, int nframes, int stage) { float max = 0.0f, min = 1.0f; if (buf == NULL) return; for (; nframes > 0; nframes-= 8) { max = *buf > max? *buf:max; min = *buf < min? *buf:min; buf++; max = *buf > max? *buf:max; min = *buf < min? *buf:min; buf++; max = *buf > max? *buf:max; min = *buf < min? *buf:min; buf++; max = *buf > max? *buf:max; min = *buf < min? *buf:min; buf++; max = *buf > max? *buf:max; min = *buf < min? *buf:min; buf++; max = *buf > max? *buf:max; min = *buf < min? *buf:min; buf++; max = *buf > max? *buf:max; min = *buf < min? *buf:min; buf++; max = *buf > max? *buf:max; min = *buf < min? *buf:min; buf++; } printf("%i %p: min %f, max %f\n", stage, buf, min, max); } static int audioShim(jack_nframes_t nframes, void *jd) { jackDev *jackdev = (jackDev *) jd; register float *outL, *outR, *toutbuf = outbuf, gain; register int i, nint; #ifdef _BRISTOL_JACK_MIDI if (~jackdev->audiomain->flags & BRISTOL_JACK_DUAL) jackMidiRoutine(nframes, NULL); #endif /* * We may need to consider jack changing its nframes on the fly. Whilst * decreasing frames is not an issue, increasing them could be painful. * * I think I would prefer to reap all synths rather than code such an * operation, or alternatively add in a shim to do some reframing. * #warning need to consider jackd changes to nframes? */ if (jackdev->jack_in[BRISTOL_JACK_STDINL]) jackdev->inbuf[BRISTOL_JACK_STDINL] = jack_port_get_buffer(jackdev->jack_in[BRISTOL_JACK_STDINL], nframes); if (jackdev->jack_in[BRISTOL_JACK_STDINR]) jackdev->inbuf[BRISTOL_JACK_STDINR] = jack_port_get_buffer(jackdev->jack_in[BRISTOL_JACK_STDINR], nframes); if (jackdev->iocount > 0) { int j; float *buf; if ((gain = jackdev->audiomain->m_io_igc) <= 0) gain = 1.0; for (i = 0; i < jackdev->iocount; i++) { jackdev->inbuf[i] = buf = jackdev->audiomain->io_i[i] = jack_port_get_buffer(jackdev->jack_in[i], nframes); for (j = 0; j < nframes; j+=8) { *buf++ *= gain; *buf++ *= gain; *buf++ *= gain; *buf++ *= gain; *buf++ *= gain; *buf++ *= gain; *buf++ *= gain; *buf++ *= gain; } jackdev->outbuf[i] = jackdev->audiomain->io_o[i] = jack_port_get_buffer(jackdev->jack_out[i], nframes); memset(jackdev->outbuf[i], 0.0f, nframes * sizeof(float)); } } toutbuf = inbuf; gain = 12.0f; for (i = 0; i < nframes; i+=8) { *toutbuf++ = jackdev->inbuf[BRISTOL_JACK_STDINL][i] * gain; *toutbuf++ = jackdev->inbuf[BRISTOL_JACK_STDINL][i] * gain; *toutbuf++ = jackdev->inbuf[BRISTOL_JACK_STDINL][i] * gain; *toutbuf++ = jackdev->inbuf[BRISTOL_JACK_STDINL][i] * gain; *toutbuf++ = jackdev->inbuf[BRISTOL_JACK_STDINL][i] * gain; *toutbuf++ = jackdev->inbuf[BRISTOL_JACK_STDINL][i] * gain; *toutbuf++ = jackdev->inbuf[BRISTOL_JACK_STDINL][i] * gain; *toutbuf++ = jackdev->inbuf[BRISTOL_JACK_STDINL][i] * gain; } /* * For now we are not going to be too picky about inbuf. * * The buffers are however mono, which is a bit of a bummer as now I have * to do the interleaving and deinterleaving. This could be changed but * it would have to apply to the native audio drivers as well. * * This doAudioOps is the same one used for the last few years by bristol * as its own dispatch routine. However, there are additional features * possible with Jack such that each synth could requisition its own * ports dynamically, one or two depending on the synth stereo status. * * That should be an option, probably, but either way, if it were done * then we would need to rework this dispatcher. That is not a bad thing * since we could have the audioEngine write directly to the jack buffer * rather than use the stereo interleaved outbuf. * * The reworked dispatcher should be placed in here, it is currently in * audioEngine.c */ doAudioOps(jackdev->audiomain, outbuf, inbuf); /* * The bristol audio does this with zero suppression. Hm. Saved data is * the output from the algo, it does not have outgain applied. */ if (dupfd > 0) nint = write(dupfd, outbuf, jackdev->audiomain->segmentsize * 2); /* * We have an issue with sample formats. These are normalised to 0/1 * whilst we have been working on full range values. No problem. */ if ((gain = jackdev->audiomain->outgain) < 1) gain = 1.0f; gain /= 32768.0; outL = (float *) jack_port_get_buffer(jackdev->jack_out[BRISTOL_JACK_STDOUTL], nframes); outR = (float *) jack_port_get_buffer(jackdev->jack_out[BRISTOL_JACK_STDOUTR], nframes); /* * Deinterleave our output through to the jack buffers. */ toutbuf = outbuf; for (i = nframes; i > 0; i--) { *outL++ = *toutbuf++ * gain; *outR++ = *toutbuf++ * gain; } if (jackdev->iocount > 0) { register int j; register float *buf, gain; if ((gain = jackdev->audiomain->m_io_ogc) <= 0) gain = 1.0; for (i = 0; i < jackdev->iocount; i++) { buf = jackdev->outbuf[i]; for (j = 0; j < nframes; j+=8) { *buf++ *= gain; *buf++ *= gain; *buf++ *= gain; *buf++ *= gain; *buf++ *= gain; *buf++ *= gain; *buf++ *= gain; *buf++ *= gain; } memset(jackdev->inbuf[i], 0.0f, nframes * sizeof(float)); } } if (jackdev->audiomain->debuglevel > 9) { bufstats(jackdev->outbuf[0], nframes, 1); bufstats(jackdev->outbuf[2], nframes, 2); } return(0); } static void bristolIntJackClose() { int i; --closedown; printf("closedown on interrupt\n"); jack_deactivate(jackdev.handle); jack_port_unregister(jackdev.handle, jackdev.jack_out[BRISTOL_JACK_STDOUTL]); jack_port_unregister(jackdev.handle, jackdev.jack_out[BRISTOL_JACK_STDOUTR]); jack_port_unregister(jackdev.handle, jackdev.jack_in[BRISTOL_JACK_STDINL]); jack_port_unregister(jackdev.handle, jackdev.jack_in[BRISTOL_JACK_STDINR]); for (i = 0; i < jackdev.iocount; i++) { jack_port_unregister(jackdev.handle, jackdev.jack_in[i]); jack_port_unregister(jackdev.handle, jackdev.jack_out[i]); } jack_client_close(jackdev.handle); _exit(0); } static int bristolJackClose(jackDev *jackdev) { int i; if ((jackdev->handle == NULL) || (jackdev->jack_out[BRISTOL_JACK_STDOUTL] == NULL)) return(-1); /* * So, if we don't have the ALSA atomic headers then just run it on ints, * this bit of code is far from critical but collisions cause some gory * shutdown sequences. The code used to call this shutdown from two * different threads, removed on of them instead to prevent the possibility * of them battering each other. */ #ifdef DONT_USE_THIS //IATOMIC_DEFINED // Not very portable if (atomic_dec_and_test(&closedown)) #else if (--closedown == 0) #endif printf("unregistering jack interface: %p->%p\n", jackdev, jackdev->handle); else { printf("interface unregistered\n"); return(0); } jack_deactivate(jackdev->handle); usleep(100000); jack_port_unregister(jackdev->handle, jackdev->jack_out[BRISTOL_JACK_STDOUTL]); jack_port_unregister(jackdev->handle, jackdev->jack_out[BRISTOL_JACK_STDOUTR]); jack_port_unregister(jackdev->handle, jackdev->jack_in[BRISTOL_JACK_STDINL]); jack_port_unregister(jackdev->handle, jackdev->jack_in[BRISTOL_JACK_STDINR]); for (i = 0; i < jackdev->iocount; i++) { jack_port_unregister(jackdev->handle, jackdev->jack_in[i]); jack_port_unregister(jackdev->handle, jackdev->jack_out[i]); } jackdev->jack_out[BRISTOL_JACK_STDOUTL] = NULL; jack_client_close(jackdev->handle); /* * The API does not seem to be clear on who owns this however since we * are exiting..... jackdev->handle = NULL; */ jackdev->audiomain->atReq |= BRISTOL_REQSTOP; jackdev->audiomain->mtReq |= BRISTOL_REQSTOP; return(0); } /* * This builds us our port list for connections. Per default we will connect * to the first capture port and the first two playback ports, but that * should also be optional. We should have some fixed starting ports though, * even if we are going to pass parameters, since when each synth starts * registering its own set of ports then they have to be linked somewhere * by default. */ static void jackPortStats(jackDev *jackdev, int dir) { int i; bristolfree(jackdev->ports); if ((jackdev->ports = jack_get_ports(jackdev->handle, NULL, NULL, JackPortIsPhysical|dir)) == NULL) { printf("Empty jack_get_ports()\n"); return; } for (i = 0; jackdev->ports[i] != NULL; i++) printf("Found port %s\n", jackdev->ports[i]); } static int bristolJackOpen(jackDev *jackdev, audioMain *audiomain, JackProcessCallback shim) { int waitc = 10, sr; if (audiomain->audiodev != NULL) regname = audiomain->audiodev; #ifdef _BRISTOL_JACK_SESSION if (audiomain->jackUUID[0] == '\0') { printf("registering jack interface: %s\n", regname); jackdev->handle = jack_client_open(regname, JackNullOption, NULL); } else { printf("reregistering jack interface: %s, UUDI %s\n", regname, &audiomain->jackUUID[0]); jackdev->handle = jack_client_open(regname, JackSessionID, NULL, &audiomain->jackUUID[0]); } #else printf("registering jack interface: %s\n", regname); jackdev->handle = jack_client_open(regname, JackNullOption, NULL); #endif if (jackdev->handle == 0) { char process_indexed[32]; /* * This had to be changed as the process ID is variable between * invocations. The port number is not, it has to be provided to build * a connection and is unique. */ snprintf(process_indexed, 32, "%s_%i", regname, audiomain->port); #ifdef _BRISTOL_JACK_SESSION if (audiomain->jackUUID[0] == '\0') jackdev->handle = jack_client_open(regname, JackNullOption, NULL); else jackdev->handle = jack_client_open(regname, JackSessionID, NULL, &audiomain->jackUUID[0]); #else jackdev->handle = jack_client_open(regname, JackNullOption, NULL); #endif if (jackdev->handle == 0) { printf("Cannot connect to jack\n"); audiomain->atStatus = BRISTOL_REQSTOP; return(-1); } } #ifdef _BRISTOL_JACK_MIDI if (~audiomain->flags & BRISTOL_JACK_DUAL) bristolJackSetMidiHandle(jackdev->handle); #endif signal(SIGINT, bristolIntJackClose); signal(SIGTERM, bristolIntJackClose); signal(SIGHUP, bristolIntJackClose); signal(SIGQUIT, bristolIntJackClose); /* * This is (was) perhaps not wise.... * Thanks to Hagen. signal(SIGSEGV, bristolIntJackClose); */ /* Samplerate mismatches should be reported however they are not critical */ if (audiomain->samplerate != (sr = jack_get_sample_rate(jackdev->handle))) printf("\nJack SAMPLERATE MISMATCH: startBristol -jack -rate %i\n", sr); /* * This value can change, and we should register a callback for such an * event. The values are used internally and are already configured for * some parts of the system, hence, for now, if this does not match we * are going to exit as this is critical. */ if (audiomain->samplecount != (sr = jack_get_buffer_size(jackdev->handle))) { printf("\nJack PERIOD COUNT MISMATCH: `startBristol -jack -count %i`\n", sr); printf("\nYou need to ensure that bristol uses the same period size\n"); /* * This did call bristolJackClose(jackdev), however as we have not * yet done much of the registration then the following is correct: */ jack_client_close(jackdev->handle); audiomain->atStatus = BRISTOL_REQSTOP; return(-1); } audiomain->samplecount = sr; audiomain->segmentsize = audiomain->samplecount * sizeof(float); /* * We double this value since I am going to be using interleaved samples * for some buffering. I should change this, just let the audio library * do interleave if it is writing to physical devices. */ outbuf = (float *) bristolmalloc(audiomain->samplecount * fsize * 2); inbuf = (float *) bristolmalloc(audiomain->samplecount * fsize * 2); audiomain->atStatus = BRISTOL_OK; audiomain->flags |= BRISTOL_AUDIOWAIT; initAudioThread(audiomain); jackdev->audiomain = audiomain; jack_set_process_callback(jackdev->handle, shim, (void *) jackdev); jack_on_shutdown(jackdev->handle, jack_shutdown, (void *) jackdev); #ifdef _BRISTOL_JACK_SESSION if (jack_set_session_callback) jack_set_session_callback(jackdev->handle, jack_session_callback, (void *) jackdev); #endif if ((jackdev->jack_out[BRISTOL_JACK_STDOUTL] = jack_port_register(jackdev->handle, "out_left", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)) == NULL) { printf("Cannot register jack port\n"); audiomain->atStatus = BRISTOL_REQSTOP; return(-1); } if ((jackdev->jack_out[BRISTOL_JACK_STDOUTR] = jack_port_register(jackdev->handle, "out_right", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)) == NULL) { printf("Cannot register jack port\n"); audiomain->atStatus = BRISTOL_REQSTOP; return(-1); } /* * We only use the input for a couple of the synths (Mini/Explorer) and * even that had limited use. It was also employed historically for sync * - read/modify/write sequences. We could drop this registration, but it * can stay in for now, it will be used in the future. */ if ((jackdev->jack_in[BRISTOL_JACK_STDINL] = jack_port_register(jackdev->handle, "in_left", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0)) == NULL) { printf("Cannot register jack port\n"); audiomain->atStatus = BRISTOL_REQSTOP; return(-1); } if ((jackdev->jack_in[BRISTOL_JACK_STDINR] = jack_port_register(jackdev->handle, "in_right", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0)) == NULL) { printf("Cannot register jack port\n"); audiomain->atStatus = BRISTOL_REQSTOP; return(-1); } /* * Our engine is going have to wait for the GUI to inform us what synth * we are going to be running. It is wiser not to request callbacks until * at least the first synth is active. If the priorities are correct this * should not be an issue, but 'dropping' a synth costs a few cycles in * the midi thread. */ while (audiomain->flags & BRISTOL_AUDIOWAIT) { sleep(1); if (--waitc <= 0) { printf("Did not receive request from GUI, exiting.\n"); /* * We should really unregister here..... */ return(-1); } } if (jack_activate(jackdev->handle) != 0) { printf("Cannot activate jack\n"); audiomain->atStatus = BRISTOL_REQSTOP; return(-1); } jackPortStats(jackdev, JackPortIsInput); if ((audiomain->flags & BRISTOL_AUTO_CONN) && (jackdev->ports != NULL)) { int jport = 0; char *lport, *rport; lport = getenv("BRISTOL_AUTO_LEFT"); rport = getenv("BRISTOL_AUTO_RIGHT"); if ((lport != NULL) && (rport != NULL)) { /* * We should scan through the list looking for our ports */ for (jport = 0; jackdev->ports[jport] != NULL; jport++) { if (strcmp(lport, jackdev->ports[jport]) == 0) { if (jack_connect(jackdev->handle, jack_port_name(jackdev->jack_out[BRISTOL_JACK_STDOUTL]), jackdev->ports[jport]) != 0) { printf("Bristol Failed Conn: %s to %s failed\n", jack_port_name(jackdev->jack_out[BRISTOL_JACK_STDOUTL]), jackdev->ports[jport]); } else printf("Bristol Env AutoConn: %s to %s\n", jack_port_name(jackdev->jack_out[BRISTOL_JACK_STDOUTL]), jackdev->ports[jport]); } if (strcmp(rport, jackdev->ports[jport]) == 0) { if (jack_connect(jackdev->handle, jack_port_name(jackdev->jack_out[BRISTOL_JACK_STDOUTR]), jackdev->ports[jport]) != 0) { printf("Bristol Failed Conn: %s to %s failed\n", jack_port_name(jackdev->jack_out[BRISTOL_JACK_STDOUTR]), jackdev->ports[jport]); } else printf("Bristol Env AutoConn: %s to %s\n", jack_port_name(jackdev->jack_out[BRISTOL_JACK_STDOUTL]), jackdev->ports[jport]); } } } else for (jport = 0; jackdev->ports[jport] != NULL; jport++) { /* * I don't like this code but I cannot find a way to ask jack if * this port is audio or midi. Without this scan then it is possible * that the engine will default a connection from audio to midi. * * It is okay here to attempt the connection but continue through * the list in the event of failure but that is sloppy. All we * actually want is to find the first two available ports to return * audio to and one to receive from the daemon. */ if (strstr(jackdev->ports[jport], "midi") != 0) { printf("Skipping Jack Conn: %s\n", jackdev->ports[jport]); continue; } if (jack_connect(jackdev->handle, jack_port_name(jackdev->jack_out[BRISTOL_JACK_STDOUTL]), jackdev->ports[jport]) != 0) { printf("Bristol Defaulted Conn: %s to %s failed\n", jack_port_name(jackdev->jack_out[BRISTOL_JACK_STDOUTL]), jackdev->ports[jport]); continue; } else printf("Bristol Defaulted Conn: %s to %s\n", jack_port_name(jackdev->jack_out[BRISTOL_JACK_STDOUTL]), jackdev->ports[jport]); for (jport++; jackdev->ports[jport] != 0; jport++) { if (strstr(jackdev->ports[jport], "midi") != 0) { printf("Skipping Jack Conn: %s\n", jackdev->ports[jport]); continue; } if (jack_connect(jackdev->handle, jack_port_name(jackdev->jack_out[BRISTOL_JACK_STDOUTR]), jackdev->ports[jport]) != 0) { printf("Bristol Defaulted Conn: %s to %s failed\n", jack_port_name(jackdev->jack_out[BRISTOL_JACK_STDOUTR]), jackdev->ports[jport]); continue; } else printf("Bristol Defaulted Conn: %s to %s\n", jack_port_name(jackdev->jack_out[BRISTOL_JACK_STDOUTR]), jackdev->ports[jport]); break; } break; } } /* * We now need to connect the ports together. For now this will be fixed * but actually needs to be a set of options. */ jackPortStats(jackdev, JackPortIsOutput); if ((audiomain->flags & BRISTOL_AUTO_CONN) && (jackdev->ports != NULL)) { int jport = 0; char *iport; iport = getenv("BRISTOL_AUTO_IN"); if (iport != NULL) { /* * We should scan through the list looking for our ports */ for (jport = 0; jackdev->ports[jport] != NULL; jport++) { if (strcmp(iport, jackdev->ports[jport]) == 0) { if (jack_connect(jackdev->handle, jackdev->ports[jport], jack_port_name(jackdev->jack_in[BRISTOL_JACK_STDINL])) != 0) { /* * We don't actually need to fail any of these, it just * means we have no defaults. */ printf("Bristol Env AutoConn: %s to %s failed\n", jackdev->ports[jport], jack_port_name(jackdev->jack_in[BRISTOL_JACK_STDINL])); continue; } else printf("Bristol Env AutoConn: %s to %s\n", jackdev->ports[jport], jack_port_name(jackdev->jack_in[BRISTOL_JACK_STDINL])); } } } else for (jport = 0; jackdev->ports[jport] != 0; jport++) { if (strstr(jackdev->ports[jport], "midi") != 0) { printf("Skipping Jack Conn: %s\n", jackdev->ports[jport]); continue; } if (jack_connect(jackdev->handle, jackdev->ports[jport], jack_port_name(jackdev->jack_in[BRISTOL_JACK_STDINL])) != 0) { /* * We don't actually need to fail any of these, it just means * we have no defaults. */ printf("Bristol Defaulted Conn: %s to %s failed\n", jackdev->ports[jport], jack_port_name(jackdev->jack_in[BRISTOL_JACK_STDINL])); continue; } else printf("Bristol Defaulted Conn: %s to %s\n", jackdev->ports[jport], jack_port_name(jackdev->jack_in[BRISTOL_JACK_STDINL])); break; } } /* * So now see if we were requested to register more ports. */ if ((jackdev->iocount = audiomain->iocount) > 0) { int i; char pn[256]; for (i = 0; i < jackdev->iocount; i++) { sprintf(pn, "out_%i", i + 1); if ((jackdev->jack_out[i] = jack_port_register(jackdev->handle, pn, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)) == NULL) { printf("Cannot register jack port\n"); audiomain->atStatus = BRISTOL_REQSTOP; return(-1); } sprintf(pn, "in_%i", i + 1); if ((jackdev->jack_in[i] = jack_port_register(jackdev->handle, pn, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0)) == NULL) { printf("Cannot register jack port\n"); audiomain->atStatus = BRISTOL_REQSTOP; return(-1); } } } return(0); } /* * Test dynamic disconnect and reconnects. Eventually each synth will * potentially register its own set of ports. Want to do this with a * reasonably large number of iterations. Correctly speaking we should * probably take a copy of the jack_in port, null the jackdev entry * and then unregister it. static void jackPortBounce(jackDev *jackdev) { jack_disconnect(jackdev->handle, jackdev->ports[0], jack_port_name(jackdev->jack_in[BRISTOL_JACK_STDINL])); if (jack_port_unregister(jackdev->handle, jackdev->jack_in[BRISTOL_JACK_STDINL]) == 0) { printf("Unregistered port\n"); jackdev->jack_in[BRISTOL_JACK_STDINL] = 0; sleep(5); if ((jackdev->jack_in[BRISTOL_JACK_STDINL] = jack_port_register(jackdev->handle, "in", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0)) != NULL) printf("Registered port\n"); } else sleep(5); jack_connect(jackdev->handle, jackdev->ports[0], jack_port_name(jackdev->jack_in[BRISTOL_JACK_STDINL])); } jack_client_t * bristolJackGetAudioHandle() { if (jackdev.audiomain == NULL) sleep(1); if (jackdev.audiomain->flags & BRISTOL_JACK_DUAL) return(NULL); sleep(1); return(jackdev.handle); } */ int bristolJackInterface(audioMain *audiomain) { /* * This was added into 0.40.3 to prevent subgraph timeouts on exit. The * call is made from the midi thread once the audio thread has done the * necessary cleanup work. */ if ((audiomain == NULL) || (audiomain->audiolist == 0)) /* * If the audiolist is empty (or we are called with a null pointer) * then assume we are being requested to close down the interface. */ return(bristolJackClose(&jackdev)); if (bristolJackOpen(&jackdev, audiomain, audioShim) != 0) return(-1); while (audiomain->atReq != BRISTOL_REQSTOP) sleep(1); return(0); } #endif /* _BRISTOL_JACK */ bristol-0.60.11/libbristolaudio/audioGUIOSS.c0000644000175000017500000001441311746476475015674 00000000000000 /* * Diverse SLab audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* * These are largely device specific operations for the audio devices. Some of * the calls are general, but may eventually be used by several of the SLab * applications. * * The operations for audio control are rather ugly. The application sets up * a number of values in the controlBuffer, and the engine intermittanly looks * to see if these values are initialised. If so, it acts on the values, and * then clears them. The reason we have to use this indirection is that the * front end applications do not own the audio device, this is under control * of the engine. * * Jul 28th 96 - Only LINUX code is active. */ /* * Audio device structure format definitions. */ #include "slabrevisions.h" #include "slabaudiodev.h" #include #include #ifdef DEBUG #include #endif #include #include #include #include static int setAudioOSS(int, duplexDev *, int, int, int); #if (BRISTOL_HAS_OSS == 1) /* * This may want to be /usr/lib/oss/include/sys/soundcard.h if someone has * purchased the 4Front drivers? */ #include audio_buf_info bufferInfo; mixer_info mInfo; static char *SLAB_SND_LABELS[SLAB_NRDEVICES] = SOUND_DEVICE_LABELS; #endif /* * Setup audio parameters with device support. */ void setAudioOSSparam(audioDev, devID, param, left, right) duplexDev *audioDev; int param, devID; short left, right; { if (audioDev->mixerFD > 0) setAudioOSS(audioDev->mixerFD, audioDev, param, left, right); } /* * Binned since alsa support was implemented. * * This is a device specific routine. We take the fd, parameter, and left * right values, and configure the device. These routines should be used by the * engine to do the actual audio horsework. * * This is actually an internal routine, it should not be called from outside * of this file. */ static int setAudioOSS(fd, audioDev, param, valueL, valueR) duplexDev *audioDev; { #if (BRISTOL_HAS_OSS == 1) int value, command; switch(param) { case SLAB_REC_SRC: case SLAB_MM_CD: case SLAB_MM_MIC: case SLAB_MM_LINE: case SLAB_MM_LINE1: case SLAB_MM_LINE2: case SLAB_MM_LINE3: case SLAB_MM_SYNTH: case SLAB_MM_PCM: case SLAB_TREBLE: case SLAB_BASS: case SLAB_MID: case SLAB_INPUT_GAIN: case SLAB_VOL_CD: case SLAB_VOL_MIC: case SLAB_VOL_LINE: case SLAB_VOL_LINE1: case SLAB_VOL_LINE2: case SLAB_VOL_LINE3: case SLAB_VOL_SYNTH: case SLAB_VOL_PCM: default: /* * These are all the rest, which should be from the microMixer, * scaled to 100 already. */ command = param & SLAB_MM_MASK; value = (valueR << 8) + valueL; } #endif /* linux */ #ifdef DEBUG printf("Command: %x, value: %x\n", command, value); #endif #if (BRISTOL_HAS_OSS == 1) #ifdef IOCTL_DBG if (audioDev->cflags & SLAB_AUDIODBG) printf("ioctl(%i, MIXER_WRITE(%i), %i)\n", fd, command, value); #endif if (ioctl(fd, MIXER_WRITE(command), &value) == -1) { /* printf("Error setting audio parameter %s\n", SLAB_SND_LABELS[command]); */ return(0); } #endif return(0); } void checkAudioOSScaps(audioDev, devID, fd) duplexDev *audioDev; int devID, fd; { #if (BRISTOL_HAS_OSS == 1) int stereodevs = 0; #ifdef DEBUG printf("checkAudioCaps2(%i, %i)\n", devID, fd); #endif if (ioctl(fd, SOUND_MIXER_READ_STEREODEVS, &stereodevs) == -1) { #ifdef IOCTL_DBG if (audioDev->cflags & SLAB_AUDIODBG) #endif printf("Failed to get stereo capabilities: %08x\n", stereodevs); } else { #ifdef IOCTL_DBG if (audioDev->cflags & SLAB_AUDIODBG) printf("Capabilities: %08x\n", stereodevs); #endif audioDev->stereoCaps = stereodevs; } #ifdef DEBUG for (i = 1; i < 131072; i = i << 1) { if (i & stereodevs) printf("Found stereo dev %08x\n", i); } #endif stereodevs = 0; if (ioctl(fd, SOUND_MIXER_READ_DEVMASK, &stereodevs) == -1) { #ifdef IOCTL_DBG if (audioDev->cflags & SLAB_AUDIODBG) #endif printf("Failed to get audio capabilities: %08x\n", stereodevs); } else { #ifdef IOCTL_DBG if (audioDev->cflags & SLAB_AUDIODBG) printf("Mono Capabilities: %08x\n", stereodevs); #endif audioDev->monoCaps = stereodevs; } stereodevs = 0; if (ioctl(fd, SOUND_MIXER_READ_RECMASK, &stereodevs) == -1) { #ifdef IOCTL_DBG if (audioDev->cflags & SLAB_AUDIODBG) #endif printf("Failed to get record capabilities: %08x\n", stereodevs); } else { #ifdef IOCTL_DBG if (audioDev->cflags & SLAB_AUDIODBG) printf("Record Caps: %08x\n", stereodevs); #endif audioDev->recordCaps = stereodevs; } #ifdef DEBUG for (i = 1; i < 131072; i = i << 1) { if (i & stereodevs) printf("Found mono dev %08x\n", i); } #endif /* DEBUG */ #endif /* linux */ } char * getOSSName(controller) int controller; { char *name = NULL; #if (BRISTOL_HAS_OSS == 1) if ((controller < 0) || (controller > SOUND_MIXER_NRDEVICES)) return("none"); name = SLAB_SND_LABELS[controller]; #endif return(name); } int getOSSCapByName(audioDev, name) duplexDev *audioDev; char *name; { #if (BRISTOL_HAS_OSS == 1) int i; for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) { if (strcmp(SLAB_SND_LABELS[i], name) == 0) return i; } #endif return(-1); } int getOSSCapability(audioDev, controller) duplexDev *audioDev; { if ((audioDev->stereoCaps | audioDev->monoCaps) & (1 << controller)) return controller; return(-1); } int getOSSRecordability(audioDev, cont) duplexDev *audioDev; { if (audioDev->cflags & SLAB_AUDIODBG) printf("getOSSRecordability(%i, %i)\n", audioDev->devID, cont); if (audioDev->recordCaps & (1< 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* * These are largely device specific operations for the audio devices. Some of * the calls are general, but may eventually be used by several of the SLab * applications. * * The operations for audio control are rather ugly. The application sets up * a number of values in the controlBuffer, and the engine intermittanly looks * to see if these values are initialised. If so, it acts on the values, and * then clears them. The reason we have to use this indirection is that the * front end applications do not own the audio device, this is under control * of the engine. * * Jul 28th 96 - Only LINUX code is active. */ /* * Audio device structure format definitions. */ #include "slabrevisions.h" #include "slabaudiodev.h" #include #include #include #include static char *SLAB_CONVERT_LABELS[32] = \ {"Master", "Bass", "Treble", "FM", "PCM", "PC Speaker", "Line", "MIC", \ "CD", "Mix ", "Pcm2 ", "Rec ", "Input Gain", "OGain", "none", "none", \ "none", "none", "none", "none", "none", "none", (char *) NULL}; extern int setAudioOSSparam(duplexDev *, int, int, int, int); extern int checkAudioOSScaps(duplexDev *, int, int); extern char * getOSSName(int); extern int getOSSRecordability(); extern int getOSSCapByName(); extern int getOSSCapability(); #if (BRISTOL_HAS_ALSA == 1) extern int setAudioALSAparam(duplexDev *, int, char *, int, int); extern int checkAudioALSAcaps(duplexDev *, int); extern void closeALSAmixer(duplexDev *); extern int openALSAmixer(duplexDev *); extern char * getAlsaName(duplexDev *, int); extern int validAlsaDev(duplexDev *, int); extern int setAlsaRecordSource(); extern int getAlsaRecordability(); extern int getAlsaMutability(); extern int getAlsaStereoStatus(); extern int getAlsaValue(); extern int setAlsaValue(); extern int setAlsaMute(); extern int getAlsaDeviceName(); extern int getAlsaCapByName(); extern int getAlsaCapability(); #endif /* * Setup audio parameters with device support. */ void SL_setAudioDevParam2(audioDev, devID, param, left, right) duplexDev *audioDev; int param, devID; short left, right; { if ((devID < 0) || (devID >= MAX_DEVICES)) return; if (audioDev->cflags & SLAB_NO_CONTROLS) return; #if (BRISTOL_HAS_ALSA == 1) if ((audioDev->flags & AUDIO_ALSA) != 0) { /* * These were OSS calls. We only want to interpret a few of them. if (param > 18) return; */ /* * We cannot force this on ALSA, since there are likely issues the * controller types - use an interpreted name. */ setAudioALSAparam(audioDev, devID, SLAB_CONVERT_LABELS[param], left, right); return; } #endif setAudioOSSparam(audioDev, devID, param, left, right); } void mixerClose(audioDev) duplexDev *audioDev; { #if (BRISTOL_HAS_ALSA == 1) if (audioDev->cflags & SLAB_AUDIODBG) printf("mixerClose()\n"); if ((audioDev->flags & AUDIO_ALSA) != 0) { closeALSAmixer(audioDev); } else #endif { if (audioDev->mixerFD > 0) close(audioDev->mixerFD); } audioDev->mixerFD = -1; } int mixerOpen(audioDev) duplexDev *audioDev; { #if (BRISTOL_HAS_ALSA == 1) if (audioDev->cflags & SLAB_AUDIODBG) printf("mixerOpen()\n"); if ((audioDev->flags & AUDIO_ALSA) != 0) { audioDev->monoCaps = 0; audioDev->stereoCaps = 0; audioDev->recordCaps = 0; return(openALSAmixer(audioDev)); } else #endif { if (audioDev->mixerName[0] != '\0') { audioDev->mixerFD = open(audioDev->mixerName, O_RDWR); } } return(audioDev->mixerFD); } char * getControllerName(audioDev, controller) duplexDev *audioDev; { #if (BRISTOL_HAS_ALSA == 1) if ((audioDev->flags & AUDIO_ALSA) != 0) return((char *) getAlsaName(audioDev, controller)); #endif return (char *) getOSSName(controller); } int setRecordSource(audioDev, controller, position) duplexDev *audioDev; { #if (BRISTOL_HAS_ALSA == 1) if ((audioDev->flags & AUDIO_ALSA) != 0) return setAlsaRecordSource(audioDev, controller, position); #endif return -1; } int getRecordability(audioDev, controller) duplexDev *audioDev; { #if (BRISTOL_HAS_ALSA == 1) if ((audioDev->flags & AUDIO_ALSA) != 0) return getAlsaRecordability(audioDev, controller); #endif return getOSSRecordability(audioDev, controller); } int getMutability(audioDev, controller) duplexDev *audioDev; { #if (BRISTOL_HAS_ALSA == 1) if ((audioDev->flags & AUDIO_ALSA) != 0) return getAlsaMutability(audioDev, controller); #endif /* * -3 indicates no ALSA support */ return -3; } int getStereoStatus(audioDev, controller) duplexDev *audioDev; { #if (BRISTOL_HAS_ALSA == 1) if ((audioDev->flags & AUDIO_ALSA) != 0) return getAlsaStereoStatus(audioDev, controller); #endif return -1; } int getValue(audioDev, controller, side) duplexDev *audioDev; { #if (BRISTOL_HAS_ALSA == 1) if ((audioDev->flags & AUDIO_ALSA) != 0) return getAlsaValue(audioDev, controller, side); #endif return -1; } int setAudioValue(audioDev, controller, side, value) duplexDev *audioDev; { if (audioDev->cflags & SLAB_AUDIODBG) printf("setAudioValue(%p, %i, %i, %i)\n", audioDev, controller, side, value); if (audioDev->cflags & SLAB_NO_CONTROLS) { return 0; } #if (BRISTOL_HAS_ALSA == 1) if ((audioDev->flags & AUDIO_ALSA) != 0) return setAlsaValue(audioDev, controller, side, value); #endif return -1; } int setAudioMute(audioDev, controller, value) duplexDev *audioDev; { if (audioDev->cflags & SLAB_AUDIODBG) printf("setAudioMute()\n"); #if (BRISTOL_HAS_ALSA == 1) if ((audioDev->flags & AUDIO_ALSA) != 0) return setAlsaMute(audioDev, controller, value); #endif return -1; } int getAudioCapByName(audioDev, name) duplexDev *audioDev; char *name; { if (audioDev->cflags & SLAB_AUDIODBG) printf("getAudioCapByName(%s, %s)\n", audioDev->devName, name); #if (BRISTOL_HAS_ALSA == 1) if ((audioDev->flags & AUDIO_ALSA) != 0) return getAlsaCapByName(audioDev, name); #endif return getOSSCapByName(audioDev, name); } int getAudioCapability(audioDev, controller) duplexDev *audioDev; { if (audioDev->cflags & SLAB_AUDIODBG) printf("getAudioCapability(%s, %i)\n", audioDev->devName, controller); #if (BRISTOL_HAS_ALSA == 1) if ((audioDev->flags & AUDIO_ALSA) != 0) { return getAlsaCapability(audioDev, controller); } #endif return getOSSCapability(audioDev, controller); } int validDev(audioDev, index) duplexDev *audioDev; { #if (BRISTOL_HAS_ALSA == 1) if ((audioDev->flags & AUDIO_ALSA) != 0) return validAlsaDev(audioDev, index); #endif return(0); } bristol-0.60.11/libbristolaudio/audioEngine.c0000644000175000017500000002142611746476475016072 00000000000000 /* * Diverse SLab audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* * These are largely device specific operations for the audio devices. Some of * the calls are general, but may eventually be used by several of the SLab * applications. * * The operations for audio control are rather ugly. The application sets up * a number of values in the controlBuffer, and the engine intermittanly looks * to see if these values are initialised. If so, it acts on the values, and * then clears them. The reason we have to use this indirection is that the * front end applications do not own the audio device, this is under control * of the engine. * * Jul 28th 96 - Only LINUX code is active. */ /* * Audio device structure format definitions. */ #include "slabrevisions.h" #include "slabaudiodev.h" #include "slabcdefs.h" #include "bristol.h" #if (BRISTOL_HAS_ALSA == 1) #include "slabalsadev.h" #endif extern int ossAudioInit(duplexDev *, int, int); extern int alsaDevOpen(duplexDev *, int, int, int); extern int alsaDevClose(duplexDev *); extern int alsaDevAudioStart(duplexDev *); #ifdef DEBUG #include #endif #include #include #ifdef SUBFRAGMENT #include #include #endif #include #if (BRISTOL_HAS_OSS == 1) /* * This may want to be /usr/lib/oss/include/sys/soundcard.h if someone has * purchased the 4Front drivers? */ #include audio_buf_info bufferInfo; #endif /* static char *SLAB_SND_LABELS[SLAB_NRDEVICES] = SLAB_DEVICE_LABELS; * Called once when the device is opened by the engine. Initialises our fd to * 44100 16 bits stereo operation. * Changed for 2.30 (or so) to include capability to have no requests to alter * the default fragment size. The code will do a simplified audio init, and let\ * the audio IO daemon use the default fragment for IO, decoupled from the block * sample size. */ int initAudioDevice2(audioDev, devID, fragSize) duplexDev *audioDev; int devID; { /* * The device is basically just opened for the first call of this routine. * This is then called several times afterwards - each time we start the * engine (that is a tape start, not an engine restart). This may be * problematic. * * First set duplex (later check duplex). * Set the fragments. * In this order set bits, channels, speed. */ #ifdef BRISTOL_PA if (audioDev->siflags & AUDIO_PULSE) return(0); #endif #if (BRISTOL_HAS_ALSA == 1) /* * ALSA is one of the secondary intrusive flags. If this is set we have * already configured what we want from the open request on the device. */ if (audioDev->siflags & AUDIO_ALSA) return(0); #endif /* * If we get here we need to call some OSS routine. */ return(ossAudioInit(audioDev, devID, fragSize)); } int setAudioStart2(audioDev, devID) duplexDev *audioDev; { int enable; #ifdef IOCTL_DBG if (audioDev->cflags & SLAB_AUDIODBG) printf("setAudioStart2(%i)\n", devID); #endif if (audioDev->flags & AUDIO_DUMMY) return(0); #ifdef BRISTOL_PA if (audioDev->siflags & AUDIO_PULSE) return(0); #endif #if (BRISTOL_HAS_ALSA == 1) if (audioDev->siflags & AUDIO_ALSA) { alsaDevAudioStart(audioDev); return(0); } #endif if (audioDev->fd < 0) return(0); #if (BRISTOL_HAS_OSS == 1) if ((audioDev->genCaps & SNDCTL_DSP_SETTRIGGER) && (audioDev->Command == 1)) { enable = (PCM_ENABLE_OUTPUT | PCM_ENABLE_INPUT); #ifdef IOCTL_DBG if (audioDev->cflags & SLAB_AUDIODBG) printf("ioctl(%i, SNDCTL_DSP_SETTRIGGER, &%08x)\n", audioDev->fd, enable); #endif ioctl(audioDev->fd, SNDCTL_DSP_SETTRIGGER, &enable); } #endif return(0); } int setAudioStop2(audioDev, devID) duplexDev *audioDev; { int enable; #ifdef IOCTL_DBG if (audioDev->cflags & SLAB_AUDIODBG) printf("setAudioStop2(%i)\n", devID); #endif if (audioDev->siflags & AUDIO_DUMMY) return(0); #ifdef BRISTOL_PA if (audioDev->siflags & AUDIO_PULSE) return(0); #endif #if (BRISTOL_HAS_ALSA == 1) if (audioDev->siflags & AUDIO_ALSA) { #ifdef IOCTL_DBG /* * This is a superfluous bit of debug, but it will at least show that * we are recognising the ALSA configuration status. There are no audio * stop commands associated with the SLab ALSA drivers, although we * could use the "pause" calls. */ if (audioDev->cflags & SLAB_AUDIODBG) printf("ALSA device, returning from setAudioStop2\n"); #endif return(0); } #endif if (audioDev->fd < 0) return(0); #if (BRISTOL_HAS_OSS == 1) if ((audioDev->genCaps & SNDCTL_DSP_SETTRIGGER) && (audioDev->Command == 1)) { enable = ~(PCM_ENABLE_OUTPUT | PCM_ENABLE_INPUT); #ifdef IOCTL_DBG if (audioDev->cflags & SLAB_AUDIODBG) printf("ioctl(%i, SNDCTL_DSP_SETTRIGGER, &%08x)\n", audioDev->fd, enable); #endif ioctl(audioDev->fd, SNDCTL_DSP_SETTRIGGER, &enable); #ifdef IOCTL_DBG if (audioDev->cflags & SLAB_AUDIODBG) { ioctl(audioDev->fd, SNDCTL_DSP_GETTRIGGER, &enable); printf("ioctl(%i, SNDCTL_DSP_GETTRIGGER, &%08x)\n", audioDev->fd, enable); } #endif } #endif return(0); } int audioClose(duplexDev *audioDev) { if (audioDev->cflags & SLAB_AUDIODBG) printf("audioClose(%p, %i, %s)\n", audioDev, audioDev->devID, audioDev->devName); if (audioDev->flags & AUDIO_DUMMY) { printf("closing AUDIO_DUMMY interface\n"); return(0); } #ifdef BRISTOL_PA if (audioDev->siflags & AUDIO_PULSE) { pulseDevClose(audioDev); return(0); } #endif #if (BRISTOL_HAS_ALSA == 1) if (audioDev->siflags & AUDIO_ALSA) { alsaDevClose(audioDev); return(0); } #endif if (audioDev->fd != -1) { close(audioDev->fd); audioDev->fd = -1; } if (audioDev->fd2 != -1) { close(audioDev->fd2); audioDev->fd2 = -1; } bristolfree(audioDev->fragBuf); audioDev->fragBuf = NULL; return(0); } int audioOpen(duplexDev *audioDev, int device, int flags) { if (audioDev->cflags & SLAB_AUDIODBG) printf("audioOpen(%p, %i, %i): %s\n", audioDev, device, flags, audioDev->devName); if (audioDev->flags & AUDIO_DUMMY) { printf("using AUDIO_DUMMY interface\n"); if (audioDev->fragBuf) bristolfree(audioDev->fragBuf); if (audioDev->channels == 0) audioDev->channels = 2; if (audioDev->fragSize == 0) audioDev->fragSize = 1024; if (audioDev->writeSampleRate == 0) audioDev->writeSampleRate = 44100; if (audioDev->readSampleRate == 0) audioDev->readSampleRate = 44100; audioDev->fragBuf = (char *) bristolmalloc(audioDev->fragSize); return(10); } #ifdef BRISTOL_PA if (audioDev->siflags & AUDIO_PULSE) return(pulseDevOpen(audioDev, device, flags, audioDev->fragSize)); #endif #if (BRISTOL_HAS_ALSA == 1) if ((audioDev->siflags & AUDIO_ALSA) && (audioDev->devName[0] != '/')) return(alsaDevOpen(audioDev, device, flags, audioDev->fragSize)); #endif /* * We need to "mung" the flags. */ if (flags == SLAB_OWRONLY) flags = O_WRONLY; else if (flags == SLAB_ORDONLY) flags = O_RDONLY; else if (flags == SLAB_ORDWR) flags = O_RDWR; else { printf(" WHAT WERE THOSE FLAGS: %x\n", flags); /* * We may as well take some default value if we are unsure about the * request. */ flags = O_RDWR; } if (audioDev->cflags & SLAB_AUDIODBG) printf("flags are now %i\n", flags); /* * Open the device. */ if ((audioDev->fd = open(audioDev->devName, flags)) < 0) { /* * Device open failed. Print an error message and exit. */ printf("Failed to open audio device \"%s\", flags %i\n", audioDev->devName, flags); return(-10); #ifdef IOCTL_DBG if (audioDev->cflags & SLAB_AUDIODBG) printf("Opened audio device \"%s\"\n", audioDev->devName); #endif } /* * We will eventually allow configurable buffer sizes. At the moment we * will take the default value for the main output device, and * configure that on all the other devices. */ if (audioDev->fragSize == 0) audioDev->fragSize = 1024; audioDev->flags = flags; bristolfree(audioDev->fragBuf); audioDev->fragBuf = (char *) bristolmalloc(audioDev->fragSize); initAudioDevice2(audioDev, device, audioDev->fragSize); /* audioDev->flags |= SLAB_AUDIODBG2; audioDev->cflags |= SLAB_AUDIODBG; */ return(audioDev->fd); } int channelStatus(duplexDev *audioDev) { return(0); } int headStatus(duplexDev *audioDev) { return(0); } bristol-0.60.11/libbristolaudio/audioMastering.c0000644000175000017500000002175311746476475016621 00000000000000 /* * Diverse SLab audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* * This will contain 3 called routines, from the audio daemon, one to open the * mastering file, one to write the header, and one to close the file. * * openMaster() * The calling rouine will pass the file type. Expects an answer of: * -1: failure - forget mastering. * Anything else - do mastering with output to that FD number. * * writeMaster() * Calling routine passes type of file, and a buffer of data. Called party * must format data as necessary. * * closeMaster() * The calling rouine will pass the file type, and the number of bytes written. */ #include #include #include #include #include #ifdef MASTER_WAV /***** I stole this from Topy Shepard *****/ /***** He stole the rest of this file from 'vplay'. *****/ /***** Thanks to: Michael Beck - beck@informatik.hu-berlin.de *****/ /* Definitions for Microsoft WAVE format */ #define BUFFSIZE 0x10000 #define RIFF 0x46464952 #define WAVE 0x45564157 #define FMT 0x20746d66 #define DATA 0x61746164 #define PCM_CODE 1 #define WAVE_MONO 1 #define WAVE_STEREO 2 /* it's in chunks like .voc and AMIGA iff, but my source say there are in only in this combination, so I combined them in one header; it works on all WAVE-file I have */ typedef struct { u_long main_chunk; /* 'RIFF' */ u_long length; /* filelen */ u_long chunk_type; /* 'WAVE' */ u_long sub_chunk; /* 'fmt ' */ u_long sc_len; /* length of sub_chunk, =16 */ u_short format; /* should be 1 for PCM-code */ u_short modus; /* 1 Mono, 2 Stereo */ u_long sample_fq; /* frequence of sample */ u_long byte_p_sec; u_short byte_p_spl; /* samplesize; 1 or 2 bytes */ u_short bit_p_spl; /* 8, 12 or 16 bit */ u_long data_chunk; /* 'data' */ u_long data_length;/* samplecount */ } WaveHeader; WaveHeader header; #endif #ifdef MASTER_MP3ONLINE int pipeFD[2]; int pid = -1; int status; #endif static int d; #ifdef MASTERING #include #include #include #include #include #include static void writeWaveHdr(duplexDev *, int, int); static void cdrFormat(); static void cdrPad(); /* * Note that the count parameter is the current songlength. This is only needed * for MP3ONLINE, since we need to put some value in the waveHeader before we * start piping the output. */ int openMaster(duplexDev *audioDev, int type, char *fileName, int count) { int fd; if (audioDev->cflags & SLAB_AUDIODBG) printf("openMaster(%i, %s, %i)\n", type, fileName, count); #ifdef MASTER_WAV #ifdef MASTER_MP3ONLINE if (pid != -1) { /* kill(pid, SIGINT); */ waitpid(pid, &status, WNOHANG); pid = -1; } /* * BASICALLY THIS DOES NOT WORK, NOT SURE WHY. FOR FUTURE STUDY..... * * Online MP3 will open a pipe to bladeenc and work dynamically. This is * a bit of a CPU hog, so the normal MP3 encoding will use output to a WAV * file, and then bladeenc is called separately by the GUI once the output * file is closed. */ if (type & MASTER_MP3ONLINE) { /* * A bit ugly, but we are going to open a pipe, and fork/exec bladeenc. * This is going into a separate library when it finally works. * * The library may use socketpair(2) instead. */ if (socketpair(PF_UNIX, SOCK_STREAM, PF_UNSPEC, pipeFD) < 0) { printf("mp3 online: socketpair() error\n"); return(-1); } else { if ((pid = vfork()) == 0) { close(pipeFD[1]); dup2(pipeFD[0], 0); execlp("bladeenc", "bladeenc", /* "-quiet", */ "stdin", fileName, (char *) NULL); printf("Could not find bladeenc\n"); _exit(0); } else { close(pipeFD[0]); fd = pipeFD[1]; } } } else #endif #endif fd = open(fileName, O_CREAT|O_WRONLY|O_TRUNC, 0644); switch(type & MASTERING_MASK) { #ifdef MASTER_WAV #ifdef MASTER_MP3ONLINE case MASTER_MP3ONLINE: writeWaveHdr(audioDev, fd, count); break; #endif #ifdef MASTER_MP3 case MASTER_MP3: #endif case MASTER_WAV: /* * We write a zero length now, and when we close the file we put * the actual length in there. */ writeWaveHdr(audioDev, fd, 0); break; #endif #ifdef MASTER_CDR case MASTER_CDR: #endif default: /* * No header. */ break; } return(fd); } int writeMaster(duplexDev *audioDev, int type, int fd, void *buffer, int size) { int d; if (audioDev->cflags & SLAB_AUDIODBG) printf("writeMaster(%i, %i, %p, %i)\n", type, fd, buffer, size); switch(type & MASTERING_MASK) { #ifdef MASTER_CDR case MASTER_CDR: /* * We need to byteswap first. Oops, this should cater for differnt * output data types. */ cdrFormat(buffer, size >> 2); d = write(fd, buffer, size); break; #endif #ifdef MASTER_WAV #ifdef MASTER_MP3 #ifdef MASTER_MP3ONLINE case MASTER_MP3ONLINE: /* printf("MP3 Online write to fd %i\n", fd); */ #endif case MASTER_MP3: #endif case MASTER_WAV: #endif default: /* * We don't need to byteswap first. */ d = write(fd, buffer, size); break; } return(0); } void closeMaster(duplexDev *audioDev, int fd, int type, int count) { if (audioDev->cflags & SLAB_AUDIODBG) printf("closeMaster(%i, %i, %i)\n", type, fd, count); switch(type & MASTERING_MASK) { #ifdef MASTER_CDR case MASTER_CDR: /* * We need to pad the file to frag boundry. */ cdrPad(fd, count); break; #endif #ifdef MASTER_WAV #ifdef MASTER_MP3ONLINE case MASTER_MP3ONLINE: /* * We cannot kick the child yet, since it may not be finnished. */ break; #endif #ifdef MASTER_MP3 case MASTER_MP3: #endif case MASTER_WAV: /* * We don't need to byteswap first. */ writeWaveHdr(audioDev, fd, count); break; #endif default: /* * We don't need to byteswap first. */ break; } close(fd); } #ifdef MASTERING void static cdrFormat(buffer, count) register int count; register char *buffer; { #if defined(__i386) || defined(__i486) || defined(__i586) || defined(__i686) \ || defined(__pentium) || defined(__pentiumpro) register short tmp; #ifdef DEBUG printf("cdrFormat(%x, %i)\n", buffer, count); #endif /* * This needs to convert the Linux based short into CD-DA format. * Not going to bother with porting issues just yet, but we should add * "ENDIAN" flags for compilation. * * cdrecord expects MSBLeft, LSBLeft, MSBRight, LSBRight. * * Swap each byte pair. */ for (;count > 0; count--) { tmp = *(buffer + 1); *(buffer + 1) = *buffer; *buffer = tmp; buffer += 2; tmp = *(buffer + 1); *(buffer + 1) = *buffer; *buffer = tmp; buffer += 2; } #endif /* cpu type */ } /* * Check the number of samples written to the output file, and pad this out * to match the CD-R sector size. */ static void cdrPad(int fd, int size) { int outCount; short extend[2]; #ifdef DEBUG printf("cdrPad(%i, %i)\n", fd, size); #endif #ifdef CD_R_OUTPUT /* * This is the number of bytes, converted into samples, modulo sectorsize. */ if ((outCount = CD_R_OUTPUT - (size % CD_R_OUTPUT)) == CD_R_OUTPUT) return; #endif extend[0] = 0; #ifdef DEBUG printf("cdrPadding with %i bytes\n", outCount); #endif while (outCount > 0) { d = write(fd, extend, 1); outCount-=1; } } #endif #ifdef MASTERING_WAV /* * This was taken from SLabIO, with many thanks to Toby Shepard. He in turn * took it from Michael Beck - beck@informatik.hu-berlin.de - thanks Michael. * Minor changes for audioDev support. Funny how code goes around..... */ static void writeWaveHdr(duplexDev *audioDev, int fd, int count) { if (audioDev->cflags & SLAB_AUDIODBG) printf("writeWavHdr(%i, %i, %i): %i, %i\n", audioDev->devID, fd, count, audioDev->channels, audioDev->writeSampleRate); if (audioDev->channels == 0) audioDev->channels = 2; lseek(fd, (long) 0, SEEK_SET); header.main_chunk = RIFF; header.length = 36 + count + 8; /* HUH? header is 36 + data + chunk */ header.chunk_type = WAVE; header.sub_chunk = FMT; header.sc_len = 16; header.format = PCM_CODE; header.modus = audioDev->channels; header.sample_fq = audioDev->writeSampleRate; header.byte_p_sec = header.modus * header.sample_fq; header.byte_p_spl = 2; header.bit_p_spl = 16; header.data_chunk = DATA; header.data_length = count / header.modus / header.byte_p_spl; d = write(fd, &header, 44); } #endif #endif /* MASTERING over whole file */ bristol-0.60.11/bin/0000755000175000017500000000000012100257366011110 500000000000000bristol-0.60.11/bin/Makefile.in0000644000175000017500000004632012073601233013075 00000000000000# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = bristoljackstats$(EXEEXT) subdir = bin DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(srcdir)/startBristol.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = startBristol CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) am_bristoljackstats_OBJECTS = bristoljackstats.$(OBJEXT) bristoljackstats_OBJECTS = $(am_bristoljackstats_OBJECTS) bristoljackstats_DEPENDENCIES = bristoljackstats_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(bristoljackstats_LDFLAGS) $(LDFLAGS) -o $@ DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(bristoljackstats_SOURCES) DIST_SOURCES = $(bristoljackstats_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALSA_CFLAGS = @ALSA_CFLAGS@ ALSA_LIBS = @ALSA_LIBS@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BRIGHTON_HAS_AUTOZOOM = @BRIGHTON_HAS_AUTOZOOM@ BRIGHTON_HAS_SHMIMAGE = @BRIGHTON_HAS_SHMIMAGE@ BRIGHTON_HAS_X11 = @BRIGHTON_HAS_X11@ BRIGHTON_HAS_XIMAGE = @BRIGHTON_HAS_XIMAGE@ BRIGHTON_LIBB11 = @BRIGHTON_LIBB11@ BRIGHTON_LIBX11 = @BRIGHTON_LIBX11@ BRIGHTON_LIBXEXT = @BRIGHTON_LIBXEXT@ BRIGHTON_LIBXLIBS = @BRIGHTON_LIBXLIBS@ BRIGHTON_X11_DIR = @BRIGHTON_X11_DIR@ BRISTOL_BARRIER = @BRISTOL_BARRIER@ BRISTOL_DIR = @BRISTOL_DIR@ BRISTOL_HAS_ALSA = @BRISTOL_HAS_ALSA@ BRISTOL_HAS_DRAIN = @BRISTOL_HAS_DRAIN@ BRISTOL_HAS_JACK = @BRISTOL_HAS_JACK@ BRISTOL_HAS_JACK_MIDI = @BRISTOL_HAS_JACK_MIDI@ BRISTOL_HAS_JACK_SESSION = @BRISTOL_HAS_JACK_SESSION@ BRISTOL_HAS_LIBLO = @BRISTOL_HAS_LIBLO@ BRISTOL_HAS_OSS = @BRISTOL_HAS_OSS@ BRISTOL_HAS_PA = @BRISTOL_HAS_PA@ BRISTOL_JACK_DEFAULT = @BRISTOL_JACK_DEFAULT@ BRISTOL_JACK_DEFAULT_MIDI = @BRISTOL_JACK_DEFAULT_MIDI@ BRISTOL_JACK_MULTI_CLOSE = @BRISTOL_JACK_MULTI_CLOSE@ BRISTOL_LIBPALIBS = @BRISTOL_LIBPALIBS@ BRISTOL_LIB_PA = @BRISTOL_LIB_PA@ BRISTOL_LIN_ATTACK = @BRISTOL_LIN_ATTACK@ BRISTOL_MAJOR_VERSION = @BRISTOL_MAJOR_VERSION@ BRISTOL_MICRO_VERSION = @BRISTOL_MICRO_VERSION@ BRISTOL_MINOR_VERSION = @BRISTOL_MINOR_VERSION@ BRISTOL_PA_DIR = @BRISTOL_PA_DIR@ BRISTOL_SEMAPHORE = @BRISTOL_SEMAPHORE@ BRISTOL_SEM_OPEN = @BRISTOL_SEM_OPEN@ BRISTOL_SO_VERSION = @BRISTOL_SO_VERSION@ BRISTOL_VERSION = @BRISTOL_VERSION@ BRR = @BRR@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFAULT_AUDIO_FLAG = @DEFAULT_AUDIO_FLAG@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JACK_CFLAGS = @JACK_CFLAGS@ JACK_LIBS = @JACK_LIBS@ LD = @LD@ LDFLAGS = -Bdynamic -lm -lpthread `pkg-config --silence-errors --libs jack` LIBLO_CFLAGS = @LIBLO_CFLAGS@ LIBLO_LIBS = @LIBLO_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ _BRISTOL_VOICES = @_BRISTOL_VOICES@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = foreign AM_CFLAGS = -pthread -Wall -g -I. -I$(srcdir)/../include/bristol @BRISTOL_HAS_JACK@ @BRISTOL_HAS_JACK_MIDI@ @JACK_CFLAGS@ bristoljackstats_LDFLAGS = -Bdynamic bristoljackstats_LDADD = @JACK_LIBS@ -lm -lpthread #bristolnotegen_LDFLAGS = -Bdynamic #bristolnotegen_LDADD = @JACK_LIBS@ -lm -lpthread -lbristolmidi -L../libbristolmidi #bristolNRPgen_LDFLAGS = -Bdynamic #bristolNRPgen_LDADD = @JACK_LIBS@ -lm -lpthread -lbristolmidi -L../libbristolmidi bristoljackstats_SOURCES = bristoljackstats.c all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign bin/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign bin/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): startBristol: $(top_builddir)/config.status $(srcdir)/startBristol.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p || test -f $$p1; \ then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list bristoljackstats$(EXEEXT): $(bristoljackstats_OBJECTS) $(bristoljackstats_DEPENDENCIES) $(EXTRA_bristoljackstats_DEPENDENCIES) @rm -f bristoljackstats$(EXEEXT) $(bristoljackstats_LINK) $(bristoljackstats_OBJECTS) $(bristoljackstats_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bristoljackstats.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) installdirs: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ clean-generic clean-libtool ctags distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-binPROGRAMS install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am tags uninstall uninstall-am \ uninstall-binPROGRAMS #bristolnotegen_SOURCES = bristolnotegen.c #install: # cp $(srcdir)/startBristol # $(INSTALL) -m 755 $(srcdir)/startBristol $(DESTDIR)$(bindir) # $(INSTALL) -m 755 $(srcdir)/bristoljackstats $(DESTDIR)$(bindir) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: bristol-0.60.11/bin/Makefile.am0000755000175000017500000000161611427006710013067 00000000000000AUTOMAKE_OPTIONS = foreign LDFLAGS = -Bdynamic -lm -lpthread `pkg-config --silence-errors --libs jack` AM_CFLAGS = -pthread -Wall -g -I. -I$(srcdir)/../include/bristol @BRISTOL_HAS_JACK@ @BRISTOL_HAS_JACK_MIDI@ @JACK_CFLAGS@ #bin_PROGRAMS = bristoljackstats bristolnotegen bristolNRPgen bin_PROGRAMS = bristoljackstats bristoljackstats_LDFLAGS = -Bdynamic bristoljackstats_LDADD = @JACK_LIBS@ -lm -lpthread #bristolnotegen_LDFLAGS = -Bdynamic #bristolnotegen_LDADD = @JACK_LIBS@ -lm -lpthread -lbristolmidi -L../libbristolmidi #bristolNRPgen_LDFLAGS = -Bdynamic #bristolNRPgen_LDADD = @JACK_LIBS@ -lm -lpthread -lbristolmidi -L../libbristolmidi bristoljackstats_SOURCES = bristoljackstats.c #bristolnotegen_SOURCES = bristolnotegen.c #install: # cp $(srcdir)/startBristol # $(INSTALL) -m 755 $(srcdir)/startBristol $(DESTDIR)$(bindir) # $(INSTALL) -m 755 $(srcdir)/bristoljackstats $(DESTDIR)$(bindir) bristol-0.60.11/bin/bristoljackstats.c0000644000175000017500000000520711746476475014611 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* * This file was taken out of the engine and moved to the audio library where * it correctly lies however it incorporates a few flags from bristol.h header * file that should really be removed to keep them independent. That is for * later study. */ /*#define DEBUG */ #include #include #include #include #include #include #include #ifdef _BRISTOL_JACK #include jack_client_t *handle; static int samplecount, samplerate; static char *regname = "bgetstats"; static int bristolJackTest() { if ((handle = jack_client_open(regname, 0, NULL)) == 0) return(-1); samplerate = jack_get_sample_rate(handle); samplecount = jack_get_buffer_size(handle); jack_client_close(handle); return(0); } /* * This should go out as the first release with Jack. After that the interface * will change - at the moment Jack subsumes Bristol, and this is the wrong * way around. The audiomain structure is buried inside the jack structure, * but I would prefer the contrary. In addition, with it the contrary then * it would be easier to integrate alternative distribution drivers (DSSI). */ #endif /* _BRISTOL_JACK */ int main(int argc, char *argv[]) { int outfd, nullfd; char lbuf[80]; #ifdef _BRISTOL_JACK /* _BRISTOL_JACK */ // printf("%s: connect to jackd to find samplerate and period size\n", // argv[0]); /* I don't want all the output from jack, redirect it */ outfd = dup(STDOUT_FILENO); nullfd = open("/dev/null", O_WRONLY); dup2(nullfd, STDOUT_FILENO); dup2(nullfd, STDERR_FILENO); if (bristolJackTest() != 0) return(-1); snprintf(lbuf, 80, "JACKSTATS: %i %i\n", samplerate, samplecount); nullfd = write(outfd, lbuf, strlen(lbuf)); return(0); #else printf("This should connect to jack but it does not appear to be compiled\n"); return(-2); #endif /* _BRISTOL_JACK */ } bristol-0.60.11/bin/startBristol.in0000755000175000017500000003333511746476746014112 00000000000000#!/bin/sh # # Diverse Bristol audio routines. # Copyright (c) by Nick Copeland 1996,2011 # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # #set -x args=$* vers=@VERSION@ cli=0 engine=1 gui=1 quiet=0 verbose=0 jack=0 export JACK_START_SERVER=1 midi=seq HELP=0 README=0 EMULATE=hammondB3 FREQ=0 #PORT=5028 # Randomise the port numbers, can be overridden by -port which would be a # requirement for multitimbral PORT=`date +%N` PORT=`expr $PORT % 65536` >/dev/null 2>&1 if [ -z $PORT ]; then PORT=`date +%s` PORT=`expr $PORT % 65536` >/dev/null 2>&1 fi if [ $PORT -lt 1024 ]; then PORT=`expr $PORT + 5028` fi valgrind=0 execme=1 liblist=0 host=net engstatus=0 guistatus=0 JS=1 RATE=44100 DRIVER=@DEFAULT_AUDIO_FLAG@ COUNT=256 LOGO=no # # The following is configured by the autotools process. # BRISTOL_DIR=@BRISTOL_DIR@ # # Whatever directory was called for startBristol we also neede in the PATH # PATH=${PATH}:`dirname $0` showhelp() { if [ $HELP -eq 3 ]; then brighton -V exit 0 fi if [ $HELP -eq 2 ]; then brighton -h | less exit 0 fi if [ $verbose = 1 ]; then # let the bristol gui give a verbose help text. engine=0 else brighton -V echo echo "startBristol [-explorer|-mini|-memory|-hammond|-b3|-dx|-axxe|-odyssey|-2600|-mono|-poly|-juno|-prophet|-pro10|-pro52|-mixer|-vox|-rhodes|-rhodesbass|-obx|-obxa|-aks|] [-oss|-alsa|-jack] [[-help|-h] [-verbose|-v]]" echo echo "Try 'startBristol -v|-h' for more verbose help output on device configuration." echo echo "Try 'startBristol -readme' for very verbose output" echo "Try 'startBristol -readme -mini' for info on specific emulator" echo echo "Try 'startBristol -b3' or 'startBristol -jack', for example, if you are unsure." echo echo "Q&A to nickycopeland@hotmail.com" echo "bugs, features, enhancements to http://sourceforge.net/projects/bristol" echo exit 0 fi } if [ $# = 0 ]; then HELP=1 fi # Nokey: Don't override BRISTOL if it's not already set if [ -z "$BRISTOL" ]; then if [ -d "${BRISTOL_DIR}/memory" ]; then export BRISTOL=${BRISTOL_DIR} else # We should first take our basename and look for a binary BRISTOL=`dirname $0` BRISTOL=`dirname $BRISTOL` if [ ! -f $BRISTOL/bin/bristol ]; then # # Take a default # export BRISTOL=/opt/audio/bristol fi fi fi export BRISTOL for index in $*; do if [ $index = "-stop" ]; then pkill bristol if [ $? != 0 ]; then pkill brighton fi exit 0 fi if [ $index = "-exit" ]; then pkill bristol pkill brighton exit 0 fi if [ $index = "-kill" ]; then pkill -f "\\$2" exit 0 fi if [ $index = "-host" ]; then host=`echo $2 | awk -F: '{print $1}'` if [ $host = "unix" ]; then localport=`echo $2 | awk -F: '{print $2}'` if [ -z $localport ]; then localport=$PORT fi fi fi if [ $index = "-freqtweak" ]; then FREQ=$2 if [ $FREQ != 0 -a -x /usr/bin/cpufreq-set -a $execme -eq 0 ]; then echo Setting min CPU speed to $FREQ cpufreq-set -d ${FREQ} fi fi if [ $index = "-count" ]; then COUNT=$2 fi if [ $index = "-rc" ]; then BRISTOL_RC=/dev/null fi if [ $index = "-sleep" ]; then sleep $2 fi if [ $index = "-emulate" ]; then EMULATE=$2 fi if [ $index = "-port" ]; then PORT=$2 fi if [ $index = "-cache" ]; then export BRISTOL_CACHE=$2 fi if [ $index = "-memdump" ]; then export BRISTOL_DUMP=$2 fi if [ $index = "--summary" ]; then brighton --summary exit 0 fi if [ $index = "-summary" ]; then brighton -summary exit 0 fi if [ $index = "-console" ]; then export BRISTOL_LOG_CONSOLE=true fi if [ $index = "-cli" ]; then cli=1 execme=0 fi if [ $index = "-exec" ]; then execme=0 fi if [ $index = "-ladi" ]; then execme=1 fi if [ $index = "-valgrind" ]; then valgrind=1 fi if [ $index = "-debug" ]; then liblist=1 fi if [ $index = "-liblist" ]; then liblist=1 fi if [ $index = "-master" ]; then engine=0 fi if [ $index = "-engine" ]; then engine=0 fi if [ $index = "-gui" ]; then gui=0 fi if [ $index = "-readme" ]; then README=1 fi if [ $index = "-v" ]; then HELP=2 fi if [ $index = "--v" ]; then HELP=2 fi if [ $index = "-verbose" ]; then verbose=1 fi if [ $index = "--verbose" ]; then verbose=1 fi if [ $index = "-version" ]; then HELP=3 fi if [ $index = "-V" ]; then HELP=3 fi if [ $index = "-logo" ]; then LOGO=yes fi if [ $index = "-h" ]; then HELP=2 fi if [ $index = "--h" ]; then HELP=2 fi if [ $index = "-help" ]; then HELP=2 fi if [ $index = "--help" ]; then HELP=2 fi if [ $index = "-libtest" ]; then engine=0 fi if [ $index = "-quiet" ]; then quiet=1 fi if [ $index = "-q" ]; then quiet=1 fi if [ $index = "-jsmuuid" ]; then export BRISTOL_AUTOCONN=false fi if [ $index = "-jackstats" ]; then JS=0 fi if [ $index = "-jack" ]; then jack=1 COUNT=1024 DRIVER=-jack fi if [ $index = "-audio" ]; then DRIVER=-$2 fi if [ $index = "-alsa" ]; then jack=0 DRIVER=-alsa fi if [ $index = "-jackstart" ]; then unset JACK_START_SERVER fi shift done # # As a note for anybody interested in reading this script, brighton also has # a BRISTOL_CACHE directory for private memories, sequences and controller maps. # Default is in $HOME/.bristol and we create this if it is not already made # if [ -z "$BRISTOL_CACHE" ]; then export BRISTOL_CACHE=${HOME}/.bristol fi if [ -z "$BRISTOL_DUMP" ]; then mkdir -p ${BRISTOL_CACHE}/memory else if [ ! -d $BRISTOL_DUMP/memory/$EMULATE ]; then mkdir -p $BRISTOL_DUMP/memory/$EMULATE cp -f $BRISTOL_DIR/memory/$EMULATE/* $BRISTOL_DUMP/memory/$EMULATE cp -f $BRISTOL_CACHE/memory/$EMULATE/* $BRISTOL_DUMP/memory/$EMULATE echo created memory shadow in $BRISTOL_DUMP fi export BRISTOL_CACHE=$BRISTOL_DUMP fi PREARGS= POSTARGS= # # Changed some of the processing to have tokens in the PREARGS file. We are # looking for PREARGS and POSTARGS. If we don't find either of them then take # the whole file which was the previous method and is equivalent to PREARGS # if [ -z "${BRISTOL_RC}" -a -f ${BRISTOL_CACHE}/bristolrc ]; then BRISTOL_RC=${BRISTOL_CACHE}/bristolrc fi if [ -f "${BRISTOL_RC}" ]; then egrep '(PREARGS|POSTARGS)' ${BRISTOL_RC} >/dev/null if [ $? -gt 0 ]; then PREARGS=`cat ${BRISTOL_RC}` else PREARGS=`awk -F= '/PREARGS/ {print $2}' ${BRISTOL_RC}` POSTARGS=`awk -F= '/POSTARGS/ {print $2}' ${BRISTOL_RC}` fi fi # Nokey: Does the BRISTOL directory actually exist? if [ ! -d $BRISTOL ]; then # Apparently not. Let's try to make a guess as to where it is. # Try to find out how we were started. If this script was in # the PATH of the user, the $0 should have a leading '/'. # This leading '/' would also be there if this script was # executed as /full/path/name/startBristol STARTUP=$0 # If this script was started as ./"*whatever*" then we need # to strip off the './' in order to accurately determine # the BRISTOL directory if [ "$(echo $STARTUP | cut -c 1-2)" = "./" ]; then STARTUP=$(echo $STARTUP | cut -c 3-) fi if [ "$(echo $STARTUP | cut -c 1)" = "/" ]; then BIN_DIR=$(dirname $STARTUP) else BIN_DIR=$(dirname $PWD/$STARTUP) fi export BRISTOL=$(dirname $BIN_DIR) unset BIN_DIR STARTUP fi if [ ${README} -ge 1 ]; then brighton $args | less exit 0 fi if [ ${HELP} -ge 1 ]; then showhelp fi # # Try and get Jack driver information. If the daemon is running, use it. If # user has a .jackdrc use that, otherwise use /etc/jackdrc # if [ ${DRIVER} = "-jack" ]; then jack=1 if [ $JS -ne 0 ]; then JP=`bristoljackstats 2>&1` if [ $? -eq 0 ]; then JACKPARAMS=`echo $JP | awk '/JACKSTATS/'` RATE=`echo ${JACKPARAMS} | awk '{print $2}'` COUNT=`echo ${JACKPARAMS} | awk '{print $3}'` echo jackstats found -rate ${RATE} -count ${COUNT} fi else # # We should not really get here. If jack was requested but the daemon # could not be reached (we did not get feedback from bristoljackstats) # then larger issues will occur presently # # Thanks to Sylvain Robitaille for the next code. # # See if the process is running # # We should replace this with pgrep and do it for this user - if the # daemon is running with other rights we may not be able to connect. # JACKD=`ps ax | grep -w jackd | grep -vw grep` # # Otherwise see what would be started # if [ -z "${JACKD}" ]; then echo "jack driver requested, jackd not running" if [ -f /etc/jackdrc ]; then echo "jack configuration found in /etc/jackdrc" JACKD=`cat /etc/jackdrc` fi if [ -f ~/.jackdrc ]; then echo "private jack configuration found in ~/.jackdrc" JACKD=`cat ~/.jackdrc` fi fi if [ -z "${JACKD}" ]; then RATE=48000 COUNT=1024 else RATE=`echo ${JACKD} |grep -o -- '-r[0-9][0-9]*' |sed 's/^-r//'` if [ -z "${RATE}" ]; then # assume Jackd's default rate: RATE=48000 fi #COUNT=`echo ${JACKD} |grep -o -- '-p[0-9][0-9]*' |sed 's/^-p//'` COUNT=`echo ${JACKD} |grep -o -- '-p[0-9][0-9]*' |tail -n1 |sed 's/^-p//'` if [ -z "${COUNT}" ]; then # assume Jackd's default count: COUNT=1024 fi fi fi fi # # If slabhome already exists, we should take it rather than this definition. # export SLAB_HOME=$BRISTOL export BRIGHTON=$BRISTOL export LD_LIBRARY_PATH=@BRISTOL_DIR@/lib:/usr/local/lib:/usr/lib:/lib export PATH=$BRISTOL/bin:/usr/local/bin:${PATH} if [ ${liblist} != 0 ]; then echo echo '*** bristol libraries ***' echo ldd `which bristol` echo '*** brighton libraries ***' echo ldd `which brighton` echo fi if [ $jack -eq 1 ]; then ldd `which bristol` | grep jack > /dev/null 2>&1 if [ $? -ne 0 ]; then echo Requested Jack drivers, not compiled into bristol exit -1 fi fi if [ ${LOGO} = "yes" ]; then # # Just to make sure # echo echo "Bristol is about to start." echo echo "This program is totally unrelated to ANY of the companies that produced" echo "the original instruments emulated by bristol, and none of the original" echo "manufacturers in ANY way endorse this product." echo sleep 1 fi # # Requesting an engine. This means we need a free TCP port. Our default is # 5028 and if it is not free then search for one from there # if [ $engine = 1 ]; then if [ $host = "unix" ]; then echo checking availability of host port $localport ls /tmp/br.$localport >/dev/null 2>&1 if [ $? -eq 0 ]; then echo "host port looked busy, unlinking" rm -f /tmp/br.$localport fi else echo checking availability of TCP port $PORT netstat -taln | awk '{print $4}' | grep $PORT > /dev/null while [ $? -eq 0 ]; do echo -n "port looked busy, trying " PORT=`expr $PORT + 1` echo $PORT netstat -taln | grep $PORT > /dev/null done if [ ${PORT} -lt 1024 -a ${USER} != "root" ]; then echo you may not have permissions for ports less than 1024 else echo using port $PORT fi fi fi # # Start up the GUI # if [ $cli = 1 ]; then if [ $engine = 1 ]; then bristol -rate ${RATE} -count ${COUNT} ${PREARGS} $args -port $PORT ${POSTARGS} & fi export BRISTOL_LOG_CONSOLE=true brighton ${PREARGS} $args -port ${PORT} ${POSTARGS} else if [ $gui = 1 ]; then if [ $engine = 1 ]; then if [ $quiet = 0 ]; then brighton ${PREARGS} $args -port ${PORT} ${POSTARGS} & else brighton ${PREARGS} $args -port ${PORT} ${POSTARGS} > /dev/null 2>&1 & fi else if [ $quiet = 0 ]; then if [ $execme = 0 ]; then if [ $valgrind = 0 ]; then brighton ${PREARGS} $args -port ${PORT} ${POSTARGS} else valgrind --leak-check=full -v --show-reachable=yes --track-origins=yes brighton $args -port ${PORT} ${POSTARGS} fi else exec brighton ${PREARGS} $args -port ${PORT} ${POSTARGS} fi guistatus=$? else if [ $execme = 0 ]; then brighton ${PREARGS} $args -port ${PORT} ${POSTARGS} > /dev/null 2>&1 else exec brighton ${PREARGS} $args -port ${PORT} ${POSTARGS} > /dev/null 2>&1 fi guistatus=$? fi fi fi # # the bristol engine has flags for -oss or -alsa drivers, -preload buffers of # -count samples: # bristol -preload 4 -count 256 [-oss] # if [ $engine = 1 ]; then if [ $quiet = 0 ]; then if [ $valgrind = 0 ]; then if [ $execme = 0 ]; then bristol -rate ${RATE} -count ${COUNT} ${PREARGS} $args -port $PORT ${POSTARGS} engstatus=$? else exec bristol -rate ${RATE} -count ${COUNT} ${PREARGS} $args -port $PORT ${POSTARGS} fi else valgrind --leak-check=full -v --show-reachable=yes --track-origins=yes bristol -rate ${RATE} -count ${COUNT} ${PREARGS} $args -port $PORT ${POSTARGS} engstatus=$? fi else if [ $execme = 0 ]; then bristol -rate ${RATE} -count ${COUNT} ${PREARGS} $args -port $PORT ${POSTARGS} > /dev/null 2>&1 else exec bristol -rate ${RATE} -count ${COUNT} ${PREARGS} $args -port $PORT ${POSTARGS} > /dev/null 2>&1 fi engstatus=$? fi fi fi # Make sure we have the children returned, prevents ugly delayed output if [ $engine = 1 ]; then wait % >/dev/null 2>&1 fi if [ $gui = 1 ]; then wait % >/dev/null 2>&1 fi sleep 1 if [ $FREQ != 0 -a -x /usr/bin/cpufreq-set ]; then cpufreq-set -d 250MHz fi # This could be a lot more intelligent but it will work. We need to remove any # dangling sockets. Alternatively just delete the files, the check for their # existance is superfluous rm -f /tmp/br.* >/dev/null 2>&1 exit `expr $engstatus + $guistatus` bristol-0.60.11/libbrightonX11/0000755000175000017500000000000012100257364013133 500000000000000bristol-0.60.11/libbrightonX11/bColor.c0000644000175000017500000001261011746476474014463 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include "brightonX11internals.h" int BFreeColor(brightonDisplay *display, brightonPalette *color) { bdisplay *bd = (bdisplay *) display->display; if (~display->flags & _BRIGHTON_WINDOW) { XFreeColors(bd->display, bd->cm, (unsigned long *) &(color->pixel), 1, 0); if (color->gc != NULL) XFreeGC(bd->display, color->gc); } color->flags &= ~B_ALLOCATED; if (color->color) { brightonX11free(color->color); color->color = 0; } color->color = 0; color->gc = 0; return(0); } int BAllocColorByName(brightonDisplay *display, brightonPalette *color, char *name) { bdisplay *bd = (bdisplay *) display->display; XColor *screen, exact; // printf("alloc color by name %s\n", name); screen = (XColor *) brightonX11malloc(sizeof(XColor)); if (~display->flags & _BRIGHTON_WINDOW) XAllocNamedColor(bd->display, bd->cm, name, screen, &exact); color->red = exact.red; color->green = exact.green; color->blue = exact.blue; color->color = screen; color->pixel = screen->pixel; color->flags |= B_ALLOCATED; return(0); } int xcolorcount; /* * Allocation of graphics contexts is only required when using pixmap rendering. * With the XImage rendering (0.10.7 and later) the library uses just the * pixel values. */ int BAllocGC(brightonDisplay *display, brightonPalette *color, unsigned short r, unsigned short g, unsigned short b) { bdisplay *bd = (bdisplay *) display->display; unsigned long valuemask = GCForeground; XGCValues values; XColor *screen = 0; if (color->color == 0) { screen = (XColor *) brightonX11malloc(sizeof(XColor)); screen->red = r; screen->green = g; screen->blue = b; screen->flags = DoRed|DoGreen|DoBlue; if (~display->flags & _BRIGHTON_WINDOW) XAllocColor(bd->display, bd->cm, screen); color->color = screen; color->pixel = screen->pixel; } else screen = color->color; values.foreground = screen->pixel; if (~display->flags & _BRIGHTON_WINDOW) color->gc = XCreateGC(bd->display, (Window) ((brightonWindow *) display->bwin)->win, valuemask, &values); color->flags |= B_ALLOCATED; xcolorcount++; return(0); } /* * This is used by the XImage interface which does not need a GC. The GC were * required by the XDrawPoints() interface for pixmap manipulation which is slow * and resource intensive. */ int BAllocColor(brightonDisplay *display, brightonPalette *color, unsigned short r, unsigned short g, unsigned short b) { bdisplay *bd = (bdisplay *) display->display; /* * Greyscale tests. * 1 is average, * 2 is min * 3 is max switch ((Window) ((brightonWindow *) display->bwin)->grayscale) { case 1: r = (r + g + b) / 3; g = b = r; break; case 2: r = (r + g + b) / 6; g = b = r; break; case 3: r = (r + g + b) / 12; g = b = r; break; case 4: if (r < g) { r = r < b? r:b; } else { r = g < b? g:b; } g = b = r; break; case 5: if (r > g) { r = r > b? r:b; } else { r = g > b? g:b; } g = b = r; break; } */ if (color->pixel <= 0) { XColor *screen; screen = (XColor *) brightonX11malloc(sizeof(XColor)); screen->red = r; screen->green = g; screen->blue = b; screen->flags = DoRed|DoGreen|DoBlue; if (~display->flags & _BRIGHTON_WINDOW) XAllocColor(bd->display, bd->cm, screen); color->color = screen; color->pixel = screen->pixel; } color->flags |= B_ALLOCATED; xcolorcount++; return(0); } brightonPalette * BInitColorMap(brightonDisplay *display) { bdisplay *bd = (bdisplay *) display->display; if (display->depth == 1) { printf("cannot support monochrome monitors....\n"); return(0); } if (display->flags & _BRIGHTON_WINDOW) return(display->palette); bd->cm = DefaultColormap(bd->display, bd->screen_num); if (!XMatchVisualInfo(bd->display, bd->screen_num, bd->depth, PseudoColor, &bd->dvi)) { if (!XMatchVisualInfo(bd->display, bd->screen_num, bd->depth, DirectColor, &bd->dvi)) { if (!XMatchVisualInfo(bd->display, bd->screen_num, bd->depth, TrueColor, &bd->dvi)) { if (!XMatchVisualInfo(bd->display, bd->screen_num, bd->depth, DirectColor, &bd->dvi)) { /* * No Psuedos or Directs. We could consider greyscale.... * This is probably superfluous these days. */ printf("Prefer not to have greyscale graphics.\n"); bd->flags |= BRIGHTON_GREYSCALE; return(display->palette); } } else { printf("Using TrueColor display\n"); } } else { printf("Using DirectColor display\n"); } } else { printf("Using PseudoColor display\n"); } /* printf("masks are %x %x %x\n", bd->dvi.red_mask, bd->dvi.red_mask, bd->dvi.red_mask); */ return(display->palette); } bristol-0.60.11/libbrightonX11/Makefile.in0000644000175000017500000004151312073601233015121 00000000000000# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = libbrightonX11 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LIBRARIES = $(noinst_LIBRARIES) ARFLAGS = cru libB11_a_AR = $(AR) $(ARFLAGS) libB11_a_LIBADD = am_libB11_a_OBJECTS = bColor.$(OBJEXT) bDisplay.$(OBJEXT) \ bEvent.$(OBJEXT) bRender.$(OBJEXT) bRoutines.$(OBJEXT) \ bWindow.$(OBJEXT) libB11_a_OBJECTS = $(am_libB11_a_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libB11_a_SOURCES) DIST_SOURCES = $(libB11_a_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALSA_CFLAGS = @ALSA_CFLAGS@ ALSA_LIBS = @ALSA_LIBS@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BRIGHTON_HAS_AUTOZOOM = @BRIGHTON_HAS_AUTOZOOM@ BRIGHTON_HAS_SHMIMAGE = @BRIGHTON_HAS_SHMIMAGE@ BRIGHTON_HAS_X11 = @BRIGHTON_HAS_X11@ BRIGHTON_HAS_XIMAGE = @BRIGHTON_HAS_XIMAGE@ BRIGHTON_LIBB11 = @BRIGHTON_LIBB11@ BRIGHTON_LIBX11 = @BRIGHTON_LIBX11@ BRIGHTON_LIBXEXT = @BRIGHTON_LIBXEXT@ BRIGHTON_LIBXLIBS = @BRIGHTON_LIBXLIBS@ BRIGHTON_X11_DIR = @BRIGHTON_X11_DIR@ BRISTOL_BARRIER = @BRISTOL_BARRIER@ BRISTOL_DIR = @BRISTOL_DIR@ BRISTOL_HAS_ALSA = @BRISTOL_HAS_ALSA@ BRISTOL_HAS_DRAIN = @BRISTOL_HAS_DRAIN@ BRISTOL_HAS_JACK = @BRISTOL_HAS_JACK@ BRISTOL_HAS_JACK_MIDI = @BRISTOL_HAS_JACK_MIDI@ BRISTOL_HAS_JACK_SESSION = @BRISTOL_HAS_JACK_SESSION@ BRISTOL_HAS_LIBLO = @BRISTOL_HAS_LIBLO@ BRISTOL_HAS_OSS = @BRISTOL_HAS_OSS@ BRISTOL_HAS_PA = @BRISTOL_HAS_PA@ BRISTOL_JACK_DEFAULT = @BRISTOL_JACK_DEFAULT@ BRISTOL_JACK_DEFAULT_MIDI = @BRISTOL_JACK_DEFAULT_MIDI@ BRISTOL_JACK_MULTI_CLOSE = @BRISTOL_JACK_MULTI_CLOSE@ BRISTOL_LIBPALIBS = @BRISTOL_LIBPALIBS@ BRISTOL_LIB_PA = @BRISTOL_LIB_PA@ BRISTOL_LIN_ATTACK = @BRISTOL_LIN_ATTACK@ BRISTOL_MAJOR_VERSION = @BRISTOL_MAJOR_VERSION@ BRISTOL_MICRO_VERSION = @BRISTOL_MICRO_VERSION@ BRISTOL_MINOR_VERSION = @BRISTOL_MINOR_VERSION@ BRISTOL_PA_DIR = @BRISTOL_PA_DIR@ BRISTOL_SEMAPHORE = @BRISTOL_SEMAPHORE@ BRISTOL_SEM_OPEN = @BRISTOL_SEM_OPEN@ BRISTOL_SO_VERSION = @BRISTOL_SO_VERSION@ BRISTOL_VERSION = @BRISTOL_VERSION@ BRR = @BRR@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFAULT_AUDIO_FLAG = @DEFAULT_AUDIO_FLAG@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JACK_CFLAGS = @JACK_CFLAGS@ JACK_LIBS = @JACK_LIBS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBLO_CFLAGS = @LIBLO_CFLAGS@ LIBLO_LIBS = @LIBLO_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ _BRISTOL_VOICES = @_BRISTOL_VOICES@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = foreign AM_CFLAGS = -pthread -Wall -g -I$(srcdir)/../include/brighton -I/usr/X11R6/include/ @BRIGHTON_HAS_XIMAGE@ @BRIGHTON_HAS_SHMIMAGE@ @BRIGHTON_HAS_X11@ #libB11_a_LDFLAGS= -export-dynamic -version-info @BRISTOL_SO_VERSION@ #libB11_a_LIBADD= -L/usr/X11R6/lib -lX11 noinst_LIBRARIES = libB11.a libB11_a_SOURCES = bColor.c bDisplay.c bEvent.c bRender.c bRoutines.c bWindow.c all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign libbrightonX11/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign libbrightonX11/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libB11.a: $(libB11_a_OBJECTS) $(libB11_a_DEPENDENCIES) $(EXTRA_libB11_a_DEPENDENCIES) -rm -f libB11.a $(libB11_a_AR) libB11.a $(libB11_a_OBJECTS) $(libB11_a_LIBADD) $(RANLIB) libB11.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bColor.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bDisplay.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bEvent.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bRender.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bRoutines.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bWindow.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLIBRARIES ctags distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am tags uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: bristol-0.60.11/libbrightonX11/Makefile.am0000755000175000017500000000061712073330071015112 00000000000000AUTOMAKE_OPTIONS = foreign AM_CFLAGS = -pthread -Wall -g -I$(srcdir)/../include/brighton -I/usr/X11R6/include/ @BRIGHTON_HAS_XIMAGE@ @BRIGHTON_HAS_SHMIMAGE@ @BRIGHTON_HAS_X11@ #libB11_a_LDFLAGS= -export-dynamic -version-info @BRISTOL_SO_VERSION@ #libB11_a_LIBADD= -L/usr/X11R6/lib -lX11 noinst_LIBRARIES = libB11.a libB11_a_SOURCES = bColor.c bDisplay.c bEvent.c bRender.c bRoutines.c bWindow.c bristol-0.60.11/libbrightonX11/bWindow.c0000644000175000017500000001300611746476474014654 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include "brightonX11internals.h" #include "icon_bitmap.xbm" /* We should bury this somewhere in the window */ Atom wmDeleteMessage; char *args[2] = {"bristol gui", (char *) 0}; int BOpenWindow(brightonDisplay *display, brightonWindow *bwin, char *programme) { bdisplay *bd = (bdisplay *) display->display; if (display->flags & _BRIGHTON_WINDOW) { bd->flags |= _BRIGHTON_WINDOW; return(bwin->win = (Window) 0xdeadbeef); } bd->x = bwin->x; bd->y = bwin->y; /* printf("libbrightonB11: %p %i, %i, %i, %i\n", bd->display, bwin->x, bwin->y, bwin->width, bwin->height); */ bwin->win = XCreateSimpleWindow(bd->display, RootWindow(bd->display, bd->screen_num), bwin->x, bwin->y, bwin->width, bwin->height, bd->border, WhitePixel(bd->display, bd->screen_num), BlackPixel(bd->display, bd->screen_num)); /* * Notify that we are interested in window manager delete events, and see * bEvent.c regarding how we find the events in Brighton. * */ wmDeleteMessage = XInternAtom(bd->display, "WM_DELETE_WINDOW", True); XSetWMProtocols(bd->display, bwin->win, &wmDeleteMessage, True); bd->icon_pixmap = XCreateBitmapFromData(bd->display, bwin->win, (char *) icon_bitmap_bits, (unsigned int) icon_bitmap_width, (unsigned int) icon_bitmap_height); bd->size_hints.flags = PPosition|PSize|PMinSize; bd->size_hints.min_width = 100; bd->size_hints.min_height = 10; bd->icon_name = programme; bwin->window_name = programme; if (XStringListToTextProperty(&bd->icon_name, 1, &bd->iconName) == 0) { printf("%s: allocation error for icon failed\n", programme); display->bwin = 0; return(0); } if (XStringListToTextProperty(&bwin->window_name, 1, &bd->windowName) == 0) { printf("%s: allocation error for window failed\n", programme); display->bwin = 0; return(0); } bd->wm_hints.initial_state = NormalState; bd->wm_hints.input = True; bd->wm_hints.icon_pixmap = bd->icon_pixmap; bd->wm_hints.flags = StateHint|IconPixmapHint|InputHint; bd->class_hints.res_name = programme; bd->class_hints.res_class = "BasicWin"; XSetWMProperties(bd->display, bwin->win, &bd->windowName, &bd->iconName, args, 1, &bd->size_hints, &bd->wm_hints, &bd->class_hints); XSelectInput(bd->display, bwin->win, KeyPressMask|KeyReleaseMask| ButtonPressMask|ButtonReleaseMask|Button1MotionMask| Button2MotionMask|Button3MotionMask|Button4MotionMask| Button5MotionMask|ButtonMotionMask| EnterWindowMask|LeaveWindowMask| KeymapStateMask|ExposureMask| VisibilityChangeMask|StructureNotifyMask| SubstructureNotifyMask|SubstructureRedirectMask| FocusChangeMask|FocusChangeMask| PropertyChangeMask|ColormapChangeMask|OwnerGrabButtonMask); /* * keep a reference to this parent for later use. */ bwin->parentwin = RootWindow(bd->display, bd->screen_num); /* * We have to register for the destroy event with our parent. * (Panned). XSelectInput(bd->display, bwin->parentwin, SubstructureNotifyMask); */ XMapWindow(bd->display, bwin->win); if (~bwin->flags & _BRIGHTON_POST) XIconifyWindow(bd->display, bwin->win, bd->screen_num); /* Incorrect location? Should maybe be in win structure? */ bwin->gc = DefaultGC(bd->display, bd->screen_num); return(bwin->win); } int BCloseWindow(brightonDisplay *display, brightonWindow *bwin) { bdisplay *bd = display->display; if (~display->flags & _BRIGHTON_WINDOW) XDestroyWindow(bd->display, bwin->win); return(0); } void BRaiseWindow(brightonDisplay *display, brightonWindow *bwin) { bdisplay *bd = display->display; if (~display->flags & _BRIGHTON_WINDOW) XRaiseWindow(bd->display, bwin->win); } void BLowerWindow(brightonDisplay *display, brightonWindow *bwin) { bdisplay *bd = display->display; if (~display->flags & _BRIGHTON_WINDOW) XLowerWindow(bd->display, bwin->win); } int BGetGeometry(brightonDisplay *display, brightonWindow *bwin) { bdisplay *bd = display->display; if (~bd->flags & _BRIGHTON_WINDOW) { if (XGetGeometry(bd->display, RootWindow(bd->display, bd->screen_num), &bd->root, (int *) (&bd->x), (int *) (&bd->y), &bd->width, &bd->height, &bd->border, &bd->depth) < 0) printf("cannot get root window geometry\n"); /* * I would prefer for these to come from the bitmap itself. */ bwin->width = bd->width; bwin->height = bd->height; bwin->depth = bd->depth; } else { bwin->width = 1024; bwin->height = 768; bwin->depth = 24; } return(0); } int BFlush(brightonDisplay *display) { bdisplay *bd = (bdisplay *) display->display; if (~display->flags & _BRIGHTON_WINDOW) XFlush(bd->display); return(0); } int BAutoRepeat(brightonDisplay *display, int onoff) { bdisplay *bd = display->display; if (display->flags & _BRIGHTON_WINDOW) return(0); if (onoff) { XAutoRepeatOn(bd->display); } else { XAutoRepeatOff(bd->display); } return(0); } bristol-0.60.11/libbrightonX11/bRoutines.c0000644000175000017500000000176311746476474015224 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include #include #include void * brightonX11malloc(size) { void *mem; mem = malloc(size); memset(mem, 0, size); return(mem); } void brightonX11free(void *mem) { free(mem); } bristol-0.60.11/libbrightonX11/bEvent.c0000644000175000017500000001477011746476474014477 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include "brightonX11internals.h" #include int command[BLASTEvent] = { BRIGHTON_NONE, BRIGHTON_NONE, BRIGHTON_KEYPRESS, BRIGHTON_KEYRELEASE, BRIGHTON_BUTTONPRESS, BRIGHTON_BUTTONRELEASE, BRIGHTON_MOTION, BRIGHTON_ENTER, BRIGHTON_LEAVE, BRIGHTON_FOCUS_IN, /* FocusIn */ BRIGHTON_FOCUS_OUT, /* FocusOut */ BRIGHTON_NONE, BRIGHTON_EXPOSE, BRIGHTON_GEXPOSE, BRIGHTON_NONE, BRIGHTON_NONE, BRIGHTON_NONE, BRIGHTON_DESTROY, BRIGHTON_NONE, BRIGHTON_NONE, BRIGHTON_NONE, BRIGHTON_NONE, BRIGHTON_CONFIGURE, BRIGHTON_CONFIGURE_REQ, BRIGHTON_NONE, BRIGHTON_RESIZE, BRIGHTON_NONE, BRIGHTON_NONE, BRIGHTON_NONE, BRIGHTON_NONE, BRIGHTON_NONE, BRIGHTON_NONE, BRIGHTON_NONE, BRIGHTON_CLIENT, BRIGHTON_NONE }; int BSendEvent(brightonDisplay *display, brightonWindow *bwin, brightonEvent *event) { bdisplay *bd = (bdisplay *) display->display; XEvent xevent; if ((bwin->flags & BRIGHTON_BUSY) || (display->flags & _BRIGHTON_WINDOW)) return(0); xevent.xany.type = KeyPress; xevent.xany.window = (Window) bwin->win; xevent.xkey.x = event->x; xevent.xkey.y = event->y; xevent.xkey.keycode = 'u'; if (XSendEvent(bd->display, (Window) bwin->win, False, KeyPressMask, &xevent) == 0) printf("send failed\n"); XFlush(bd->display); return(0); } int OldBNextEvent(brightonDisplay *display, brightonEvent *event) { bdisplay *bd = (bdisplay *) display->display; XEvent xevent; XNextEvent(bd->display, &xevent); event->type = xevent.xany.type; event->wid = xevent.xany.window; event->command = command[xevent.xany.type]; printf("event %i: %x\n", xevent.xany.type, event->wid); switch (xevent.xany.type) { case KeyPress: case KeyRelease: event->x = xevent.xkey.x; event->y = xevent.xkey.y; event->key = XLookupKeysym(&xevent.xkey, 0); /* * Left shift for right shift */ if (event->key == 65506) event->key = 65505; break; case ButtonPress: case ButtonRelease: event->x = xevent.xbutton.x; event->y = xevent.xbutton.y; event->key = xevent.xbutton.button; break; case MotionNotify: event->x = xevent.xmotion.x; event->y = xevent.xmotion.y; break; case ConfigureNotify: event->x = xevent.xconfigure.x; event->y = xevent.xconfigure.y; event->w = xevent.xconfigure.width; event->h = xevent.xconfigure.height; break; case ResizeRequest: event->w = xevent.xresizerequest.width; event->h = xevent.xresizerequest.height; break; case Expose: event->x = xevent.xexpose.x; event->y = xevent.xexpose.y; event->w = xevent.xexpose.width; event->h = xevent.xexpose.height; break; default: break; } return(0); } extern Atom wmDeleteMessage; int BNextEvent(brightonDisplay *display, brightonEvent *event) { bdisplay *bd = (bdisplay *) display->display; XEvent xevent; long int l, n; if (display->flags & _BRIGHTON_WINDOW) return(0); l = LastKnownRequestProcessed(bd->display); n = XNextRequest(bd->display); if ((l - n) >= 0) { printf("request window out of sync %i - %i = %i\n", (int) l, (int) n, (int) (l - n)); usleep(100000); } /* * This is a bit of overkill, I want to just use NextEvent however I need * to also get some notifications from the midi control channel into this * thread since they may update the screen. Only have a callback active * means this is not easy. It would probably have been better to reconsider * the thread separation but anyway, we check for masked and typed events, * the masked are generic mouse motion, keyboard, etc, the typed events * are specifically for WM notifications. */ if ((XCheckMaskEvent(bd->display, 0xffffffff, &xevent) == True) || (XCheckTypedEvent(bd->display, ClientMessage, &xevent) == True)) { event->type = xevent.xany.type; event->wid = xevent.xany.window; event->command = command[xevent.xany.type]; switch (xevent.xany.type) { case KeyPress: case KeyRelease: event->x = xevent.xkey.x; event->y = xevent.xkey.y; event->key = XLookupKeysym(&xevent.xkey, 0); event->flags = xevent.xkey.state; /* * Left shift for right shift */ if (event->key == 65506) event->key = 65505; break; case ButtonPress: case ButtonRelease: /* * We need to do some event translation for button4 and button5 * as these are used for a mousewheel up/down. We need to make * a translation into J/K for example. */ event->x = xevent.xbutton.x; event->y = xevent.xbutton.y; if (xevent.xbutton.button == 4) { event->type = KeyPress; event->command = command[2]; event->key = 0x6b; } else if (xevent.xbutton.button == 5) { event->type = KeyPress; event->command = command[2]; event->key = 0x6a; } else event->key = xevent.xbutton.button; break; case MotionNotify: event->x = xevent.xmotion.x; event->y = xevent.xmotion.y; break; case FocusIn: case FocusOut: break; case ConfigureNotify: event->x = xevent.xconfigure.x; event->y = xevent.xconfigure.y; event->w = xevent.xconfigure.width; event->h = xevent.xconfigure.height; break; case ResizeRequest: event->w = xevent.xresizerequest.width; event->h = xevent.xresizerequest.height; break; case Expose: event->x = xevent.xexpose.x; event->y = xevent.xexpose.y; event->w = xevent.xexpose.width; event->h = xevent.xexpose.height; break; case ClientMessage: /* * This is a bit rough at the moment. */ if (xevent.xclient.data.l[0] == wmDeleteMessage) { BAutoRepeat(display, 1); /* This was originally PIPE */ kill(getpid(), SIGHUP); } break; default: break; } return(1); } return(0); } bristol-0.60.11/libbrightonX11/bDisplay.c0000644000175000017500000000730411746476474015016 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include "brightonX11internals.h" bdisplay *displays; bdisplay * bFindDisplayByName(bdisplay *dlist, char *name) { if (dlist == 0) return(0); if (strcmp(dlist->name, name) == 0) return(dlist); return(bFindDisplayByName(dlist->next, name)); } bdisplay * bFindDisplay(bdisplay *dlist, bdisplay *display) { if (dlist == 0) return(0); if (dlist == display) return(display); return(bFindDisplay(dlist->next, display)); } bdisplay * BOpenDisplay(brightonDisplay *bd, char *displayname) { bdisplay *display, *exists; int ign, major, minor; Bool pixmaps; display = (bdisplay *) brightonX11malloc(sizeof(bdisplay)); //printf("BOpenDisplay(%s)\n", displayname); if (strcmp(displayname, "cli") == 0) { display->display = (void *) 0xdeadbeef; display->flags |= _BRIGHTON_WINDOW; display->uses = 1; } else { if ((exists = bFindDisplayByName(displays, displayname)) != 0) { printf("reusing display %s\n", displayname); exists->uses++; display->uses++; bcopy(exists, display, sizeof(bdisplay)); } else { if ((display->display = XOpenDisplay(displayname)) == NULL) { printf("cannot connect to %s\n", XDisplayName(displayname)); return(0); } display->uses = 1; } } /* * Link in the new display */ display->next = displays; if (displays) displays->last = display; displays = display; sprintf(display->name, "%s", displayname); if (~display->flags & _BRIGHTON_WINDOW) { printf("connected to %s\n", XDisplayName(displayname)); display->width = DisplayWidth(display->display, display->screen_num); display->height = DisplayHeight(display->display, display->screen_num); display->screen_num = DefaultScreen(display->display); display->screen_ptr = DefaultScreenOfDisplay(display->display); } else printf("not connected to display: cli\n"); bd->width = display->width; bd->height = display->height; bd->depth = display->depth; #ifdef BRIGHTON_XIMAGE #ifdef BRIGHTON_SHMIMAGE /* * Check for the XShm extension - mark that we want to use them */ bd->flags |= BRIGHTON_BIMAGE; if (XQueryExtension(display->display, "MIT-SHM", &ign, &ign, &ign)) { if (XShmQueryVersion(display->display, &major, &minor, &pixmaps) == True) { printf("XShm extention version %d.%d %s shared pixmaps\n", major, minor, (pixmaps==True) ? "with" : "without"); // if (pixmaps != True) // display->flags &= ~BRIGHTON_BIMAGE; } else bd->flags &= ~BRIGHTON_BIMAGE; } #endif #endif return(display); } int BCloseDisplay(bdisplay *display) { bdisplay *d; /* * Find the display */ if ((d = bFindDisplay(displays, display)) == 0) return(0); if (--d->uses == 0) { /* * Free the display, disconnect, etc. */ if (~display->flags & _BRIGHTON_WINDOW) XCloseDisplay(d->display); } /* * Unlink it. */ if (d->next) d->next->last = d->last; if (d->last) d->last->next = d->next; else displays = d->next; brightonX11free(d); return(0); } bristol-0.60.11/libbrightonX11/bRender.c0000644000175000017500000004007611746476474014633 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include "brightonX11internals.h" /* * At the moment (14/3/02) this code uses XDrawPoint directly onto the screen. * It could be accelerated by using an XImage structure. In the mean time this * will be accelerated using XDrawPoints() rather than the singular version. */ int BCopyArea(brightonDisplay *display, int x, int y, int w, int h, int dx, int dy) { bdisplay *bd = display->display; /*printf("BCopyArea(%x %x, (%i/%i/%i/%i) (%i/%i/%i,%i) %x\n",*/ /*bd, display->image, x, y, w, h, dx, dy, bd->width, bd->height, bd->gc);*/ if ((display->image == NULL) || (display->flags & _BRIGHTON_WINDOW)) return(0); #ifdef BRIGHTON_XIMAGE /* 0.10.7 code for XImage accelerators */ if (display->flags & BRIGHTON_BIMAGE) { //printf("image copy code %i %i, %i %i, %i %i\n", x, y, dx, dy, w, h); #ifdef BRIGHTON_SHMIMAGE XShmPutImage(bd->display, (Window) ((brightonWindow *) display->bwin)->win, (GC) ((brightonWindow *) display->bwin)->gc, (XImage *) display->image, x, y, dx, dy, w, h, False); #else XPutImage(bd->display, (Window) ((brightonWindow *) display->bwin)->win, (GC) ((brightonWindow *) display->bwin)->gc, (XImage *) display->image, x, y, dx, dy, w, h); #endif } else #endif XCopyArea(bd->display, (Pixmap) display->image, (Window) ((brightonWindow *) display->bwin)->win, (GC) ((brightonWindow *) display->bwin)->gc, x, y, w, h, dx, dy); return(0); } int BResizeWindow(brightonDisplay *display, brightonWindow *bwin, int width, int height) { bdisplay *bd = display->display; /*printf("BResizeWindow(%x, %x, %i, %i)\n", display, bwin, width, height);*/ if (~display->flags & _BRIGHTON_WINDOW) XResizeWindow(bd->display, (Window) bwin->win, width, height); return(0); } #ifdef BRIGHTON_XIMAGE #ifdef BRIGHTON_SHMIMAGE static int BDrawImage(brightonDisplay *display, brightonBitmap *bitmap, int sx, int sy, int sw, int sh, int destx, int desty) { register bdisplay *bd = display->display; /* register brightonWindow *bwin = (brightonWindow *) display->bwin; */ register brightonPalette *palette = display->palette; register int *pixels = bitmap->pixels; register int x, y, pindex; register int dx, dy = desty; XImage *image; struct shmid_ds myshmid; //printf("BDrawImage(%p, (%i/%i/%i/%i) (%i/%i) (%i/%i) %i\n", //bitmap, sx, sy, sw, sh, destx, desty, bd->width, bd->height, bd->depth); if (display->flags & _BRIGHTON_WINDOW) return(0); /* * See if we need an image or to resize the image */ if (display->image == 0) { char *iData; Visual *visual = DefaultVisual(bd->display, bd->screen_num); bd->width = ((brightonWindow *) display->bwin)->width; bd->height = ((brightonWindow *) display->bwin)->height; iData = brightonX11malloc(bd->width * bd->height * sizeof(unsigned)); /* * The bitmap pad has several interpretations and none of them seem * consistent, however if the last two parameters are not correctly * given then the call fails (seen on 64bit systems). We did have: * * 8 * sizeof(long) - bd->depth, sizeof(long) * bd->width)) * * This had been changed to * * bd->depth >= 24? 32: bd->depth, 0 * * However correctly speaking we might prefer * * bd->depth > 16? 32: bd->depth > 8? 16:8, 0 */ if ((image = (void *) XShmCreateImage( bd->display, visual, bd->depth, ZPixmap, 0, &bd->shminfo, bd->width, bd->height)) == NULL) { printf("failed to allocate image: try using option -pixmap\n"); brightonX11free(iData); return(0); } /* Get the shared memory and check for errors */ bd->shminfo.shmid = shmget(IPC_PRIVATE, image->bytes_per_line * image->height, IPC_CREAT | 0777 ); if(bd->shminfo.shmid < 0) return(0); /* attach, and check for errrors */ bd->shminfo.shmaddr = image->data = (char *) shmat(bd->shminfo.shmid, 0, 0); if (bd->shminfo.shmaddr == (char *) -1) return 1; /* set as read/write, and attach to the display */ bd->shminfo.readOnly = False; XShmAttach(bd->display, &bd->shminfo); /* * This looks odd but now that we have attached it, mark it for * deletion. This will clear up the mess after all the detaches * have occured. */ shmctl(bd->shminfo.shmid, IPC_STAT, &myshmid); shmctl(bd->shminfo.shmid, IPC_RMID, &myshmid); display->image = (void *) image; } else if ((bd->width != ((brightonWindow *) display->bwin)->width) || (bd->height != ((brightonWindow *) display->bwin)->height)) { char *iData; Visual *visual = DefaultVisual(bd->display, bd->screen_num); XShmDetach(bd->display, &bd->shminfo); XDestroyImage((XImage *) display->image); shmdt(bd->shminfo.shmaddr); bd->width = ((brightonWindow *) display->bwin)->width; bd->height = ((brightonWindow *) display->bwin)->height; iData = brightonX11malloc(bd->width * bd->height * sizeof(unsigned)); if ((image = (void *) XShmCreateImage( bd->display, visual, bd->depth, ZPixmap, 0, &bd->shminfo, bd->width, bd->height)) == NULL) { printf("failed to reallocate image\n"); brightonX11free(iData); return(0); } /* Get the shared memory and check for errors */ bd->shminfo.shmid = shmget(IPC_PRIVATE, image->bytes_per_line * image->height, IPC_CREAT | 0777 ); if(bd->shminfo.shmid < 0) return(0); /* attach, and check for errrors */ bd->shminfo.shmaddr = image->data = (char *) shmat(bd->shminfo.shmid, 0, 0); if (bd->shminfo.shmaddr == (char *) -1) return 1; /* set as read/write, and attach to the display */ bd->shminfo.readOnly = False; XShmAttach(bd->display, &bd->shminfo); /* * This looks odd but now that we have attached it, mark it for * deletion. This will clear up the mess after all the detaches * have occured. */ shmctl(bd->shminfo.shmid, IPC_STAT, &myshmid); shmctl(bd->shminfo.shmid, IPC_RMID, &myshmid); display->image = (void *) image; } /* * We now go through each pixel in the bitmap, check we have its color, and * then render it onto the pixmap. After that we copy the relevant area * of the pixmap over to the screen. * * This is currently the main performance hog since the color cache was * implemented in the libbrighton color management code. The only real * resolution that I can see is to use on screen bitmap management. */ for (y = sy; y < (sy + sh); y++) { if (y >= bitmap->height) break; dx = destx; for (x = sx; x < (sx + sw); x++) { if (x >= bitmap->width) break; pindex = y * bitmap->width + x; /* * Do not render blue */ if ((palette[pixels[pindex]].red == 0) && (palette[pixels[pindex]].green == 0) && (palette[pixels[pindex]].blue == 65535)) { ++dx; continue; } if (palette[pixels[pindex]].pixel < 0) { /* * Allocate a color so we can start painting with them. */ BAllocColor(display, &palette[pixels[pindex]], palette[pixels[pindex]].red, palette[pixels[pindex]].green, palette[pixels[pindex]].blue); } XPutPixel((XImage *) display->image, dx, dy, palette[pixels[pindex]].pixel); ++dx; } ++dy; } BCopyArea(display, destx, desty, sw, sh, destx, desty); return(0); } #else /* ShmImage code */ static int BDrawImage(brightonDisplay *display, brightonBitmap *bitmap, int sx, int sy, int sw, int sh, int destx, int desty) { register bdisplay *bd = display->display; /* register brightonWindow *bwin = (brightonWindow *) display->bwin; */ register brightonPalette *palette = display->palette; register int *pixels = bitmap->pixels; register int x, y, pindex; register int dx, dy = desty; //printf("BDrawImage(%x %x, (%i/%i/%i/%i) (%i/%i) (%i/%i) %i\n", //bwin, bitmap, sx, sy, sw, sh, destx, desty, bd->width, bd->height, bd->depth); if (display->flags & _BRIGHTON_WINDOW) return(0); /* * See if we need an image or to resize the image */ if (display->image == 0) { char *iData; Visual *visual = DefaultVisual(bd->display, bd->screen_num); bd->width = ((brightonWindow *) display->bwin)->width; bd->height = ((brightonWindow *) display->bwin)->height; iData = brightonX11malloc(bd->width * bd->height * sizeof(unsigned)); /* * The bitmap pad has several interpretations and none of them seem * consistent, however if the last two parameters are not correctly * given then the call fails (seen on 64bit systems). We did have: * * 8 * sizeof(long) - bd->depth, sizeof(long) * bd->width)) * * This had been changed to * * bd->depth >= 24? 32: bd->depth, 0 * * However correctly speaking we might prefer * * bd->depth > 16? 32: bd->depth > 8? 16:8, 0 */ if ((display->image = (void *) XCreateImage( bd->display, visual, bd->depth, ZPixmap, 0, iData, bd->width, bd->height, bd->depth > 16? 32:bd->depth > 8? 16:8, 0)) == NULL) { printf("failed to allocate image: try using option -pixmap\n"); brightonX11free(iData); return(0); } } else if ((bd->width != ((brightonWindow *) display->bwin)->width) || (bd->height != ((brightonWindow *) display->bwin)->height)) { char *iData; Visual *visual = DefaultVisual(bd->display, bd->screen_num); XDestroyImage((XImage *) display->image); bd->width = ((brightonWindow *) display->bwin)->width; bd->height = ((brightonWindow *) display->bwin)->height; iData = brightonX11malloc(bd->width * bd->height * sizeof(unsigned)); if ((display->image = (void *) XCreateImage( bd->display, visual, bd->depth, ZPixmap, 0, iData, bd->width, bd->height, bd->depth > 16? 32:bd->depth > 8? 16:8, 0)) == NULL) { printf("failed to reallocate image\n"); brightonX11free(iData); return(0); } } /* * We now go through each pixel in the bitmap, check we have its color, and * then render it onto the pixmap. After that we copy the relevant area * of the pixmap over to the screen. * * This is currently the main performance hog since the color cache was * implemented in the libbrighton color management code. The only real * resolution that I can see is to use on screen bitmap management. */ for (y = sy; y < (sy + sh); y++) { if (y >= bitmap->height) break; dx = destx; for (x = sx; x < (sx + sw); x++) { if (x >= bitmap->width) break; pindex = y * bitmap->width + x; /* * Do not render blue */ if ((palette[pixels[pindex]].red == 0) && (palette[pixels[pindex]].green == 0) && (palette[pixels[pindex]].blue == 65535)) { ++dx; continue; } if (palette[pixels[pindex]].pixel < 0) { /* * Allocate a color so we can start painting with them. */ BAllocColor(display, &palette[pixels[pindex]], palette[pixels[pindex]].red, palette[pixels[pindex]].green, palette[pixels[pindex]].blue); } XPutPixel((XImage *) display->image, dx, dy, palette[pixels[pindex]].pixel); ++dx; } ++dy; } BCopyArea(display, destx, desty, sw, sh, destx, desty); return(0); } #endif /* note shmImage code */ #endif /* Image code */ static int BDrawPixmap(brightonDisplay *display, brightonBitmap *bitmap, int sx, int sy, int sw, int sh, int destx, int desty) { bdisplay *bd = display->display; brightonWindow *bwin = (brightonWindow *) display->bwin; brightonQRender *qrender = bd->qrender; brightonPalette *palette = display->palette; int *pixels = bitmap->pixels, ncolors = bd->ocount, cindex; int missed = 0; GC tgc; int x, y, pindex; int dx, dy = desty; /*printf("BDrawArea(%x %x, (%i/%i/%i/%i) (%i/%i) (%i/%i) %i\n",*/ /*bwin, bitmap, sx, sy, sw, sh, destx, desty, bd->width, bd->height, bd->depth);*/ if (display->flags & _BRIGHTON_WINDOW) return(0); if (qrender == 0) { qrender = (brightonQRender *) brightonX11malloc(BRIGHTON_QR_COLORS * sizeof(brightonQRender)); bd->qrender = qrender; ncolors = bd->ocount = BRIGHTON_QR_COLORS; } /* * See if we need an image or to resize the image */ if (display->image == 0) { bd->width = ((brightonWindow *) display->bwin)->width; bd->height = ((brightonWindow *) display->bwin)->height; display->image = (void *) XCreatePixmap(bd->display, (Window) bwin->win, bd->width, bd->height, bd->depth); } else { if ((bd->width != ((brightonWindow *) display->bwin)->width) || (bd->height != ((brightonWindow *) display->bwin)->height)) { XFreePixmap(bd->display, (Pixmap) display->image); bd->width = ((brightonWindow *) display->bwin)->width; bd->height = ((brightonWindow *) display->bwin)->height; display->image = (void *) XCreatePixmap(bd->display, (Window) bwin->win, bd->width, bd->height, bd->depth); } } /* * We now go through each pixel in the bitmap, check we have its color, and * then render it onto the pixmap. After that we copy the relevant area * of the pixmap over to the screen. * * This is currently the main performance hog since the color cache was * implemented in the libbrighton color management code. The only real * resolution that I can see is to use on screen bitmap management. */ for (y = sy; y < (sy + sh); y++) { if (y >= bitmap->height) break; dx = destx; for (x = sx; x < (sx + sw); x++) { if (x >= bitmap->width) break; pindex = y * bitmap->width + x; /* * Do not render blue */ if ((palette[pixels[pindex]].red == 0) && (palette[pixels[pindex]].green == 0) && (palette[pixels[pindex]].blue == 65535)) { ++dx; continue; } if (palette[pixels[pindex]].gc == 0) { /* * Get a GC */ BAllocGC(display, &palette[pixels[pindex]], palette[pixels[pindex]].red, palette[pixels[pindex]].green, palette[pixels[pindex]].blue); } tgc = palette[pixels[pindex]].gc; for (cindex = 0; cindex < ncolors; cindex++) { if (qrender[cindex].gc == tgc) break; if (qrender[cindex].gc == 0) { /* * We have not filled this queue yet. */ qrender[cindex].gc = tgc; qrender[cindex].index = cindex; break; } } if (cindex == ncolors) { missed++; XDrawPoint(bd->display, (Pixmap) display->image, (GC) palette[pixels[pindex]].gc, dx, dy); } else { qrender[cindex].queue[qrender[cindex].count].x = dx; qrender[cindex].queue[qrender[cindex].count].y = dy; if (++qrender[cindex].count == BRIGHTON_QR_QSIZE) { XDrawPoints(bd->display, (Pixmap) display->image, tgc, qrender[cindex].queue, BRIGHTON_QR_QSIZE, CoordModeOrigin); qrender[cindex].count = 0; } } ++dx; } ++dy; } for (cindex = 0; cindex < ncolors; cindex++) { if (qrender[cindex].count == 0) continue; XDrawPoints(bd->display, (Pixmap) display->image, qrender[cindex].gc, qrender[cindex].queue, qrender[cindex].count, CoordModeOrigin); qrender[cindex].count = 0; } if (missed) { brightonX11free(bd->qrender); bd->ocount += BRIGHTON_QR_COLORS; bd->qrender = (brightonQRender *) brightonX11malloc(bd->ocount * sizeof(brightonQRender)); /*printf("Allocated %i colors (%i)\n", ncolors, bd->ocount);*/ } BCopyArea(display, destx, desty, sw, sh, destx, desty); return(0); } int BDrawArea(brightonDisplay *display, brightonBitmap *bitmap, int sx, int sy, int sw, int sh, int destx, int desty) { if (display->flags & _BRIGHTON_WINDOW) return(0); #ifdef BRIGHTON_XIMAGE /* 0.10.7 code for XImage accelerators */ if (display->flags & BRIGHTON_BIMAGE) return(BDrawImage(display, bitmap, sx, sy, sw, sh, destx, desty)); #endif return(BDrawPixmap(display, bitmap, sx, sy, sw, sh, destx, desty)); } bristol-0.60.11/bristoljackstats.10000644000175000017500000000350511651320011013717 00000000000000.\" Hey, EMACS: -*- nroff -*- .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) .TH BRISTOLJACKSTATS 1 "May 11, 2011" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: .\" .nh disable hyphenation .\" .hy enable hyphenation .\" .ad l left justify .\" .ad b justify to both left and right margins .\" .nf disable filling .\" .fi enable filling .\" .br insert line break .\" .sp insert n+1 empty lines .\" for manpage-specific macros, see man(7) .SH NAME bristoljackstats \- ancillary program for bristol .SH SYNOPSIS .B bristoljackstats .SH DESCRIPTION .PP .\" TeX users may be more comfortable with the \fB\fP and .\" \fI\fP escape sequences to invode bold face and italics, .\" respectively. \fBbristoljackstats\fP is an ancillary program for the bristol emulator suite which requests the jack engine start itself and report its target sampling rate and period size. These are needed a priori by bristol so have to be evaluated in advance. The program is not intended for general use, it is called by the startBristol process as the emulator environment is created. .SH SEE ALSO startBristol(1) .SH AUTHOR Written by Nicholas Copeland .SH REPORTING BUGS Bugs and enhancement requests can be submitted to the bristol project page on SourceForge: .PP .SH COPYRIGHT Copyright © 1996,2011 Nick Copeland. License GPLv3+: GNU GPL version 3 or later . This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. bristol-0.60.11/libbrighton/0000755000175000017500000000000012100257365012642 500000000000000bristol-0.60.11/libbrighton/brightonKbd.c0000644000175000017500000000621411746476474015211 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* * Render a brightonBitmap into an area. */ #include "brightoninternals.h" int destroyKbd(brightonDevice *dev) { printf("destroyKbd()\n"); if (dev->image) brightonFreeBitmap(dev->bwin, dev->image); dev->image = NULL; return(0); } static int displayKbd(brightonDevice *dev) { brightonIResource *panel; /*printf("displayKbd\n"); */ /* * We should render any text we desire into the bmap, and then have it * painted */ if (dev->bwin->app->resources[dev->panel].flags & BRIGHTON_WITHDRAWN) return(0); panel = &dev->bwin->app->resources[dev->panel]; brightonDevUndraw(dev->bwin, dev->bwin->dlayer, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width, dev->height); /* * Only draw fixed number of steps. */ brightonStretch(dev->bwin, dev->image, dev->bwin->dlayer, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width, dev->height, dev->position); brightonFinalRender(dev->bwin, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width, dev->height); return(0); } static int configure(brightonDevice *dev, brightonEvent *event) { /*printf("configureKbd(%i)\n", event->command); */ if (event->command == -1) return(-1); if (event->command == BRIGHTON_RESIZE) { dev->originx = event->x; dev->originy = event->y; dev->x = event->x; dev->y = event->y; dev->width = event->w; dev->height = event->h; displayKbd(dev); return(0); } if (event->command == BRIGHTON_PARAMCHANGE) { /* * This will be used to configure different background images */ if ((event->type == BRIGHTON_MEM) && (event->m != 0)) { if (dev->image) brightonFreeBitmap(dev->bwin, dev->image); dev->image = brightonReadImage(dev->bwin, event->m); displayKbd(dev); } } return(0); } int * createKbd(brightonWindow *bwin, brightonDevice *dev, int index, char *bitmap) { printf("createKbd(%s)\n", bitmap); dev->destroy = destroyKbd; dev->configure = configure; dev->bwin = bwin; if (bitmap != 0) { if (dev->image) brightonFreeBitmap(bwin, dev->image); dev->image = brightonReadImage(bwin, bitmap); } /* * These will force an update when we first display ourselves. */ dev->value = 0; dev->lastvalue = -1; dev->lastposition = -1; return(0); } bristol-0.60.11/libbrighton/brightonDevice.c0000644000175000017500000002046711746476474015716 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* * This is the generic device creator. It will generate the device and give it * all the generic handlers and tables. The device init is then also called to * provide its specifics. */ #include "brightoninternals.h" #include "brightonDevtable.h" extern int BSendEvent(brightonDisplay *, brightonWindow *, brightonEvent *); static int brightonInitDevice(brightonWindow *bwin, brightonDevice *device, int index, char *bitmap) { if (device->device == -1) return(0); /* * Then call the generic inheritances. */ if ((brightonDevTable[device->device].from >= 0) && (brightonDevTable[device->device].from != index)) { int orgdev = device->device; device->device = brightonDevTable[device->device].from; brightonInitDevice(bwin, device, index, bitmap); device->device = orgdev; } /* * And finally the specific instances */ brightonDevTable[device->device].create(bwin, device, index, bitmap); return(0); } brightonDevice * brightonCreateDevice(brightonWindow *bwin, int type, int panel, int index, char *bitmap) { brightonDevice *device; /* printf("brightonCreateDevice(%x, %i, %i, %s)\n", */ /* bwin, type, index, bitmap); */ if ((type < 0) || (type >= BRIGHTON_DEVTABLE_SIZE)) return(0); device = brightonmalloc(sizeof(brightonDevice)); device->device = type; device->panel = panel; device->index = index; device->flags |= BRIGHTON_DEV_INITED; if (brightonInitDevice(bwin, device, index, bitmap) == 0) return(device); else { brightonDestroyDevice(device); return(0); } } static void brightonDestroyDevices(brightonDevice *device) { #warning we return early here, that may have to be resolved printf("destroying %p\n", device); return; if ((device == 0) || (device->device == -1)) return; if ((brightonDevTable[device->device].from >= 0) && (brightonDevTable[device->device].from != device->device)) { int index = device->device; device->device = brightonDevTable[device->device].from; brightonDestroyDevices(device); device->device = index; } brightonDevTable[device->device].destroy(device); } void brightonDestroyDevice(brightonDevice *device) { printf("destroyDevice()\n"); brightonDestroyDevices(device); if (device->destroy) device->destroy(device); if (device->next) device->next->last = device->last; if (device->last) device->last->next = device->next; if (device->shadow.coords) brightonfree(device->shadow.coords); if (device->shadow.mask) brightonfree(device->shadow.mask); brightonfree(device); } void brightonConfigureDevice(brightonDevice *dev, brightonEvent *event) { } /* * Event can be motion, keypress, varchange, buttonpress, etc. * Alterations to world are handled in configure - ie, changes in position, * size, etc. We may, however, collapse these into a single call? */ void brightonDeviceEvent(brightonDevice *dev, brightonEvent *event) { } int brightonSendEvent(brightonWindow* bwin, int panel, int index, brightonEvent *event) { /* * This needs to go to BSendEvent(), this will evaluate global x/y location * so that the correct device receives the even. */ event->x = bwin->app->resources[panel].devlocn[index].x + bwin->app->resources[panel].x + 1; event->y = bwin->app->resources[panel].devlocn[index].y + bwin->app->resources[panel].y; return(BSendEvent(bwin->display, bwin, event)); } /* * This will make the GUI reflect the new value being given. */ int brightonParamChange(brightonWindow *bwin, int panel, int index, brightonEvent *event) { char *image = "bitmaps/images/cable.xpm"; if (((index < 0) && (event->type != BRIGHTON_EXPOSE)) || (panel < 0) || (bwin == NULL)) return(-1); if (panel >= bwin->app->nresources) { if (bwin->flags & BRIGHTON_DEBUG) printf("panel count %i over %i\n", panel, bwin->app->nresources); return(-1); } if (index >= bwin->app->resources[panel].ndevices) { /* * Drop this debug printf("index %i over panel count %i (transposed keyboard?)\n", index, bwin->app->resources[panel].ndevices); */ return(-1); } /* if (bwin->flags & BRIGHTON_BUSY) */ /* return(-1); */ /* printf("brightonParamChange(%x, %i): link\n", bwin, index); */ if (event->type == BRIGHTON_LINK) { int i2, x1, y1, x2, y2, xh; /* * The main reason to be here is to adjust the location of the place * request. We do not really mind what the device is, only the two * indices, source and dest. These are taken from the resource list * and scaled according to the window geometry, then placed on the * device bitmaps. * * We have the brightonWindow which gives us all our resources, and * we should know which devices we are linking together. */ if ((i2 = event->intvalue) < 0) return(0); x1 = bwin->app->resources[panel].devlocn[index].x * bwin->app->resources[panel].sw / 1000 + bwin->app->resources[panel].sx; y1 = bwin->app->resources[panel].devlocn[index].y * bwin->app->resources[panel].sh / 1000 + bwin->app->resources[panel].sy; x2 = bwin->app->resources[panel].devlocn[i2].x * bwin->app->resources[panel].sw / 1000 + bwin->app->resources[panel].sx; y2 = bwin->app->resources[panel].devlocn[i2].y * bwin->app->resources[panel].sh / 1000 + bwin->app->resources[panel].sy; if (x2 < x1) { xh = x2; x2 = x1; x1 = xh; xh = y2; y2 = y1; y1 = xh; image = "bitmaps/images/cablered.xpm"; } else image = "bitmaps/images/cableyellow.xpm"; /* * We should correct positioning now: the aspect - if height is greater * then width then we are going to use a different bitmap and it will * be slid rather than shifted, and the endpoints need to have some * constants added. Plus we want to give organised coord (x1 < x2). */ if (x2 < x1) { int w, h, xh = x2, yh = y2; image = "bitmaps/images/cableyellow.xpm"; x2 = x1; y2 = y1; x1 = xh; y1 = yh; w = x2 - x1; if ((h = y2 - y1) < 0) h = -h; if (w < h) { x1 += 1; y1 -= 0; x2 += 3; y2 += 8; image = "bitmaps/images/cableV.xpm"; } else { x1 += 2; y1 += 0; x2 += 9; y2 -= 1; } } else { int w, h; w = x2 - x1; if ((h = y2 - y1) < 0) h = -h; if (w < h) { if (bwin->app->resources[panel].devlocn[i2].x < bwin->app->resources[panel].devlocn[index].x) image = "bitmaps/images/cableVred.xpm"; else image = "bitmaps/images/cableVyellow.xpm"; if (y1 < y2) { x1 += 2; y1 += 1; x2 += 3; y2 += 7; } else { x1 += 1; y1 += 7; x2 += 2; y2 += 1; } } else { if (y1 < y2) { x1 += 2; y1 += 0; x2 += 8; y2 += 2; } else { x1 += 2; y1 -= 0; x2 += 8; y2 -= 1; } } } return(brightonPlace(bwin, image, x1, y1, x2, y2)); } if (event->type == BRIGHTON_UNLINK) { brightonRemove(bwin, event->intvalue); return(-1); } if ((event->command != BRIGHTON_SLOW_TIMER) && (event->command != BRIGHTON_FAST_TIMER)) event->command = BRIGHTON_PARAMCHANGE; /* if (type == 0) param.args.f = value; else if (type == 1) param.args.m = (void *) &value; */ if (panel >= bwin->app->nresources) return(-1); if (index >= bwin->app->resources[panel].ndevices) return(-1); if (bwin->app->resources[panel].devlocn[index].type == -1) return(-1); /* * See if this is a panel configuration event. */ if (index == -1) { if (bwin->app->resources[panel].configure) bwin->app->resources[panel].configure (bwin, &bwin->app->resources[panel], event); } else ((brightonDevice *) bwin->app->resources[panel].devlocn[index].dev) ->configure(bwin->app->resources[panel].devlocn[index].dev, event); return(0); } bristol-0.60.11/libbrighton/brightonHammond.c0000644000175000017500000003662111746476474016101 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* * This will be a linear drawbar. Takes a bitmap and locates it according to * input from the mouse/keyboard. Previous positions need to be unmapped, since * there is total repositioning of the image bitmap. */ #include "brightoninternals.h" int destroyHammond(brightonDevice *dev) { printf("destroyHammond()\n"); if (dev->image) brightonFreeBitmap(dev->bwin, dev->image); dev->image = NULL; return(0); } static int displayhammond(brightonDevice *dev) { brightonIResource *panel; float displayvalue; if (dev->bwin->app->resources[dev->panel].flags & BRIGHTON_WITHDRAWN) return(0); if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_WITHDRAWN) return(0); panel = &dev->bwin->app->resources[dev->panel]; /* * Build up a smooth position for the bar. We may need to adjust this based * on the to/from values. */ if (dev->value == dev->lastvalue) return(0); displayvalue = dev->value; /* brightonFinalRender(dev->bwin, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->lastposition + dev->bwin->app->resources[dev->panel].sy, dev->width, dev->height / 4); */ /* * This seems odd, the vertical flag refers to the scrolled item, not the * direction of movement. Perhaps that should change as the direction of * movement is counterintuitive */ if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_VERTICAL) { if (dev->lastposition >= 0) { brightonDevUndraw(dev->bwin, dev->bwin->dlayer, dev->x + ((int) dev->lastposition) + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width / 8, dev->height); brightonRenderShadow(dev, 1); } dev->position = displayvalue * (dev->width - dev->width / 4); /* * Only draw fixed number of steps. Panned. Just draw it..... */ brightonStretch(dev->bwin, dev->image, dev->bwin->dlayer, (int)(dev->x + dev->position + dev->bwin->app->resources[dev->panel].sx), dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width / 8, dev->height, 1); brightonRenderShadow(dev, 0); /* * And request the panel to put this onto the respective image. */ if (dev->position > dev->lastposition) { brightonFinalRender(dev->bwin, dev->x + dev->lastposition + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width * 2, dev->position - dev->lastposition + (dev->width >> 2) + (dev->height >> 1)); } else { brightonFinalRender(dev->bwin, dev->x + dev->position + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width * 2 + 1, dev->lastposition - dev->position + (dev->width >> 2) + (dev->height >> 1)); } } else { if (dev->lastposition >= 0) { brightonDevUndraw(dev->bwin, dev->bwin->dlayer, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + ((int) dev->lastposition) + dev->bwin->app->resources[dev->panel].sy, dev->width, dev->height / 4); brightonRenderShadow(dev, 1); } dev->position = displayvalue * (dev->height - dev->height / 4); /* * Drawbars are only ever rendered vertically. */ if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_HSCALE) { brightonBitmap image2; brightonDevUndraw(dev->bwin, dev->bwin->dlayer, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width, dev->height); /* * For the Hammond scale we need a different transform. The bitmap * wants to be stretched onto the destination, but only part of it * depending on the current value. * * We have to dynamically rebuild the bitmap as well so that we * get it to move rather than just be placed. */ image2.flags = dev->image2->flags; image2.width = dev->image2->width; image2.ncolors = dev->image2->ncolors; image2.ctabsize = dev->image2->ctabsize; image2.istatic = dev->image2->istatic; image2.ostatic = dev->image2->ostatic; image2.colormap = dev->image2->colormap; image2.name = dev->image2->name; image2.height = (((float) dev->image2->height) * displayvalue); image2.pixels = &dev->image2->pixels[ dev->image2->height * image2.width - image2.height * image2.width]; if (image2.height != 0) brightonStretch(dev->bwin, &image2, dev->bwin->dlayer, (int) (dev->x + dev->bwin->app->resources[dev->panel].sx), (int) (dev->y + dev->bwin->app->resources[dev->panel].sy), dev->width, (int) dev->position, 0); brightonFinalRender(dev->bwin, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width, (int) dev->height); } /* * Only draw fixed number of steps. Panned. Just draw it..... */ brightonStretch(dev->bwin, dev->image, dev->bwin->dlayer, dev->x + dev->bwin->app->resources[dev->panel].sx, (int)(dev->y + dev->position + dev->bwin->app->resources[dev->panel].sy), dev->width, dev->height / 4, 0); brightonRenderShadow(dev, 0); /* * And request the panel to put this onto the respective image. */ if (dev->position > dev->lastposition) { brightonFinalRender(dev->bwin, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->lastposition + dev->bwin->app->resources[dev->panel].sy, dev->width * 2, dev->position - dev->lastposition + (dev->height >> 2) + (dev->width >> 1)); } else { brightonFinalRender(dev->bwin, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->position + dev->bwin->app->resources[dev->panel].sy, dev->width * 2, dev->lastposition - dev->position + (dev->height >> 2) + 1 + (dev->width >> 1)); } } dev->lastvalue = dev->value; dev->lastposition = dev->position; return(0); } static int considercallback(brightonDevice *dev) { brightonIResource *panel = &dev->bwin->app->resources[dev->panel]; float callvalue; if (dev->bwin->flags & BRIGHTON_NO_DRAW) return(0); if (dev->value > 1.0) dev->value = 1.0; else if (dev->value < 0) dev->value = 0.0; /* * Due to the co-ordinate system, if we do NOT have the reverse flags * then we need to reverse the value. */ if ((dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_REVERSE) == 0) callvalue = 1.0 - dev->value; else callvalue = dev->value; if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].to != 1.0) { callvalue = (callvalue * dev->bwin->app->resources[dev->panel].devlocn[dev->index].to); if ((callvalue - ((int) callvalue)) > 0.5) callvalue = ((float) ((int) callvalue) + 1); else callvalue = ((float) ((int) callvalue)); } if (dev->lastvalue != dev->value) { if (panel->devlocn[dev->index].callback) { panel->devlocn[dev->index].callback(dev->bwin, dev->panel, dev->index, callvalue); } else { if (panel->callback) panel->callback(dev->bwin, dev->panel, dev->index, callvalue); } } return(0); } static int cx, cy; static float sval; static int configure(brightonDevice *dev, brightonEvent *event) { /* printf("configureHammond(%i, %f)\n", event->command, event->value); */ if (event->command == -1) return(-1); if (event->command == BRIGHTON_RESIZE) { dev->originx = event->x; dev->originy = event->y; dev->x = event->x; dev->y = event->y; dev->width = event->w; dev->height = event->h; /* * We should now rework our parent understanding of our window, since * it will have altered. NOT NECESSARY FOR SCALE. brightonPanelLocation(dev->bwin, dev->panel, dev->index, dev->x, dev->y, dev->width, dev->height); considercallback(dev); */ /* * Highlights need to be rendered dynamically in displayhammond(). */ dev->lastvalue = -1; displayhammond(dev); return(0); } if (event->command == BRIGHTON_KEYRELEASE) { /* * This is a little bit 'happens they work'. We should fix these key * mappings for keycodes. */ switch(event->key) { default: break; case 37: case 109: case 65508: case 65507: dev->flags &= ~BRIGHTON_CONTROLKEY; cx = cy = sval = -1; break; case 50: case 62: case 65505: dev->flags &= ~BRIGHTON_SHIFTKEY; break; } } if (event->command == BRIGHTON_BUTTONPRESS) { /* * This is hard coded, it calls back to the GUI. This is incorrect as * the callback dispatcher should be requested by the GUI. * * Perhaps the MIDI code should actually be in the same library? Why * does the GUI need to know about this? */ if (event->key == BRIGHTON_BUTTON2) brightonRegisterController(dev); return(0); } if (event->command == BRIGHTON_BUTTONRELEASE) { cx = cy = sval = -1; dev->flags &= ~BRIGHTON_CONTROLKEY; if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_CENTER) { dev->value = 0.5; considercallback(dev); displayhammond(dev); } return(0); } if (event->command == BRIGHTON_KEYPRESS) { switch(event->key) { default: break; case 37: case 109: case 65508: case 65507: cx = event->x; cy = event->y; sval = dev->value; dev->flags |= BRIGHTON_CONTROLKEY; break; case 50: case 62: case 65505: dev->flags |= BRIGHTON_SHIFTKEY; break; case 0x6a: case 0xff54: if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_VERTICAL) { if (dev->flags & BRIGHTON_SHIFTKEY) dev->value -= ((float) 256) / 16384; else dev->value -= ((float) 1) / 16384; } else { if (dev->flags & BRIGHTON_SHIFTKEY) dev->value += ((float) 256) / 16384; else dev->value += ((float) 1) / 16384; } break; case 0x6b: case 0xff52: /*if (dev->flags & BRIGHTON_VERTICAL) */ if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_VERTICAL) { if (dev->flags & BRIGHTON_SHIFTKEY) dev->value += ((float) 256) / 16384; else dev->value += ((float) 1) / 16384; } else { if (dev->flags & BRIGHTON_SHIFTKEY) dev->value -= ((float) 256) / 16384; else dev->value -= ((float) 1) / 16384; } break; } considercallback(dev); displayhammond(dev); } if (event->command == BRIGHTON_MOTION) { if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_VERTICAL) { /* * Need to add in an optional central dead spot. This should be a * small fraction of either side of the bar. It will be where * position deviates from mouse location. if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_NOTCH) { } else */ if (dev->flags & BRIGHTON_CONTROLKEY) { float deltax; if (cx == -1) { sval = dev->value; cx = event->x; cy = event->y; } deltax = ((float) (event->x - cx)) / 16383.0f; dev->value = sval + deltax; } else if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_NOTCH) { /* * When we are passing zero we should hold for a bit. */ dev->value = (((float) (event->x + 5 - dev->x - (dev->width / 8))) / (dev->width - dev->width / 4)); if (dev->value > 0.6) dev->value -= 0.1; else if (dev->value < 0.4) dev->value += 0.1; else dev->value = 0.5; } else dev->value = (((float) (event->x + 5 - dev->x - (dev->width / 8))) / (dev->width - dev->width / 4)); } else { if (dev->flags & BRIGHTON_CONTROLKEY) { float deltax; if (cx == -1) { sval = dev->value; cx = event->x; cy = event->y; } deltax = ((float) (event->y - cy)) / 16383.0f; dev->value = sval + deltax; } else if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_NOTCH) { dev->value = (((float) (event->y - dev->y - (dev->height / 8))) / (dev->height - dev->height / 4)); if (dev->value > 0.6) dev->value -= 0.1; else if (dev->value < 0.4) dev->value += 0.1; else dev->value = 0.5; } else dev->value = (((float) (event->y - dev->y - (dev->height / 8))) / (dev->height - dev->height / 4)); } /*printf("hammond motion %i %i, %i %i, %i %i: %f\n", */ /*event->x, event->y, dev->x, dev->y, dev->width, dev->height, dev->value); */ /* * We now need to consider rounding this to the resolution of this * device. If the max value is not 1.0 then we need to put fixed steps * into our new device value. */ if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].to != 1.0) { dev->value = (float) ((int) (dev->value * dev->bwin->app->resources[dev->panel].devlocn[dev->index].to)) / dev->bwin->app->resources[dev->panel].devlocn[dev->index].to; } considercallback(dev); displayhammond(dev); return(0); } if (event->command == BRIGHTON_PARAMCHANGE) { if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_REVERSE) dev->value = event->value / dev->bwin->app->resources[dev->panel].devlocn[dev->index].to; else { if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].to != 1.0) { dev->value = (dev->bwin->app->resources[dev->panel].devlocn[dev->index].to - event->value) / dev->bwin->app->resources[dev->panel].devlocn[dev->index].to; } else { dev->value = (1.0 - event->value) / dev->bwin->app->resources[dev->panel].devlocn[dev->index].to; } } considercallback(dev); displayhammond(dev); return(0); } return(0); } int * createHammond(brightonWindow *bwin, brightonDevice *dev, int index, char *bitmap) { /* printf("createHammond(%s)\n", bitmap); */ dev->destroy = destroyHammond; dev->configure = configure; dev->index = index; dev->bwin = bwin; if (bitmap == 0) { if (dev->image) brightonFreeBitmap(bwin, dev->image); /* * Open the default bitmap */ if (bwin->app->resources[dev->panel].devlocn[dev->index].image != 0) dev->image = bwin->app->resources[dev->panel].devlocn[dev->index].image; else dev->image = brightonReadImage(bwin, "bitmaps/knobs/slider1.xpm"); } else { if (dev->image) brightonFreeBitmap(bwin, dev->image); dev->image = brightonReadImage(bwin, bitmap); } if (bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_HSCALE) { if (dev->image2) brightonFreeBitmap(bwin, dev->image2); dev->image2 = brightonReadImage(bwin, "bitmaps/knobs/hammondbar.xpm"); } /* * These will force an update when we first display ourselves. */ if (bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_CENTER) dev->value = 0.5; else dev->value = 0; dev->value = 0.500001; dev->lastvalue = -1; dev->lastposition = 0; return(0); } bristol-0.60.11/libbrighton/brightonModWheel.c0000644000175000017500000003547211746476474016225 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* * This will be a linear drawbar. Takes a bitmap and locates it according to * input from the mouse/keyboard. Previous positions need to be unmapped, since * there is total repositioning of the image bitmap. */ #include "brightoninternals.h" int destroyModWheel(brightonDevice *dev) { printf("destroyModWheel()\n"); if (dev->image) brightonFreeBitmap(dev->bwin, dev->image); dev->image = NULL; return(0); } static int displaymodwheel(brightonDevice *dev) { brightonIResource *panel; float displayvalue; if (dev->bwin->app->resources[dev->panel].flags & BRIGHTON_WITHDRAWN) return(0); if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_WITHDRAWN) return(0); panel = &dev->bwin->app->resources[dev->panel]; /* * Build up a smooth position for the bar. We may need to adjust this based * on the to/from values. */ if (dev->value == dev->lastvalue) return(0); displayvalue = dev->value; /* brightonFinalRender(dev->bwin, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->lastposition + dev->bwin->app->resources[dev->panel].sy, dev->width, dev->height / 4); */ /* * This seems odd, the vertical flag refers to the scrolled item, not the * direction of movement. Perhaps that should change as the direction of * movement is counterintuitive */ if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_VERTICAL) { if (dev->lastposition >= 0) { brightonDevUndraw(dev->bwin, dev->bwin->dlayer, dev->x + ((int) dev->lastposition) + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width / 8, dev->height); brightonRenderShadow(dev, 1); } dev->position = displayvalue * (dev->width - dev->width / 4); /* * Only draw fixed number of steps. Panned. Just draw it..... */ brightonStretch(dev->bwin, dev->image, dev->bwin->dlayer, (int)(dev->x + dev->position + dev->bwin->app->resources[dev->panel].sx), dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width / 8, dev->height, 1); brightonRenderShadow(dev, 0); /* * And request the panel to put this onto the respective image. */ if (dev->position > dev->lastposition) { brightonFinalRender(dev->bwin, dev->x + dev->lastposition + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width * 2, dev->position - dev->lastposition + (dev->width >> 2) + (dev->height >> 1)); } else { brightonFinalRender(dev->bwin, dev->x + dev->position + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width * 2 + 1, dev->lastposition - dev->position + (dev->width >> 2) + (dev->height >> 1)); } } else { brightonBitmap image2; dev->position = displayvalue * (dev->height - dev->height / 4); /* printf("modwheel motion %i %i, %i %i, %i %i: %f\n", event->x, event->y, dev->x, dev->y, dev->width, dev->height, dev->value); */ /* * Don't need to undraw as we have to paint the whole lot anyway * brightonDevUndraw(dev->bwin, dev->bwin->dlayer, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width, dev->height); * For the ModWheel scale we need a different transform. The bitmap * wants to be stretched onto the destination, but only part of it * depending on the current value. * * We have to dynamically rebuild the bitmap as well so that we * get it to move rather than just be placed. */ image2.flags = dev->image2->flags; image2.width = dev->image2->width; image2.ncolors = dev->image2->ncolors; image2.ctabsize = dev->image2->ctabsize; image2.istatic = dev->image2->istatic; image2.ostatic = dev->image2->ostatic; image2.colormap = dev->image2->colormap; image2.name = dev->image2->name; image2.height = dev->image2->height * 9 / 16; image2.pixels = &dev->image2->pixels[image2.width * (int) (((float) dev->image2->height * 7/16) * (1.0 - dev->value))]; if (image2.height != 0) brightonStretch(dev->bwin, &image2, dev->bwin->dlayer, (int) (dev->x + dev->bwin->app->resources[dev->panel].sx), (int) (dev->y + dev->bwin->app->resources[dev->panel].sy), dev->width, dev->height, 0); brightonFinalRender(dev->bwin, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width, (int) dev->height); } dev->lastvalue = dev->value; dev->lastposition = dev->position; return(0); } static int considercallback(brightonDevice *dev) { brightonIResource *panel = &dev->bwin->app->resources[dev->panel]; float callvalue; if (dev->bwin->flags & BRIGHTON_NO_DRAW) return(0); if (dev->value > 1.0) dev->value = 1.0; else if (dev->value < 0) dev->value = 0.0; /* * Due to the co-ordinate system, if we do NOT have the reverse flags * then we need to reverse the value. */ if ((dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_REVERSE) == 0) callvalue = 1.0 - dev->value; else callvalue = dev->value; if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].to != 1.0) { callvalue = (callvalue * dev->bwin->app->resources[dev->panel].devlocn[dev->index].to); if ((callvalue - ((int) callvalue)) > 0.5) callvalue = ((float) ((int) callvalue) + 1); else callvalue = ((float) ((int) callvalue)); } if (dev->lastvalue != dev->value) { if (panel->devlocn[dev->index].callback) { panel->devlocn[dev->index].callback(dev->bwin, dev->panel, dev->index, callvalue); } else { if (panel->callback) panel->callback(dev->bwin, dev->panel, dev->index, callvalue); } } return(0); } static int cx, cy; static float sval; static int configure(brightonDevice *dev, brightonEvent *event) { /* printf("configureModWheel(%i, %f)\n", event->command, event->value); */ if (event->command == -1) return(-1); if (event->command == BRIGHTON_RESIZE) { dev->originx = event->x; dev->originy = event->y; dev->x = event->x; dev->y = event->y; dev->width = event->w; dev->height = event->h; /* * We should now rework our parent understanding of our window, since * it will have altered. NOT NECESSARY FOR SCALE. brightonPanelLocation(dev->bwin, dev->panel, dev->index, dev->x, dev->y, dev->width, dev->height); considercallback(dev); */ /* * Highlights need to be rendered dynamically in displaymodwheel(). */ dev->lastvalue = -1; displaymodwheel(dev); return(0); } if (event->command == BRIGHTON_KEYRELEASE) { /* * This is a little bit 'happens they work'. We should fix these key * mappings for keycodes. */ switch(event->key) { default: break; case 37: case 109: case 65508: case 65507: dev->flags &= ~BRIGHTON_CONTROLKEY; cx = cy = sval = -1; break; case 50: case 62: case 65505: dev->flags &= ~BRIGHTON_SHIFTKEY; break; } } if (event->command == BRIGHTON_BUTTONPRESS) { /* * This is hard coded, it calls back to the GUI. This is incorrect as * the callback dispatcher should be requested by the GUI. * * Perhaps the MIDI code should actually be in the same library? Why * does the GUI need to know about this? */ if (event->key == BRIGHTON_BUTTON2) brightonRegisterController(dev); return(0); } if (event->command == BRIGHTON_BUTTONRELEASE) { cx = cy = sval = -1; dev->flags &= ~BRIGHTON_CONTROLKEY; if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_CENTER) { dev->value = 0.5; considercallback(dev); displaymodwheel(dev); } return(0); } if (event->command == BRIGHTON_KEYPRESS) { switch(event->key) { default: break; case 37: case 109: case 65508: case 65507: cx = event->x; cy = event->y; sval = dev->value; dev->flags |= BRIGHTON_CONTROLKEY; break; case 50: case 62: case 65505: dev->flags |= BRIGHTON_SHIFTKEY; break; case 0x6a: case 0xff54: if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_VERTICAL) { if (dev->flags & BRIGHTON_SHIFTKEY) dev->value -= ((float) 256) / 16384; else dev->value -= ((float) 1) / 16384; } else { if (dev->flags & BRIGHTON_SHIFTKEY) dev->value += ((float) 256) / 16384; else dev->value += ((float) 1) / 16384; } break; case 0x6b: case 0xff52: /*if (dev->flags & BRIGHTON_VERTICAL) */ if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_VERTICAL) { if (dev->flags & BRIGHTON_SHIFTKEY) dev->value += ((float) 256) / 16384; else dev->value += ((float) 1) / 16384; } else { if (dev->flags & BRIGHTON_SHIFTKEY) dev->value -= ((float) 256) / 16384; else dev->value -= ((float) 1) / 16384; } break; case 0xff51: if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_VERTICAL) { if (dev->flags & BRIGHTON_SHIFTKEY) dev->value -= ((float) 2048) / 16384; else dev->value -= ((float) 32) / 16384; } else { if (dev->flags & BRIGHTON_SHIFTKEY) dev->value += ((float) 2048) / 16384; else dev->value += ((float) 32) / 16384; } break; case 0xff53: /*if (dev->flags & BRIGHTON_VERTICAL) */ if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_VERTICAL) { if (dev->flags & BRIGHTON_SHIFTKEY) dev->value += ((float) 2048) / 16384; else dev->value += ((float) 32) / 16384; } else { if (dev->flags & BRIGHTON_SHIFTKEY) dev->value -= ((float) 2048) / 16384; else dev->value -= ((float) 32) / 16384; } break; } considercallback(dev); displaymodwheel(dev); } if (event->command == BRIGHTON_MOTION) { if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_VERTICAL) { /* * Need to add in an optional central dead spot. This should be a * small fraction of either side of the bar. It will be where * position deviates from mouse location. if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_NOTCH) { } else */ if (dev->flags & BRIGHTON_CONTROLKEY) { float deltax; if (cx == -1) { sval = dev->value; cx = event->x; cy = event->y; } deltax = ((float) (event->x - cx)) / 16383.0f; dev->value = sval + deltax; } else if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_NOTCH) { /* * When we are passing zero we should hold for a bit. */ dev->value = (((float) (event->x + 5 - dev->x - (dev->width / 8))) / (dev->width - dev->width / 4)); if (dev->value > 0.6) dev->value -= 0.1; else if (dev->value < 0.4) dev->value += 0.1; else dev->value = 0.5; } else dev->value = (((float) (event->x + 5 - dev->x - (dev->width / 8))) / (dev->width - dev->width / 4)); } else { if (dev->flags & BRIGHTON_CONTROLKEY) { float deltax; if (cx == -1) { sval = dev->value; cx = event->x; cy = event->y; } deltax = ((float) (event->y - cy)) / 16383.0f; dev->value = sval + deltax; } else if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_NOTCH) { dev->value = (((float) (event->y - dev->y - (dev->height / 8))) / (dev->height - dev->height / 4)); if (dev->value > 0.6) dev->value -= 0.1; else if (dev->value < 0.4) dev->value += 0.1; else dev->value = 0.5; } else dev->value = (((float) (event->y - dev->y - (dev->height / 8))) / (dev->height - dev->height / 4)); } /* * We now need to consider rounding this to the resolution of this * device. If the max value is not 1.0 then we need to put fixed steps * into our new device value. */ if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].to != 1.0) { dev->value = (float) ((int) (dev->value * dev->bwin->app->resources[dev->panel].devlocn[dev->index].to)) / dev->bwin->app->resources[dev->panel].devlocn[dev->index].to; } considercallback(dev); displaymodwheel(dev); return(0); } if (event->command == BRIGHTON_PARAMCHANGE) { if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_REVERSE) dev->value = event->value / dev->bwin->app->resources[dev->panel].devlocn[dev->index].to; else { if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].to != 1.0) { dev->value = (dev->bwin->app->resources[dev->panel].devlocn[dev->index].to - event->value) / dev->bwin->app->resources[dev->panel].devlocn[dev->index].to; } else { dev->value = (1.0 - event->value) / dev->bwin->app->resources[dev->panel].devlocn[dev->index].to; } } considercallback(dev); displaymodwheel(dev); return(0); } return(0); } int * createModWheel(brightonWindow *bwin, brightonDevice *dev, int index, char *bitmap) { /* printf("createModWheel(%s)\n", bitmap); */ dev->destroy = destroyModWheel; dev->configure = configure; dev->index = index; dev->bwin = bwin; if (bitmap == 0) { if (dev->image) brightonFreeBitmap(bwin, dev->image); /* * Open the default bitmap */ if (bwin->app->resources[dev->panel].devlocn[dev->index].image != 0) dev->image = bwin->app->resources[dev->panel].devlocn[dev->index].image; else dev->image = brightonReadImage(bwin, "bitmaps/knobs/slider1.xpm"); } else { if (dev->image) brightonFreeBitmap(bwin, dev->image); dev->image = brightonReadImage(bwin, bitmap); } if (bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_HSCALE) { if (dev->image2) brightonFreeBitmap(bwin, dev->image2); dev->image2 = brightonReadImage(bwin, bitmap); } /* * These will force an update when we first display ourselves. */ if (bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_CENTER) dev->value = 0.5; else dev->value = 0; dev->value = 0.500001; dev->lastvalue = -1; dev->lastposition = 0; return(0); } bristol-0.60.11/libbrighton/brightonLever.c0000644000175000017500000003526411746476474015575 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* * This will be a linear potmeter. Takes a bitmap and locates it according to * input from the mouse/keyboard. Previous positions need to be unmapped, since * there is total repositioning of the image bitmap. */ #include "brightoninternals.h" int destroyLever(brightonDevice *dev) { printf("destroyLever()\n"); if (dev->image) brightonFreeBitmap(dev->bwin, dev->image); dev->image = NULL; return(0); } static int displaylever(brightonDevice *dev) { brightonIResource *panel; float displayvalue; if (dev->bwin->app->resources[dev->panel].flags & BRIGHTON_WITHDRAWN) return(0); if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_WITHDRAWN) return(0); panel = &dev->bwin->app->resources[dev->panel]; /* * Build up a smooth position for the pot. We may need to adjust this based * on the to/from values. */ if (dev->value == dev->lastvalue) return(0); displayvalue = dev->value; /* brightonFinalRender(dev->bwin, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->lastposition + dev->bwin->app->resources[dev->panel].sy, dev->width, dev->height / 4); */ /* * This seems odd, the vertical flag refers to the scrolled item, not the * direction of movement. Perhaps that should change as the direction of * movement is counterintuitive */ if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_VERTICAL) { if (dev->lastposition >= 0) { brightonDevUndraw(dev->bwin, dev->bwin->dlayer, dev->x + ((int) dev->lastposition) + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width / 8, dev->height); brightonRenderShadow(dev, 1); } dev->position = displayvalue * (dev->width - dev->width / 4); /* * Only draw fixed number of steps. Panned. Just draw it..... */ brightonStretch(dev->bwin, dev->image, dev->bwin->dlayer, (int)(dev->x + dev->position + dev->bwin->app->resources[dev->panel].sx), dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width / 8, dev->height, 1); brightonRenderShadow(dev, 0); /* * And request the panel to put this onto the respective image. */ if (dev->position > dev->lastposition) { /* * We have to render from the last position up to the current one * adding in bits for shade. */ brightonFinalRender(dev->bwin, dev->x + dev->lastposition + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->position - dev->lastposition + (dev->width >> 2), dev->height + 5); } else { brightonFinalRender(dev->bwin, dev->x + dev->position + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->lastposition - dev->position + (dev->width >> 2), dev->height + 5); } } else { brightonDevUndraw(dev->bwin, dev->bwin->dlayer, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width, dev->height + 2); brightonRenderShadow(dev, 1); dev->position = displayvalue * (dev->height - dev->height / 4); /* * Only draw fixed number of steps. Panned. Just draw it..... brightonStretch(dev->bwin, dev->image, dev->bwin->dlayer, dev->x + dev->bwin->app->resources[dev->panel].sx, (int)(dev->y + dev->position + dev->bwin->app->resources[dev->panel].sy), dev->width, dev->height / 4, 0); * * If we are greater than 1/2 then stretch the image from 3/8 up to * 5/8 + value * 3/8. * If we are less than 1/2 then stretch (bitmap2) from value * 3/8 * up to 5/8. */ if (displayvalue < 0.5) brightonStretch(dev->bwin, dev->image2 == 0? dev->image: dev->image2, dev->bwin->dlayer, dev->x + dev->bwin->app->resources[dev->panel].sx, (int) (dev->y + dev->bwin->app->resources[dev->panel].sy + (dev->height * 6 / 8) * displayvalue), dev->width, (int) (dev->height * 1 / 4 + dev->height * 6 / 8 * (0.5 - displayvalue)) - dev->height * (0.5 - displayvalue) / 2, 0); else brightonStretch(dev->bwin, dev->image, dev->bwin->dlayer, dev->x + dev->bwin->app->resources[dev->panel].sx, (int) (dev->y + dev->bwin->app->resources[dev->panel].sy + dev->height * 3 / 8) + dev->height * (displayvalue - 0.5) / 2, dev->width, dev->height * displayvalue - dev->height * 2 / 8 - dev->height * (displayvalue - 0.5) * 6 / 8, 0); brightonRenderShadow(dev, 0); /* * And request the panel to put this onto the respective image. */ brightonFinalRender(dev->bwin, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width * 2 + 1, dev->height + dev->height / 4); } dev->lastvalue = dev->value; dev->lastposition = dev->position; return(0); } static void considercallback(brightonDevice *dev) { brightonIResource *panel = &dev->bwin->app->resources[dev->panel]; float callvalue; if (dev->bwin->flags & BRIGHTON_NO_DRAW) return; if (dev->value > 1.0) dev->value = 1.0; else if (dev->value < 0) dev->value = 0.0; /* * Due to the co-ordinate system, if we do NOT have the reverse flags * then we need to reverse the value. */ if ((dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_REVERSE) == 0) callvalue = 1.0 - dev->value; else callvalue = dev->value; if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].to != 1.0) { callvalue = (callvalue * dev->bwin->app->resources[dev->panel].devlocn[dev->index].to); if ((callvalue - ((int) callvalue)) > 0.5) callvalue = ((float) ((int) callvalue) + 1); else callvalue = ((float) ((int) callvalue)); } if (dev->lastvalue != dev->value) { if (panel->devlocn[dev->index].callback) { panel->devlocn[dev->index].callback(dev->bwin, dev->panel, dev->index, callvalue); } else { if (panel->callback) panel->callback(dev->bwin, dev->panel, dev->index, callvalue); } } } static int cx, cy; static float sval; static int configure(brightonDevice *dev, brightonEvent *event) { /* printf("configureLever(%i, %f)\n", event->command, event->value); */ if (event->command == -1) return(-1); if (event->command == BRIGHTON_RESIZE) { dev->originx = event->x; dev->originy = event->y; dev->x = event->x; dev->y = event->y; dev->width = event->w; dev->height = event->h; /* * We should now rework our parent understanding of our window, since * it will have altered. NOT NECESSARY FOR SCALE. brightonPanelLocation(dev->bwin, dev->panel, dev->index, dev->x, dev->y, dev->width, dev->height); considercallback(dev); */ /* * Highlights need to be rendered dynamically in displaylever(). */ dev->lastvalue = -1; displaylever(dev); return(0); } if (event->command == BRIGHTON_KEYRELEASE) { /* * This is a little bit 'happens they work'. We should fix these key * mappings for keycodes. */ switch(event->key) { default: break; case 37: case 109: case 65508: case 65507: dev->flags &= ~BRIGHTON_CONTROLKEY; cx = cy = sval = -1; break; case 50: case 62: case 65505: dev->flags &= ~BRIGHTON_SHIFTKEY; break; } } if (event->command == BRIGHTON_BUTTONPRESS) { /* * This is hard coded, it calls back to the GUI. This is incorrect as * the callback dispatcher should be requested by the GUI. * * Perhaps the MIDI code should actually be in the same library? Why * does the GUI need to know about this? */ if (event->key == BRIGHTON_BUTTON2) brightonRegisterController(dev); return(0); } if (event->command == BRIGHTON_BUTTONRELEASE) { cx = cy = sval = -1; dev->flags &= ~BRIGHTON_CONTROLKEY; if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_CENTER) { dev->value = 0.5; considercallback(dev); displaylever(dev); } return(0); } if (event->command == BRIGHTON_KEYPRESS) { switch(event->key) { default: break; case 37: case 109: case 65508: case 65507: cx = event->x; cy = event->y; sval = dev->value; dev->flags |= BRIGHTON_CONTROLKEY; break; case 50: case 62: case 65505: dev->flags |= BRIGHTON_SHIFTKEY; break; case 0x6a: case 0xff54: if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_VERTICAL) { if (dev->flags & BRIGHTON_SHIFTKEY) dev->value -= ((float) 256) / 16384; else dev->value -= ((float) 1) / 16384; } else { if (dev->flags & BRIGHTON_SHIFTKEY) dev->value += ((float) 256) / 16384; else dev->value += ((float) 1) / 16384; } break; case 0x6b: case 0xff52: /*if (dev->flags & BRIGHTON_VERTICAL) */ if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_VERTICAL) { if (dev->flags & BRIGHTON_SHIFTKEY) dev->value += ((float) 256) / 16384; else dev->value += ((float) 1) / 16384; } else { if (dev->flags & BRIGHTON_SHIFTKEY) dev->value -= ((float) 256) / 16384; else dev->value -= ((float) 1) / 16384; } break; } considercallback(dev); displaylever(dev); } if (event->command == BRIGHTON_MOTION) { if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_VERTICAL) { /* * Need to add in an optional central dead spot. This should be a * small fraction of either side of the pot. It will be where * position deviates from mouse location. if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_NOTCH) { } else */ if (dev->flags & BRIGHTON_CONTROLKEY) { float deltax; if (cx == -1) { sval = dev->value; cx = event->x; cy = event->y; } deltax = ((float) (event->x - cx)) / 16383.0f; dev->value = sval + deltax; } else if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_NOTCH) { /* * When we are passing zero we should hold for a bit. */ dev->value = (((float) (event->x + 5 - dev->x - (dev->width / 8))) / (dev->width - dev->width / 4)); if (dev->value > 0.6) dev->value -= 0.1; else if (dev->value < 0.4) dev->value += 0.1; else dev->value = 0.5; } else dev->value = (((float) (event->x + 5 - dev->x - (dev->width / 8))) / (dev->width - dev->width / 4)); } else { if (dev->flags & BRIGHTON_CONTROLKEY) { float deltax; if (cx == -1) { sval = dev->value; cx = event->x; cy = event->y; } deltax = ((float) (event->y - cy)) / 16383.0f; dev->value = sval + deltax; } else if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_NOTCH) { dev->value = (((float) (event->y - dev->y - (dev->height / 8))) / (dev->height - dev->height / 4)); if (dev->value > 0.6) dev->value -= 0.1; else if (dev->value < 0.4) dev->value += 0.1; else dev->value = 0.5; } else dev->value = (((float) (event->y - dev->y - (dev->height / 8))) / (dev->height - dev->height / 4)); } /*printf("lever motion %i %i, %i %i, %i %i: %f\n", */ /*event->x, event->y, dev->x, dev->y, dev->width, dev->height, dev->value); */ /* * We now need to consider rounding this to the resolution of this * device. If the max value is not 1.0 then we need to put fixed steps * into our new device value. */ if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].to != 1.0) { dev->value = (float) ((int) (dev->value * dev->bwin->app->resources[dev->panel].devlocn[dev->index].to)) / dev->bwin->app->resources[dev->panel].devlocn[dev->index].to; } considercallback(dev); displaylever(dev); return(0); } if (event->command == BRIGHTON_PARAMCHANGE) { if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_REVERSE) dev->value = event->value / dev->bwin->app->resources[dev->panel].devlocn[dev->index].to; else { if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].to != 1.0) { dev->value = (dev->bwin->app->resources[dev->panel].devlocn[dev->index].to - event->value) / dev->bwin->app->resources[dev->panel].devlocn[dev->index].to; } else { dev->value = (1.0 - event->value) / dev->bwin->app->resources[dev->panel].devlocn[dev->index].to; } } considercallback(dev); displaylever(dev); return(0); } return(0); } int * createLever(brightonWindow *bwin, brightonDevice *dev, int index, char *bitmap) { /* printf("createLever(%s)\n", bitmap); */ dev->destroy = destroyLever; dev->configure = configure; dev->index = index; dev->bwin = bwin; if (bitmap == 0) { if (dev->image) brightonFreeBitmap(bwin, dev->image); /* * Open the default bitmap */ if (bwin->app->resources[dev->panel].devlocn[dev->index].image != 0) dev->image = bwin->app->resources[dev->panel].devlocn[dev->index].image; else dev->image = brightonReadImage(bwin, "bitmaps/knobs/slider1.xpm"); if (bwin->app->resources[dev->panel].devlocn[dev->index].image2 != 0) dev->image2 = brightonReadImage(bwin, bwin->template->resources[dev->panel].devlocn[dev->index].image2); } else { if (dev->image) brightonFreeBitmap(bwin, dev->image); dev->image = brightonReadImage(bwin, bitmap); if (bwin->app->resources[dev->panel].devlocn[dev->index].image2 != 0) dev->image2 = brightonReadImage(bwin, bwin->template->resources[dev->panel].devlocn[dev->index].image2); } if (bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_HSCALE) { if (dev->image2) brightonFreeBitmap(bwin, dev->image2); dev->image2 = brightonReadImage(bwin, "bitmaps/knobs/extend.xpm"); } /* * These will force an update when we first display ourselves. */ if (bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_CENTER) dev->value = 0.5; else dev->value = 0; dev->value = 0.500001; dev->lastvalue = -1; dev->lastposition = 0; return(0); } bristol-0.60.11/libbrighton/Makefile.in0000644000175000017500000005037012073601233014630 00000000000000# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = libbrighton DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LIBRARIES = $(noinst_LIBRARIES) ARFLAGS = cru libbrighton_a_AR = $(AR) $(ARFLAGS) libbrighton_a_LIBADD = am_libbrighton_a_OBJECTS = brightonBitmaps.$(OBJEXT) \ brightonButton.$(OBJEXT) brightonC.$(OBJEXT) \ brightonColorMgt.$(OBJEXT) brightonDevice.$(OBJEXT) \ brightonDispatch.$(OBJEXT) brightonDisplay.$(OBJEXT) \ brightonDisplayMgt.$(OBJEXT) brightonEventHandlers.$(OBJEXT) \ brightonHammond.$(OBJEXT) brightonInterface.$(OBJEXT) \ brightonKbd.$(OBJEXT) brightonLayer.$(OBJEXT) \ brightonPanelMgt.$(OBJEXT) brightonPic.$(OBJEXT) \ brightonRender.$(OBJEXT) brightonRotary.$(OBJEXT) \ brightonScale.$(OBJEXT) brightonShadowMgt.$(OBJEXT) \ brightonTouchpanel.$(OBJEXT) brightonVu.$(OBJEXT) \ brightonWindowMgt.$(OBJEXT) brightonXpmRead.$(OBJEXT) \ brightonMenu.$(OBJEXT) brightonLedBlock.$(OBJEXT) \ brightonHButton.$(OBJEXT) brightonLever.$(OBJEXT) \ brightonModWheel.$(OBJEXT) brightonLed.$(OBJEXT) \ brightonSlowTimer.$(OBJEXT) brightonFastTimer.$(OBJEXT) \ brightonRibbonKbd.$(OBJEXT) libbrighton_a_OBJECTS = $(am_libbrighton_a_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libbrighton_a_SOURCES) DIST_SOURCES = $(libbrighton_a_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALSA_CFLAGS = @ALSA_CFLAGS@ ALSA_LIBS = @ALSA_LIBS@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BRIGHTON_HAS_AUTOZOOM = @BRIGHTON_HAS_AUTOZOOM@ BRIGHTON_HAS_SHMIMAGE = @BRIGHTON_HAS_SHMIMAGE@ BRIGHTON_HAS_X11 = @BRIGHTON_HAS_X11@ BRIGHTON_HAS_XIMAGE = @BRIGHTON_HAS_XIMAGE@ BRIGHTON_LIBB11 = @BRIGHTON_LIBB11@ BRIGHTON_LIBX11 = @BRIGHTON_LIBX11@ BRIGHTON_LIBXEXT = @BRIGHTON_LIBXEXT@ BRIGHTON_LIBXLIBS = @BRIGHTON_LIBXLIBS@ BRIGHTON_X11_DIR = @BRIGHTON_X11_DIR@ BRISTOL_BARRIER = @BRISTOL_BARRIER@ BRISTOL_DIR = @BRISTOL_DIR@ BRISTOL_HAS_ALSA = @BRISTOL_HAS_ALSA@ BRISTOL_HAS_DRAIN = @BRISTOL_HAS_DRAIN@ BRISTOL_HAS_JACK = @BRISTOL_HAS_JACK@ BRISTOL_HAS_JACK_MIDI = @BRISTOL_HAS_JACK_MIDI@ BRISTOL_HAS_JACK_SESSION = @BRISTOL_HAS_JACK_SESSION@ BRISTOL_HAS_LIBLO = @BRISTOL_HAS_LIBLO@ BRISTOL_HAS_OSS = @BRISTOL_HAS_OSS@ BRISTOL_HAS_PA = @BRISTOL_HAS_PA@ BRISTOL_JACK_DEFAULT = @BRISTOL_JACK_DEFAULT@ BRISTOL_JACK_DEFAULT_MIDI = @BRISTOL_JACK_DEFAULT_MIDI@ BRISTOL_JACK_MULTI_CLOSE = @BRISTOL_JACK_MULTI_CLOSE@ BRISTOL_LIBPALIBS = @BRISTOL_LIBPALIBS@ BRISTOL_LIB_PA = @BRISTOL_LIB_PA@ BRISTOL_LIN_ATTACK = @BRISTOL_LIN_ATTACK@ BRISTOL_MAJOR_VERSION = @BRISTOL_MAJOR_VERSION@ BRISTOL_MICRO_VERSION = @BRISTOL_MICRO_VERSION@ BRISTOL_MINOR_VERSION = @BRISTOL_MINOR_VERSION@ BRISTOL_PA_DIR = @BRISTOL_PA_DIR@ BRISTOL_SEMAPHORE = @BRISTOL_SEMAPHORE@ BRISTOL_SEM_OPEN = @BRISTOL_SEM_OPEN@ BRISTOL_SO_VERSION = @BRISTOL_SO_VERSION@ BRISTOL_VERSION = @BRISTOL_VERSION@ BRR = @BRR@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFAULT_AUDIO_FLAG = @DEFAULT_AUDIO_FLAG@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JACK_CFLAGS = @JACK_CFLAGS@ JACK_LIBS = @JACK_LIBS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBLO_CFLAGS = @LIBLO_CFLAGS@ LIBLO_LIBS = @LIBLO_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ _BRISTOL_VOICES = @_BRISTOL_VOICES@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = foreign AM_CFLAGS = -pthread -Wall -g -I$(srcdir)/../include/brighton -I/usr/X11R6/include/ -I. -O0 @BRIGHTON_HAS_X11@ @BRIGHTON_HAS_AUTOZOOM@ noinst_LIBRARIES = libbrighton.a #libbrighton_a_LDFLAGS=-export-dynamic -version-info @BRISTOL_SO_VERSION@ @BRIGHTON_LIBXLIBS@ @BRIGHTON_LIBXLIBS@ #libbrighton_a_LIBADD= @BRIGHTON_LIBB11@ -lm libbrighton_a_SOURCES = brightonBitmaps.c brightonButton.c brightonC.c brightonColorMgt.c brightonDevice.c brightonDispatch.c brightonDisplay.c brightonDisplayMgt.c brightonEventHandlers.c brightonHammond.c brightonInterface.c brightonKbd.c brightonLayer.c brightonPanelMgt.c brightonPic.c brightonRender.c brightonRotary.c brightonScale.c brightonShadowMgt.c brightonTouchpanel.c brightonVu.c brightonWindowMgt.c brightonXpmRead.c brightonkeymappings.h brightonMenu.c brightonLedBlock.c brightonHButton.c brightonLever.c brightonModWheel.c brightonLed.c brightonSlowTimer.c brightonFastTimer.c brightonRibbonKbd.c all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign libbrighton/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign libbrighton/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libbrighton.a: $(libbrighton_a_OBJECTS) $(libbrighton_a_DEPENDENCIES) $(EXTRA_libbrighton_a_DEPENDENCIES) -rm -f libbrighton.a $(libbrighton_a_AR) libbrighton.a $(libbrighton_a_OBJECTS) $(libbrighton_a_LIBADD) $(RANLIB) libbrighton.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonBitmaps.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonButton.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonC.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonColorMgt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonDevice.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonDispatch.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonDisplay.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonDisplayMgt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonEventHandlers.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonFastTimer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonHButton.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonHammond.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonInterface.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonKbd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonLayer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonLed.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonLedBlock.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonLever.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonMenu.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonModWheel.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonPanelMgt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonPic.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonRender.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonRibbonKbd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonRotary.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonScale.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonShadowMgt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonSlowTimer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonTouchpanel.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonVu.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonWindowMgt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brightonXpmRead.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLIBRARIES ctags distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am tags uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: bristol-0.60.11/libbrighton/brightonVu.c0000644000175000017500000002001011746476474015071 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* * This will be a VU meter set, 16 LED sets for different tracks. * * We are probably going to cheat on the implementation: The backdrop will be * an array of LEDs. We will produce a "blueprint" bitmap that will mask in/out * the backdrop. * * This was written with internal brighton bitmaps, but to improve efficiency * of these rather slow access routines (XDrawPixmap, etc), am going to build * another extrapolated access to the X11 PixMap structures. These will use * native sizes rather than scaling the results. */ #include "brightoninternals.h" int destroyVu(brightonDevice *dev) { printf("destroyVu()\n"); if (dev->image) brightonFreeBitmap(dev->bwin, dev->image); if (dev->image2) brightonFreeBitmap(dev->bwin, dev->image2); dev->image = NULL; dev->image2 = NULL; return(0); } static int displayvu(brightonDevice *dev) { brightonIResource *panel; /* printf("displayvu()\n"); */ if (dev->bwin->app->resources[dev->panel].flags & BRIGHTON_WITHDRAWN) return(0); panel = &dev->bwin->app->resources[dev->panel]; /* * Only draw fixed number of steps. */ brightonStretch(dev->bwin, dev->image2, dev->bwin->dlayer, dev->x + dev->bwin->app->resources[dev->panel].sx, (int)(dev->y + dev->bwin->app->resources[dev->panel].sy), dev->width, dev->height, 0); brightonFinalRender(dev->bwin, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width * 2, (dev->height >> 2) + 1 + (dev->width >> 1)); return(0); } static void pbm(brightonDevice *dev, register int o, register int c) { register int *pixels2 = dev->image2->pixels; /* dev->image2->pixels[o + 0] = dev->image->pixels[o + 0]; dev->image2->pixels[o + 1] = dev->image->pixels[o + 1]; dev->image2->pixels[o + 2] = dev->image->pixels[o + 2]; dev->image2->pixels[o + 3] = dev->image->pixels[o + 3]; dev->image2->pixels[o + 4] = dev->image->pixels[o + 4]; dev->image2->pixels[o + 5] = dev->image->pixels[o + 5]; dev->image2->pixels[o + 6] = dev->image->pixels[o + 6]; dev->image2->pixels[o + 7] = dev->image->pixels[o + 7]; dev->image2->pixels[o + 8] = dev->image->pixels[o + 8]; dev->image2->pixels[o + 9] = dev->image->pixels[o + 9]; */ pixels2[o + 0] = c; pixels2[o + 1] = c; pixels2[o + 2] = c; pixels2[o + 3] = c; pixels2[o + 4] = c; pixels2[o + 5] = c; pixels2[o + 6] = c; pixels2[o + 7] = c; pixels2[o + 8] = c; pixels2[o + 9] = c; } static void fbm(brightonDevice *dev) { register int i, j; register int *pixels2 = dev->image2->pixels; /* * Param indicates the values on the points. Just deal with one for now * * Bitmap image 2 is all black. We are going to cut a few holes in it. */ for (i = 63; i > 0; --i) { j = i * 160; pixels2[j + 0] = dev->image->pixels[j + 0]; pixels2[j + 1] = dev->image->pixels[j + 1]; pixels2[j + 2] = dev->image->pixels[j + 2]; pixels2[j + 3] = dev->image->pixels[j + 3]; pixels2[j + 4] = dev->image->pixels[j + 4]; pixels2[j + 5] = dev->image->pixels[j + 5]; pixels2[j + 6] = dev->image->pixels[j + 6]; pixels2[j + 7] = dev->image->pixels[j + 7]; pixels2[j + 8] = dev->image->pixels[j + 8]; pixels2[j + 9] = dev->image->pixels[j + 9]; pixels2[j + 20] = dev->image->pixels[j + 0]; pixels2[j + 21] = dev->image->pixels[j + 1]; pixels2[j + 22] = dev->image->pixels[j + 2]; pixels2[j + 23] = dev->image->pixels[j + 3]; pixels2[j + 24] = dev->image->pixels[j + 4]; pixels2[j + 25] = dev->image->pixels[j + 5]; pixels2[j + 26] = dev->image->pixels[j + 6]; pixels2[j + 27] = dev->image->pixels[j + 7]; pixels2[j + 28] = dev->image->pixels[j + 8]; pixels2[j + 29] = dev->image->pixels[j + 9]; pixels2[j + 40] = dev->image->pixels[j + 0]; pixels2[j + 41] = dev->image->pixels[j + 1]; pixels2[j + 42] = dev->image->pixels[j + 2]; pixels2[j + 43] = dev->image->pixels[j + 3]; pixels2[j + 44] = dev->image->pixels[j + 4]; pixels2[j + 45] = dev->image->pixels[j + 5]; pixels2[j + 46] = dev->image->pixels[j + 6]; pixels2[j + 47] = dev->image->pixels[j + 7]; pixels2[j + 48] = dev->image->pixels[j + 8]; pixels2[j + 49] = dev->image->pixels[j + 9]; pixels2[j + 90] = dev->image->pixels[j + 0]; pixels2[j + 91] = dev->image->pixels[j + 1]; pixels2[j + 92] = dev->image->pixels[j + 2]; pixels2[j + 93] = dev->image->pixels[j + 3]; pixels2[j + 94] = dev->image->pixels[j + 4]; pixels2[j + 95] = dev->image->pixels[j + 5]; pixels2[j + 96] = dev->image->pixels[j + 6]; pixels2[j + 97] = dev->image->pixels[j + 7]; pixels2[j + 98] = dev->image->pixels[j + 8]; pixels2[j + 99] = dev->image->pixels[j + 9]; } } static void cbm(brightonDevice *dev) { int i, j, c; /* * Param indicates the values on the points. Just deal with one for now * * Bitmap image 2 is all black. We are going to cut a few holes in it. */ for (i = 64 - dev->value--; i > 0; i--) { j = i * 160; c = dev->image2->colormap[0]; /* pbm(dev, j, c); */ pbm(dev, j + 20, c); /* pbm(dev, j + 20, c); */ /* pbm(dev, j + 40, c); */ /* pbm(dev, j + 90, c); */ } } static int configure(brightonDevice *dev, brightonEvent *event) { printf("configureVu()\n"); if (event->command == -1) return(-1); if (event->command == BRIGHTON_RESIZE) { dev->originx = event->x; dev->originy = event->y; dev->x = event->x; dev->y = event->y; dev->width = event->w; dev->height = event->h; printf("vuMeter width = %i, height = %i\n", dev->width, dev->height); /* * We should now delete our existing bitmap and create a new one for * the size of this window. */ /* * We should now rework our parent understanding of our window, since * it will have altered. NOT NECESSARY FOR SCALE. brightonPanelLocation(dev->bwin, dev->panel, dev->index, dev->x, dev->y, dev->width, dev->height); */ displayvu(dev); return(0); } if (event->command == BRIGHTON_KEYRELEASE) { } if (event->command == BRIGHTON_BUTTONRELEASE) { } if (event->command == BRIGHTON_KEYPRESS) { } if (event->command == BRIGHTON_MOTION) { } if ((event->command == BRIGHTON_PARAMCHANGE) || (event->command == BRIGHTON_KEYPRESS)) { cbm(dev); cbm(dev); cbm(dev); cbm(dev); if (dev->value <= 1) { dev->value = 64; fbm(dev); } displayvu(dev); return(0); } return(0); } int * createVu(brightonWindow *bwin, brightonDevice *dev, int index, char *bitmap) { printf("createVu(%s)\n", bitmap); dev->destroy = destroyVu; dev->configure = configure; dev->index = index; dev->bwin = bwin; if (bitmap == 0) { if (dev->image) brightonFreeBitmap(bwin, dev->image); if (dev->image2) brightonFreeBitmap(bwin, dev->image2); /* * Open the default bitmap */ if (bwin->app->resources[dev->panel].devlocn[dev->index].image != 0) dev->image = bwin->app->resources[dev->panel].devlocn[dev->index].image; if (bwin->app->resources[dev->panel].devlocn[dev->index].image2 != 0) dev->image2 = bwin->app->resources[dev->panel].devlocn[dev->index].image2; } else { if (dev->image) brightonFreeBitmap(bwin, dev->image); dev->image = brightonReadImage(bwin, bitmap); if (bwin->app->resources[dev->panel].devlocn[dev->index].image2 != 0) dev->image2 = bwin->app->resources[dev->panel].devlocn[dev->index].image2; } /* * These will force an update when we first display ourselves. */ dev->value = 64; fbm(dev); return(0); } bristol-0.60.11/libbrighton/Makefile.am0000755000175000017500000000171412073330071014617 00000000000000AUTOMAKE_OPTIONS = foreign AM_CFLAGS = -pthread -Wall -g -I$(srcdir)/../include/brighton -I/usr/X11R6/include/ -I. -O0 @BRIGHTON_HAS_X11@ @BRIGHTON_HAS_AUTOZOOM@ noinst_LIBRARIES = libbrighton.a #libbrighton_a_LDFLAGS=-export-dynamic -version-info @BRISTOL_SO_VERSION@ @BRIGHTON_LIBXLIBS@ @BRIGHTON_LIBXLIBS@ #libbrighton_a_LIBADD= @BRIGHTON_LIBB11@ -lm libbrighton_a_SOURCES = brightonBitmaps.c brightonButton.c brightonC.c brightonColorMgt.c brightonDevice.c brightonDispatch.c brightonDisplay.c brightonDisplayMgt.c brightonEventHandlers.c brightonHammond.c brightonInterface.c brightonKbd.c brightonLayer.c brightonPanelMgt.c brightonPic.c brightonRender.c brightonRotary.c brightonScale.c brightonShadowMgt.c brightonTouchpanel.c brightonVu.c brightonWindowMgt.c brightonXpmRead.c brightonkeymappings.h brightonMenu.c brightonLedBlock.c brightonHButton.c brightonLever.c brightonModWheel.c brightonLed.c brightonSlowTimer.c brightonFastTimer.c brightonRibbonKbd.c bristol-0.60.11/libbrighton/brightonButton.c0000644000175000017500000003603511746476474015770 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* * This will be a simple pushbutton, initially it will function as 2 throw, * but may incorporate capabilities to support pure contact switches. * radio buttons will probably have to be separate. */ #include #include "brightoninternals.h" extern int brightonPanelLocation(); int destroyButton(brightonDevice *dev) { printf("destroyButton()\n"); if (dev->image) brightonFreeBitmap(dev->bwin, dev->image); if (dev->image2) brightonFreeBitmap(dev->bwin, dev->image2); dev->image = NULL; dev->image2 = NULL; return(0); } static void displaybutton(brightonDevice *dev) { int flags = dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags; if (dev->bwin->app->resources[dev->panel].flags & BRIGHTON_WITHDRAWN) return; if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_WITHDRAWN) return; /* * This is not needed except for moving parts - sliders primarily, but * also touch panels. Rotary and buttons are located and stay that way. */ if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_REDRAW) brightonDevUndraw(dev->bwin, dev->bwin->dlayer, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + + dev->bwin->app->resources[dev->panel].sy, dev->width, dev->height); brightonRenderShadow(dev, 1); if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & (BRIGHTON_THREEWAY|BRIGHTON_FIVEWAY)) { if ((dev->value >= 0) && (dev->value <= 0.5)) { brightonStretch(dev->bwin, dev->imagec, dev->bwin->dlayer, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width, dev->height, flags); } else if ((dev->value > 0.5) && (dev->value <= 1.5)) { brightonStretch(dev->bwin, dev->image2, dev->bwin->dlayer, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width, dev->height, flags); } else if ((dev->value > 1.5) && (dev->value <= 2.5)) { brightonStretch(dev->bwin, dev->image, dev->bwin->dlayer, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width, dev->height, flags); } else if ((dev->value > 2.5) && (dev->value <= 3.5)) { brightonStretch(dev->bwin, dev->image3, dev->bwin->dlayer, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width, dev->height, flags); } else if ((dev->value > 3.5) && (dev->value <= 4.5)) { brightonStretch(dev->bwin, dev->image4, dev->bwin->dlayer, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width, dev->height, flags); } } else if (dev->image2) { if (dev->value) brightonStretch(dev->bwin, dev->image2, dev->bwin->dlayer, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width, dev->height, dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags); else brightonStretch(dev->bwin, dev->image, dev->bwin->dlayer, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width, dev->height, dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags); } else { if ((~dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_CHECKBUTTON)) { if (dev->value == 0) flags = 0; else flags = BRIGHTON_REVERSE|BRIGHTON_HALF_REVERSE; flags |= (BRIGHTON_VERTICAL & dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags); } brightonStretch(dev->bwin, dev->image, /*dev->bwin->app->resources[dev->panel].canvas, */ dev->bwin->dlayer, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width, dev->height, flags); } brightonRenderShadow(dev, 0); brightonFinalRender(dev->bwin, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width, dev->height); dev->lastvalue = dev->value; dev->lastposition = dev->position; } /* * This will go into brighton render */ static int renderHighlights(brightonWindow *bwin, brightonDevice *dev) { float d, streak, dx, dy; brightonCoord p[8]; if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & (BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN)) return(0); dx = dev->x - bwin->lightX; dy = dev->y - bwin->lightY; d = sqrt((double) (dx * dx + dy * dy)); streak = (dev->width * 2.0 * d / bwin->lightH) / (1 - dev->width * 2.0 / bwin->lightH); p[0].x = dev->x; p[0].y = dev->y + dev->height; p[1].x = dev->x + dev->width; p[1].y = dev->y; p[2].x = dev->x + dx * streak / d; p[2].y = dev->y + dy * streak / d; /* XFillPolygon(bwin->display, bwin->background, bwin->cheap_shade, */ /* (XPoint *) &p, 3, Complex, CoordModeOrigin); */ return(0); } static int considercallback(brightonDevice *dev) { brightonIResource *panel = &dev->bwin->app->resources[dev->panel]; if (dev->bwin->flags & BRIGHTON_NO_DRAW) return(0); if ((dev->lastvalue != dev->value) || (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_CHECKBUTTON)) { if (panel->devlocn[dev->index].callback) { panel->devlocn[dev->index].callback(dev->bwin, dev->panel, dev->index, dev->value); } else { if (panel->callback) panel->callback(dev->bwin, dev->panel, dev->index, dev->value); } } return(0); } static int configure(brightonDevice *dev, brightonEvent *event) { /* printf("configureButton(%i, %f)\n", dev->index, dev->value); */ /* * We had to do this for some withdrawn panels if (dev->bwin->app->resources[dev->panel].flags & BRIGHTON_WITHDRAWN) return(0); */ if (event->command == -1) return(-1); if (event->command == BRIGHTON_RESIZE) { dev->x = event->x; dev->y = event->y; dev->width = event->w; dev->height = event->h; /* * We should consider altering the locations structure, so that * event dispatching is correct. */ if ((dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_CHECKBUTTON) == 0) considercallback(dev); brightonPanelLocation(dev->bwin, dev->panel, dev->index, dev->x, dev->y, dev->width, dev->height); /* * We need to build in some shadow, to prevent the button from looking * like it is hanging in mid air. */ renderHighlights(dev->bwin, dev); dev->lastvalue = -1; displaybutton(dev); return(0); } if (event->command == BRIGHTON_LEAVE) { if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_CHECKBUTTON) { dev->value = 0; displaybutton(dev); } return(0); } if (event->command == BRIGHTON_ENTER) { if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_CHECKBUTTON) { dev->value = 1; displaybutton(dev); } return(0); } if (event->command == BRIGHTON_BUTTONRELEASE) { if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_CHECKBUTTON) { dev->value = 0; displaybutton(dev); if ((event->x >= dev->x) && (event->y >= dev->y) && (event->x < (dev->x + dev->width)) && (event->y < (dev->y + dev->height))) considercallback(dev); } else { brightonIResource *panel = &dev->bwin->app->resources[dev->panel]; if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_NO_TOGGLE) { if (dev->value == 0) dev->value = panel->devlocn[dev->index].to; else dev->value = panel->devlocn[dev->index].from; considercallback(dev); displaybutton(dev); } } return(0); } if (event->command == BRIGHTON_BUTTONPRESS) { brightonIResource *panel = &dev->bwin->app->resources[dev->panel]; if (event->key == BRIGHTON_BUTTON2) { brightonRegisterController(dev); return(0); } /* if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_CHECKBUTTON) return(0); */ if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_THREEWAY) { if (--dev->value < 0) dev->value = 2; } else if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_FIVEWAY) { if (--dev->value < 0) dev->value = 4; } else if (dev->value == 0) dev->value = panel->devlocn[dev->index].to; else dev->value = panel->devlocn[dev->index].from; if ((dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_CHECKBUTTON) == 0) considercallback(dev); displaybutton(dev); return(0); } if (event->command == BRIGHTON_KEYPRESS) { brightonIResource *panel = &dev->bwin->app->resources[dev->panel]; if (event->key == 0x20) { if (dev->value == 0) dev->value = panel->devlocn[dev->index].to; else dev->value = panel->devlocn[dev->index].from; considercallback(dev); displaybutton(dev); return(0); } /* * If this was not a space bar which we use to activate and de-activate * any arbitrary button then it could be that we pressed some key that * can otherwise be interpretted. * This is awkward since here we are in a single button and I would * like to use keypress to emulate a piano keyboard from the computer. * These events would have to be delivered to the parent, not to the * device, and the parent would then decide to which device the event * should be delivered. */ } if (event->command == BRIGHTON_KEYRELEASE) { /* * This is just to clear the event and repaint the key, we should not * be bothered with the callback. */ if (event->key == 0x20) { if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_CHECKBUTTON) { dev->value = 0; displaybutton(dev); /* considercallback(dev); */ } } return(0); } if (event->command == BRIGHTON_PARAMCHANGE) { dev->value = event->value; dev->lastvalue = -1; if ((dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_CHECKBUTTON) == 0) considercallback(dev); displaybutton(dev); return(0); } return(0); } int * createButton(brightonWindow *bwin, brightonDevice *dev, int index, char *bitmap) { brightonIResource *panel = &bwin->app->resources[dev->panel]; /*printf("createButton(%s, %x)\n", bitmap, panel->devlocn[dev->index].image); */ dev->destroy = destroyButton; dev->configure = configure; dev->bwin = bwin; if (bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_THREEWAY) { char path[256]; if (dev->image) brightonFreeBitmap(bwin, dev->image); if (dev->image2) brightonFreeBitmap(bwin, dev->image2); if (dev->imagec) brightonFreeBitmap(bwin, dev->imagec); sprintf(path, "bitmaps/buttons/%s1.xpm", bitmap); if ((dev->image = brightonReadImage(bwin, path)) != 0) { sprintf(path, "bitmaps/buttons/%s2.xpm", bitmap); if ((dev->image2 = brightonReadImage(bwin, path)) == 0) dev->image2 = brightonReadImage(bwin, "bitmaps/buttons/sw4.xpm"); sprintf(path, "bitmaps/buttons/%s3.xpm", bitmap); if ((dev->imagec = brightonReadImage(bwin, path)) == 0) dev->image2 = brightonReadImage(bwin, "bitmaps/buttons/sw4.xpm"); } else { dev->image = brightonReadImage(bwin, "bitmaps/buttons/sw5.xpm"); dev->image2 = brightonReadImage(bwin, "bitmaps/buttons/sw4.xpm"); dev->imagec = brightonReadImage(bwin, "bitmaps/buttons/sw3.xpm"); } } else if (bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_FIVEWAY) { char path[256]; if (dev->image) brightonFreeBitmap(bwin, dev->image); if (dev->image2) brightonFreeBitmap(bwin, dev->image2); if (dev->image3) brightonFreeBitmap(bwin, dev->image3); if (dev->image4) brightonFreeBitmap(bwin, dev->image4); if (dev->imagec) brightonFreeBitmap(bwin, dev->imagec); sprintf(path, "bitmaps/buttons/%s1.xpm", bitmap); if ((dev->image = brightonReadImage(bwin, path)) != 0) { sprintf(path, "bitmaps/buttons/%s2.xpm", bitmap); if ((dev->image2 = brightonReadImage(bwin, path)) == 0) dev->image2 = brightonReadImage(bwin, "bitmaps/buttons/sw2.xpm"); sprintf(path, "bitmaps/buttons/%s3.xpm", bitmap); if ((dev->image3 = brightonReadImage(bwin, path)) == 0) dev->image3 = brightonReadImage(bwin, "bitmaps/buttons/sw3.xpm"); sprintf(path, "bitmaps/buttons/%s4.xpm", bitmap); if ((dev->image4 = brightonReadImage(bwin, path)) == 0) dev->image4 = brightonReadImage(bwin, "bitmaps/buttons/sw4.xpm"); sprintf(path, "bitmaps/buttons/%s5.xpm", bitmap); if ((dev->imagec = brightonReadImage(bwin, path)) == 0) dev->imagec = brightonReadImage(bwin, "bitmaps/buttons/sw5.xpm"); } else { dev->image = brightonReadImage(bwin, "bitmaps/buttons/sw1.xpm"); dev->image2 = brightonReadImage(bwin, "bitmaps/buttons/sw2.xpm"); dev->image3 = brightonReadImage(bwin, "bitmaps/buttons/sw3.xpm"); dev->image4 = brightonReadImage(bwin, "bitmaps/buttons/sw4.xpm"); dev->imagec = brightonReadImage(bwin, "bitmaps/buttons/sw5.xpm"); } } else if (bitmap == NULL) { if (dev->image) brightonFreeBitmap(bwin, dev->image); /* * If we have been passed a specific image name for this device then * use it. */ if (panel->devlocn[dev->index].image != 0) dev->image = bwin->app->resources[dev->panel].devlocn[dev->index].image; else dev->image = brightonReadImage(bwin, "bitmaps/buttons/rockerred.xpm"); if (panel->devlocn[dev->index].image2 != 0) dev->image2 = bwin->app->resources[dev->panel].devlocn[dev->index].image2; else dev->image = brightonReadImage(bwin, "bitmaps/buttons/rockerred.xpm"); } else { if (dev->image) brightonFreeBitmap(bwin, dev->image); if (panel->devlocn[dev->index].image != 0) dev->image = bwin->app->resources[dev->panel].devlocn[dev->index].image; else dev->image = brightonReadImage(bwin, bitmap); if (dev->image2) brightonFreeBitmap(bwin, dev->image2); dev->image2 = brightonReadImage(bwin, bwin->template->resources[dev->panel].devlocn[dev->index].image2); /* if (panel->devlocn[dev->index].image2 != 0) dev->image2 = bwin->app->resources[dev->panel].devlocn[dev->index].image2; */ } /* * These will force an update when we first display ourselves. */ dev->value = 0; dev->lastvalue = -1; dev->lastposition = -1; return(0); } bristol-0.60.11/libbrighton/brightonRender.c0000644000175000017500000012017211746476474015730 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include #include #include "brightonX11.h" /* * This is for some basic profiling of some of the routines, needed to optimise * the codebase. */ #define STATS //#define STATS2 #ifdef STATS #include struct timeval tstart, tend; #endif #include "brightoninternals.h" #define SQRT_TAB_SIZE 128 double sqrttab[SQRT_TAB_SIZE][SQRT_TAB_SIZE]; extern int cacheInsertColor(unsigned short, unsigned short, unsigned short, int); void initSqrtTab() { int i, j; for (j = 0 ; j < SQRT_TAB_SIZE; j++) { for (i = 0 ; i < SQRT_TAB_SIZE; i++) { if ((sqrttab[i][j] = sqrt((double) (i * i + j * j))) == 0) sqrttab[i][j] = 0.0001; } } } int brightonInitBitmap(brightonBitmap *bitmap, int value) { register int pindex, total = bitmap->width * bitmap->height; for (pindex = 0; pindex < total; pindex++) bitmap->pixels[pindex] = value; return(0); } /* * This is dead slow. */ int brightonWorldChanged(brightonWindow *bwin, int width, int height) { if (bwin->flags & BRIGHTON_DEBUG) printf("brightonWorldChanged(%i %i %i %i) %i %i\n", width, height, bwin->width, bwin->height, bwin->template->width, bwin->template->height); /* * We need to maintain aspect ratio. First take the new width, and build * a corresponding height. If the height is outside the realms of the * display then do the reverse. If, however, the width and height are * within a reasonable amount of the desired aspect ratio, just use * them. * * 110908 - FR 2243291 - Add an option to override the checks for aspect * ratio. Required by some window managers to prevent permanant redrawing * of the window however it results in some pretty gruesome images if the * ratio is not a reasonable approximation of the original. * * There is some pretty ugly resizing stuff here. Going to propose the app * will lose aspect ratio as resizing takes place, then on Focus change * events it will see if aspect should be maintained and do a single resize * at that point. */ if (bwin->flags & BRIGHTON_DEBUG) printf("%i %i, %i %i\n", width, height, bwin->width, bwin->height); if (bwin->height != height) bwin->flags |= _BRIGHTON_SET_HEIGHT; /* This is the KDE Postage Stamp fix */ if ((height < 30) || (width < 50)) { brightonRequestResize(bwin, bwin->template->width, bwin->template->height); return(0); } bwin->width = width; bwin->height = height; brightonFreeBitmap(bwin, bwin->canvas); brightonFreeBitmap(bwin, bwin->render); brightonFreeBitmap(bwin, bwin->dlayer); brightonFreeBitmap(bwin, bwin->slayer); brightonFreeBitmap(bwin, bwin->tlayer); brightonFreeBitmap(bwin, bwin->mlayer); bwin->canvas = brightonCreateNamedBitmap(bwin, bwin->width, bwin->height, "canvas"); bwin->dlayer = brightonCreateNamedBitmap(bwin, bwin->width, bwin->height, "dlayer"); bwin->slayer = brightonCreateNamedBitmap(bwin, bwin->width, bwin->height, "slayer"); bwin->tlayer = brightonCreateNamedBitmap(bwin, bwin->width, bwin->height, "tlayer"); bwin->mlayer = brightonCreateNamedBitmap(bwin, bwin->width, bwin->height, "mlayer"); bwin->render = brightonCreateNamedBitmap(bwin, bwin->width, bwin->height, "render"); if (bwin->display->flags & BRIGHTON_ANTIALIAS_3) { brightonFreeBitmap(bwin, bwin->renderalias); bwin->renderalias = brightonCreateBitmap(bwin, bwin->width, bwin->height); } if (bwin->opacity == 0) bwin->opacity = 0.5f; /* * Our device and shadow layer need to be initialised with -1 */ brightonInitBitmap(bwin->dlayer, -1); brightonInitBitmap(bwin->slayer, -1); brightonInitBitmap(bwin->tlayer, -1); brightonInitBitmap(bwin->mlayer, -1); //placebox(bwin, bwin->mlayer, 100, 100, 100, 200); bwin->lightX = -1000; bwin->lightY = -1000; bwin->lightH = 3000; bwin->lightI = 0.95; /* * We now have a configured size. We need to render the surface onto the * window background, and render the image if we have any configured * blueprints. These are rendered onto our canvas. */ if (bwin->app->flags & BRIGHTON_STRETCH) brightonStretch(bwin, bwin->surface, bwin->canvas, 0, 0, bwin->width, bwin->height, bwin->app->flags); else brightonTesselate(bwin, bwin->surface, bwin->canvas, 0, 0, bwin->width, bwin->height, bwin->app->flags); if ((bwin->display->flags & BRIGHTON_ANTIALIAS_5) || (bwin->display->flags & BRIGHTON_ANTIALIAS_3)) brightonStretchAlias(bwin, bwin->image, bwin->canvas, 0, 0, bwin->width, bwin->height, 0.8); else brightonStretch(bwin, bwin->image, bwin->canvas, 0, 0, bwin->width, bwin->height, 0); brightonRender(bwin, bwin->canvas, bwin->render, 0, 0, bwin->width, bwin->height, 0); bwin->flags |= BRIGHTON_NO_DRAW; if (bwin->app) { int panel; brightonEvent event; for (panel = 0; panel < bwin->app->nresources; panel++) { /* * We need to configure the device to resize itself */ event.command = BRIGHTON_RESIZE; event.x = (int) bwin->app->resources[panel].x * bwin->width / 1000; event.y = (int) bwin->app->resources[panel].y * bwin->height / 1000; event.w = (int) bwin->app->resources[panel].width * bwin->width / 1000; event.h = (int) bwin->app->resources[panel].height * bwin->height / 1000; bwin->app->resources[panel].configure(bwin, &bwin->app->resources[panel], &event); } } bwin->flags &= ~BRIGHTON_NO_DRAW; brightonRePlace(bwin); brightonFinalRender(bwin, 0, 0, bwin->width, bwin->height); /* * Call the application to see if it wants to alter anything after the * world changed. */ if (bwin->template->configure) bwin->template->configure(bwin); return(0); } int brightonColorQuality(brightonWindow *bwin, int quality) { if ((bwin->quality = quality) < 2) bwin->quality = 2; else if (bwin->quality > 8) bwin->quality = 8; return(0); } int brightonOpacity(brightonWindow *bwin, float opacity) { if ((bwin->opacity = opacity) < 0.01f) bwin->opacity = 0.01f; else if (bwin->opacity > 1.0f) bwin->opacity = 1.0f; return(0); } void brightonLogo(brightonWindow *bwin) { bwin->flags |= BRIGHTON_NO_LOGO; } static int antialias(brightonWindow *bwin, brightonBitmap *b, int x, int y, float primary) { register int nr, ng, nb, dy, color = 0, cpre, cnext, pindex, cpy, cny; register brightonPalette *palette = bwin->display->palette; float secondary; if ((primary <= 0) || (primary > 1.0)) return(color); if ((x == 0) || (x >= bwin->width - 1) || (y == 0) || (y >= bwin->height - 1)) return(0); dy = x + y * bwin->width; cpy = b->pixels[x + (y - 1) * bwin->width]; cny = b->pixels[x + (y + 1) * bwin->width]; cpre = b->pixels[dy - 1]; color = b->pixels[dy]; cnext = b->pixels[dy + 1]; /* * Generally the palette for any color C will be specified as * * C * aa + (4C * (1 - n)/4) * * This would work if aa was a floating point from 0 to 1.0. To do this * requires two options, one of which is a flag to state that we are doing * either texture or full image antialiasing and the value we want to use. * * For now we have a couple of values for each and they use predefined * levels. As the value tends to one the antialiasing lessens, ie, we take * more of the target pixel and less smoothing from the surrounding ones. * This is counter intuitive in my opinion, I think the smoothing should * increase as this value does, hence we will make it reciprocal. * * Values greater that 0.5 are actually counter productive, reducing the * definition of the target pixel to the benefit of the surrounding ones. */ secondary = (1.0 - primary) / 4.0; nr = (int) ( ((float) palette[color].red) * primary + ((float) (palette[cpy].red + palette[cny].red + palette[cpre].red + palette[cnext].red)) * secondary); ng = (int) ( ((float) palette[color].green) * primary + ((float) (palette[cpy].green + palette[cny].green + palette[cpre].green + palette[cnext].green)) * secondary); nb = (int) ( ((float) palette[color].blue) * primary + ((float) (palette[cpy].blue + palette[cny].blue + palette[cpre].blue + palette[cnext].blue)) * secondary); /* * We want to be flexible on matches otherwise we use excessive colors and * slow the GUI down */ if ((pindex = brightonFindColor(palette, bwin->cmap_size, nr, ng, nb, bwin->quality)) >= 0) { palette[pindex].uses++; return(pindex); } /* * If we have no free colors, then palette[0] is the default */ if ((pindex = brightonFindFreeColor(palette, bwin->cmap_size)) < 0) return(0); palette[pindex].red = nr; palette[pindex].green = ng; palette[pindex].blue = nb; palette[pindex].uses++; palette[pindex].flags &= ~BRIGHTON_INACTIVE_COLOR; palette[pindex].uses++; /* * Set up the cache. */ cacheInsertColor(nr, ng, nb, pindex); return(pindex); } static void brightonAliasArea(brightonWindow *bwin, int x, int y, int width, int height) { register int i, j, dy, aa = 1; register int *dest; if (bwin->renderalias == NULL) bwin->renderalias = brightonCreateBitmap(bwin, bwin->width, bwin->height); dest = bwin->renderalias->pixels; aa = bwin->display->flags & BRIGHTON_ANTIALIAS_3? 1:2; if (y == 0) { y += 1; height -= 1; } if (x == 0) { x += 1; width -= 1; } for (j = y; j < (y + height); j++) { if (j >= (bwin->height - 1)) break; dy = j * bwin->width; for (i = x; i < (x + width); i++) { if (i >= (bwin->width - 1)) break; dest[i + dy] = antialias(bwin, bwin->render, i, j, bwin->antialias); } } } static int makeMonoChrome(brightonWindow *bwin, int dest) { register int r, g, b; register int pindex; register brightonPalette *palette = bwin->display->palette; r = palette[dest].red; g = palette[dest].green; b = palette[dest].blue; /* * Greyscale tests. * 1 is average, * 2 is min * 3 is max */ switch (bwin->grayscale) { case 1: r = (r + g + b) / 3; g = b = r; break; case 2: r = (r + g + b) / 6; g = b = r; break; case 3: r = (r + g + b) / 12; g = b = r; break; case 4: if (r < g) { r = r < b? r:b; } else { r = g < b? g:b; } g = b = r; break; case 5: if (r > g) { r = r > b? r:b; } else { r = g > b? g:b; } g = b = r; break; } /* * We want to be flexible on matches otherwise we use excessive colors and * slow the GUI down */ if ((pindex = brightonFindColor(palette, bwin->cmap_size, r, g, b, bwin->quality - 2)) >= 0) { palette[pindex].uses++; return(pindex); } /* * If we have no free colors, then palette[0] is the default */ if ((pindex = brightonFindFreeColor(palette, bwin->cmap_size)) < 0) return(0); palette[pindex].red = r; palette[pindex].green = g; palette[pindex].blue = b; palette[pindex].uses++; palette[pindex].flags &= ~BRIGHTON_INACTIVE_COLOR; palette[pindex].uses++; cacheInsertColor(r, g, b, pindex); return(pindex); } static int makeTransparent(brightonWindow *bwin, int dest, int tlayer, float opacity) { register int nr, ng, nb; register int pindex; register brightonPalette *palette = bwin->display->palette; if (opacity >= 0.99) return(tlayer); /* * Take the color selections between the two values, the more opaque the * greater the more of the selected value will be taken from the top patch * layer. */ nr = (int) ( (((float) (palette[dest].red)) * (1.0f - opacity)) + (((float) (palette[tlayer].red)) * opacity)); ng = (int) ( (((float) (palette[dest].green)) * (1.0f - opacity)) + (((float) (palette[tlayer].green)) * opacity)); nb = (int) ( (((float) (palette[dest].blue)) * (1.0f - opacity)) + (((float) (palette[tlayer].blue)) * opacity)); /* * We want to be flexible on matches otherwise we use excessive colors and * slow the GUI down */ if ((pindex = brightonFindColor(palette, bwin->cmap_size, nr, ng, nb, bwin->quality - 2)) >= 0) { palette[pindex].uses++; return(pindex); } /* * If we have no free colors, then palette[0] is the default */ if ((pindex = brightonFindFreeColor(palette, bwin->cmap_size)) < 0) return(0); palette[pindex].red = nr; palette[pindex].green = ng; palette[pindex].blue = nb; palette[pindex].uses++; palette[pindex].flags &= ~BRIGHTON_INACTIVE_COLOR; palette[pindex].uses++; cacheInsertColor(nr, ng, nb, pindex); return(pindex); } static int makeMenuPixel(brightonWindow *bwin, int x, int y, int dy) { int nr, ng, nb; int cpy = bwin->render->pixels[x + (y - 1) * bwin->width]; int cny = bwin->render->pixels[x + (y + 1) * bwin->width]; int cpre = bwin->render->pixels[dy - 1]; int color = bwin->render->pixels[dy]; int cnext = bwin->render->pixels[dy + 1]; brightonPalette *palette = bwin->display->palette; /* * This takes a pixel and does the following options as a single call: * * dest[i + dy] = antialias(bwin, bwin->render, i, j, 0.05); * dest[i + dy] = makeMonoChrome(bwin, dest[i + dy]); * dest[i + dy] = makeTransparent(bwin, dest[i + dy], menu[index], * bwin->opacity); * * These routines were called separately however that had two negative * side effects: * * 1. Creates excess colours as each routine will request new brighton * colours that may never actually be rendered but are cached. * 2. Has the overhead of 3 subroutine calls per pixel. * * The code may need to be put into brightonMenu.c */ if ((x == 0) || (x >= bwin->width - 1) || (y == 0) || (y == bwin->height - 1)) return(0); /* * Antialias the color: */ nr = (int) (((float) palette[color].red) * 0.08 + ((float) (palette[cpy].red + palette[cny].red + palette[cpre].red + palette[cnext].red)) * 0.23); ng = (int) (((float) palette[color].green) * 0.08 + ((float) (palette[cpy].green + palette[cny].green + palette[cpre].green + palette[cnext].green)) * 0.23); nb = (int) (((float) palette[color].blue) * 0.08 + ((float) (palette[cpy].blue + palette[cny].blue + palette[cpre].blue + palette[cnext].blue)) * 0.23); /* * Make monochrome based on selected algorithm, failing any match it will * not be grayscaled: */ switch (bwin->grayscale) { case 1: nr = (nr + ng + nb) / 3; ng = nb = nr; break; case 2: nr = (nr + ng + nb) / 6; ng = nb = nr; break; case 3: nr = (nr + ng + nb) / 12; ng = nb = nr; break; case 4: if (nr < ng) nr = nr < nb? nr:nb; else nr = ng < nb? ng:nb; ng = nb = nr; break; case 5: if (nr > ng) nr = nr > nb? nr:nb; else nr = ng > nb? ng:nb; ng = nb = nr; break; } /* * Make it transparent to the menu layer */ nr = (int) ( (((float) nr) * (1.0f - bwin->opacity)) + (((float) (palette[bwin->mlayer->pixels[dy]].red)) * bwin->opacity)); ng = (int) ( (((float) ng) * (1.0f - bwin->opacity)) + (((float) (palette[bwin->mlayer->pixels[dy]].green)) * bwin->opacity)); nb = (int) ( (((float) nb) * (1.0f - bwin->opacity)) + (((float) (palette[bwin->mlayer->pixels[dy]].blue)) * bwin->opacity)); /* * We want to be flexible on matches otherwise we use excessive colors and * slow the GUI down */ if ((color = brightonFindColor(palette, bwin->cmap_size, nr, ng, nb, bwin->quality - 2)) >= 0) { palette[color].uses++; return(color); } /* * If we have no free colors, then palette[0] is the default */ if ((color = brightonFindFreeColor(palette, bwin->cmap_size)) < 0) return(0); palette[color].red = nr; palette[color].green = ng; palette[color].blue = nb; palette[color].uses++; palette[color].flags &= ~BRIGHTON_INACTIVE_COLOR; palette[color].uses++; cacheInsertColor(nr, ng, nb, color); return(color); } /* * This is the final render algorithm. * It will take the window canvas, device layer and shadow layer at a given * offset, put them all onto the rendering plane, and update our screen * interface library. */ #ifdef STATS int statFunction(int op, char *operation) { if (op == 0) { gettimeofday(&tstart, 0); } else { time_t delta; gettimeofday(&tend, 0); /* * I hate this calculation. * * If seconds are the same then take the difference of the micros. * If seconds are not the same then diff secs - 1 blah blah blah */ delta = (tend.tv_sec - tstart.tv_sec) * 1000000 - tstart.tv_usec + tend.tv_usec; printf("%16s: %7i us\n", operation, (int) delta); } return(0); } #endif static int lock = 0; int brightonDoFinalRender(brightonWindow *bwin, register int x, register int y, register int width, register int height) { register int i, j, dy, pindex, aa; register int *src; register int *dest; register int *device; register int *shadow; register int *top; register int *menu; int count = 40; #ifdef STATS2 statFunction(0, "Brighton"); #endif while (lock) { usleep(25000); if (--count == 0) lock = 0; } lock = 1; if (bwin == NULL) return(lock = 0); if (bwin->canvas) src = bwin->canvas->pixels; else return(lock = 0); if (bwin->render) dest = bwin->render->pixels; else return(lock = 0); device = bwin->dlayer->pixels; shadow = bwin->slayer->pixels; top = bwin->tlayer->pixels; menu = bwin->mlayer->pixels; if ((width < 0) || (height < 0)) return(lock = 0); aa = bwin->display->flags & (BRIGHTON_ANTIALIAS_1 | BRIGHTON_ANTIALIAS_2); for (j = y; j < (y + height); j++) { if (j >= bwin->height) break; dy = j * bwin->width; for (i = x; i < (x + width); i++) { if (i >= bwin->width) break; /*pindex = i + j * bwin->width; */ pindex = i + dy; /* * We have 3 layers, the topmost device layer, the middle shadow * layer, and the lower canvas. The colors from each layer are * moved into the render layer in order of priority. Where any * layer has a negative brightonColor reference it is passed over * to a lower plane. Other planes may be introduced at a later date * as other features are incorporated. * * Adding another layer initially for patch cabling. We should * consider adding the top layer last and allow it to act as a * transparancy, but that is non trivial since we are not dealing * with colors, but with pixel identifiers. FFS. Done. * * FS: We should paint in the pixel as if the transparency were * not there, then, if we have a color in the transparency then we * will paint it in with opacity. * * Going to try and add in some 'smoothing', or antialiasing of the * rendering. Start with some trivial stuff - horizontal. Finally * implemented a trivial LR/TB antialiasing. Will extend it to use * a sandwiched bitmap since otherwise there are issues with how * devices are rendered - they are not antialiased as they appear * in a separate layer. The results are actualy quite nice, the * textures and blueprints get smoothed and the devices stand out * as more than real. Optional total smoothing is also possible. */ if (device[pindex] >= 0) dest[i + dy] = device[pindex]; else if (shadow[pindex] >= 0) dest[i + dy] = shadow[pindex]; else if (aa && ((i > 0) && (i < bwin->width - 1)) && ((j > 0) && (j < bwin->height - 1))) dest[i + dy] = antialias(bwin, bwin->canvas, i, j, bwin->antialias); else dest[i + dy] = src[pindex]; if (top[pindex] >= 0) dest[i + dy] = makeTransparent(bwin, dest[i + dy], top[pindex], bwin->opacity); /* * Now look for floating or other menus. These should generally be * on top as not to be obscured by devices or patch cables. */ if (menu[pindex] >= 0) { /* * So, we have to do something. I would initially suggest that * the existing image be greyscaled, blurred, made transparent * to the color in the menu layer. * * This should be put into a separate subroutine since calling * each operation individually means our internal colormap gets * filled with entries that are not used. This does not put any * greater load on the windowing system but will increase our * color cache lookup depth and hence lower lookup rate. dest[i + dy] = antialias(bwin, bwin->render, i, j, 0.05); dest[i + dy] = makeMonoChrome(bwin, dest[i + dy]); dest[i + dy] = makeTransparent(bwin, dest[i + dy], menu[pindex], bwin->opacity); */ dest[i + dy] = makeMenuPixel(bwin, i, j, i + dy); } } } #ifdef STATS2 statFunction(1, "Brighton"); statFunction(0, "Library"); #endif /* * The third levels of antialias is to re-alias the whole image rather * than just the backgrounds. This only works if we have already been * given the renderAlias image. */ if (bwin->display->flags & (BRIGHTON_ANTIALIAS_3|BRIGHTON_ANTIALIAS_4)) { brightonAliasArea(bwin, x, y, width, height); BDrawArea(bwin->display, bwin->renderalias, x, y, width, height, x, y); } else /* * Finally call the B library, of which currently only one version, the * B11 interface to X11. */ BDrawArea(bwin->display, bwin->render, x, y, width, height, x, y); #ifdef STATS2 statFunction(1, "Library"); #endif return(lock = 0); } int brightonFinalRender(brightonWindow *bwin, register int x, register int y, register int width, register int height) { /* * Speed up on resizing - prevent excess redraws since we will have to * scan the whole lot again anyway */ if (bwin->flags & BRIGHTON_NO_DRAW) return(0); /* if (bwin->flags & BRIGHTON_BUSY) */ /* return(0); */ /* bwin->flags |= BRIGHTON_BUSY; */ brightonDoFinalRender(bwin, x, y, width, height); /* bwin->flags &= ~BRIGHTON_BUSY; */ return(0); } /* * A tesselation algorithm, takes a bitmap and tiles it onto the specified area. */ int brightonTesselate(register brightonWindow *bwin, register brightonBitmap *src, register brightonBitmap *dest, register int x, register int y, register int width, register int height, int direction) { register int i, j, dy, w, h; register int *pixels; if ((src == 0) || (dest == 0)) return(0); /*printf("brightonTesselate()\n"); */ pixels = src->pixels; for (j = 0; j < height; j += src->height) { if (((j + y) >= dest->height) || (j >= height)) break; dy = (j + y) * dest->width; /* * Bounds check for reduction of last image to be rendered. */ if (j + src->height >= height) h = height - j; else h = src->height; for (i = 0; i < width; i += src->width) { if (((i + x) >= dest->width) || (i >= width)) break; if (i + src->width >= width) w = width - i; else w = src->width; brightonRender(bwin, src, dest, i + x, j + y, w, h, direction); } } return(0); } /* * This is a render algorithm. Takes a bitmap and copies it to the * brightonBitmap area. We should do some bounds checking first? */ int brightonRender(register brightonWindow *bwin, register brightonBitmap *src, register brightonBitmap *dest, register int x, register int y, register int width, register int height, int direction) { register int i, j, dy; register int *pixels; if ((src == 0) || (dest == 0) || (dest == src)) return(0); /*printf(" render %i %i %i %i, %i %i, %i %i %x\n", x, y, width, height, */ /*src->width, src->height, dest->width, dest->height, src->pixels); */ /*printf("bitmap \"%s\" uses = %i\n", src->name, src->uses); */ pixels = src->pixels; for (j = 0; j < height; j++) { if (((j + y) >= dest->height) || (j >= height)) break; dy = (j + y) * dest->width + x; for (i = 0; i < width; i++) { if (((i + x) >= dest->width) || (i >= width)) break; if (isblue(i + j * src->width, bwin->display->palette, pixels)) continue; dest->pixels[i + dy] = src->pixels[i + j * src->width]; } } return(0); } #define round(x) x - ((float) ((int) x)) >= 0.5? x, x + 1; static int brightonround(float x) { int ix = x; float fx = ix; if (x - fx >= 0.5) return(ix + 1); return(ix); } /* * This is a scaling render algorithm. Takes a bitmap and speads it across * the brightonWindow canvas area with interpolative antialiasing. It is only * really intended for blueprints as they are the only ones that are not easily * interpolated. */ void brightonStretchAlias(register brightonWindow *bwin, brightonBitmap *src, register brightonBitmap *dest, register int x, register int y, register int width, register int height, float primary) { register float i, j, fx, fy, px, py; register int ix, iy, ng, nb, nr, pindex; register int c, n, s, e, w; register brightonPalette *palette = bwin->display->palette; register int *pixels; register int *scratch; if ((src == 0) || (dest == 0) || (src == dest)) return; /* printf(" stretchAlias %i %i %i %i, %i %i: p %f\n", x, y, width, height, src->width, src->height, primary); */ pixels = src->pixels; /* * Do not support rendering outside of the panel area, excepting where we * go over outer edges. */ if ((x < 0) || (x >= bwin->width) || (y < 0) || (y >= bwin->height)) return; /* * Scratch should be allocated and only reallocated if it inceases in size * which is a fairly easy enhancement. */ scratch = (int *) brightonmalloc(sizeof(int) * dest->width * dest->height); bcopy(dest->pixels, scratch, sizeof(int) * dest->width * dest->height); /* * We now have the test bitmap, and it should have generated a palette. * render the bits onto our background, and copy it over. */ for (j = y; j <= (y + height); j++) { fy = (j - y) * ((float) src->height) / ((float) height); iy = fy; if ((iy = fy) >= src->height) break; if ((fy -= iy) < 0.5) py = fy; else py = 1.0 - fy; for (i = x; i <= (x + width - 1); i++) { /* * Take the x relative index into the source bitmap. These are * relative since they are floating points that will eventually * specify the depth of antialiasing. * * We take a floating point index and an integer, one for the * bitmap index and the float for the eventual alias munging. */ fx = (i - x) * ((float) src->width) / ((float) width); if ((ix = fx) >= src->width) break; /* * Set pixel. Since we are using brightonBitmaps we do not have to * go around using X library calls to set the pixel states. * * We may want to put in here isblue then destpixel;continue; */ if (isblue(ix + iy * src->width, palette, pixels)) c = scratch[(int) (i + j * dest->width)]; else c = pixels[ix + iy * src->width]; if (c >= bwin->cmap_size) c = 1; if (c < 0) continue; if (iy <= 0) { n = c; } else { if (isblue(ix + (iy - 1) * src->width, palette, pixels)) n = scratch[(int) (i + (j - 1) * dest->width)]; else n = pixels[ix + (iy - 1) * src->width]; if ((n < 0) || (n >= bwin->cmap_size)) continue; } if ((iy >= src->height - 1) || (j >= dest->height - 1)) s = c; else { if (isblue(ix + (iy + 1) * src->width, palette, pixels)) s = scratch[(int) (i + (j + 1) * dest->width)]; else s = pixels[ix + (iy + 1) * src->width]; if ((s < 0) || (s >= bwin->cmap_size)) continue; } if (ix >= src->width - 1) e = c; else { if (isblue(ix + 1 + iy * src->width, palette, pixels)) e = scratch[(int) (i + j * dest->width)]; else e = pixels[ix + 1 + iy * src->width]; if ((e < 0) || (e >= bwin->cmap_size)) continue; } if (ix <= 0) w = c; else { if (isblue(ix - 1 + iy * src->width, palette, pixels)) w = scratch[(int) (i - 1 + j * dest->width)]; else w = pixels[ix - 1 + iy * src->width]; if ((w < 0) || (w >= bwin->cmap_size)) continue; } /* * We now have centre plus north/south/east/west. We could go for * more compasspoints but that will do for now. * * We want to give most weight to the real current pixel and the * remainder to the n/s/e/w components. * * Primary = 0.8 * Secondary = (0.999 - 0.8) / 4; * * So, each secondary sums to 0.05 of itself but that is split * between dx and dy respectively. * * primary: 0.5 + (1.0 - (fx - ix)) * secondary: (1.0 - primary) * 0.25; * c: primary * c; * n: (1.0 - (fy - iy)) * secondary * n * s: (fy - iy) * secondary * s * w: (1.0 - (fx - ix)) * secondary * w * e: (fx - ix) * secondary * e printf("(%f, %f) (%f, %f) (%i, %i): %i %i %i %i %i\n", i, j, fx, fy, ix, iy, c, n, s, e, w); printf("%f %i: %f\n", fy, iy, (fy - iy)); printf("%f %f: %f %i, %f %i\n", px, py, fx, ix, fy, iy); */ if ((fx -= ix) < 0.5) px = fx; else px = 1.0 - fx; nr = (int) (((float) palette[c].red) * (py + px) + ((float) palette[n].red) * (1.0 - fy) * (0.5 - py) + ((float) palette[s].red) * fy * (0.5 - py) + ((float) palette[w].red) * (1.0 - fx) * (0.5 - px) + ((float) palette[e].red) * fx * (0.5 - px)); ng = (int) (((float) palette[c].green) * (py + px) + ((float) palette[n].green) * (1.0 - fy) * (0.5 - py) + ((float) palette[s].green) * fy * (0.5 - py) + ((float) palette[w].green) * (1.0 - fx) * (0.5 - px) + ((float) palette[e].green) * fx * (0.5 - px)); nb = (int) (((float) palette[c].blue) * (py + px) + ((float) palette[n].blue) * (1.0 - fy) * (0.5 - py) + ((float) palette[s].blue) * fy * (0.5 - py) + ((float) palette[w].blue) * (1.0 - fx) * (0.5 - px) + ((float) palette[e].blue) * fx * (0.5 - px)); /* * We want to be flexible on matches otherwise we use excessive * colors and slow the GUI down */ if ((pindex = brightonFindColor(palette, bwin->cmap_size, nr, ng, nb, bwin->quality)) >= 0) { palette[pindex].uses++; dest->pixels[(int) (i + j * dest->width)] = pindex; continue; } /* * If we have no free colors, then palette[0] is the default */ if ((pindex = brightonFindFreeColor(palette, bwin->cmap_size)) < 0) continue; palette[pindex].red = nr; palette[pindex].green = ng; palette[pindex].blue = nb; palette[pindex].uses++; palette[pindex].flags &= ~BRIGHTON_INACTIVE_COLOR; palette[pindex].uses++; /* * Set up the cache. */ cacheInsertColor(nr, ng, nb, pindex); dest->pixels[(int) (i + j * dest->width)] = pindex; } } brightonfree(scratch); } /* * This is a scaling render algorithm. Takes a bitmap and speads it across * the brightonWindow canvas area. We should do some bounds checking first. */ void brightonStretch(register brightonWindow *bwin, brightonBitmap *src, register brightonBitmap *dest, register int x, register int y, register int width, register int height, int flags) { register float i, j, x1 = 0; register int y1 = 0, ix1; register brightonPalette *palette = bwin->display->palette; register int *pixels; if ((src == 0) || (dest == 0) || (src == dest)) return; /*printf(" stretch %i %i %i %i, %i %i: flags %x\n", x, y, width, height, */ /*src->width, src->height, flags); */ if ((pixels = src->pixels) == NULL) return; /* * Do not support rendering outside of the panel area, excepting where we * go over outer edges. */ if ((x < 0) || (x >= bwin->width) || (y < 0) || (y >= bwin->height)) return; /* * We now have the test bitmap, and it should have generated a palette. * render the bits onto our background, and copy it over. */ for (i = y; i < (y + height); i++) { switch (flags & BRIGHTON_DIRECTION_MASK) { default: /* Default case and reverse take same values here */ case BRIGHTON_REVERSE: y1 = (int) ((i - y) * src->height / height) * src->width; break; case BRIGHTON_VERTICAL: y1 = (i - y) / height * src->width; break; case (BRIGHTON_VERTICAL|BRIGHTON_REVERSE): if (flags & BRIGHTON_HALF_REVERSE) { y1 = (i - y) / height * src->width; if (y1 < src->width / 2) y1 += src->width / 2; else y1 -= src->width / 2; } else { y1 = src->width - (i - y) / height * src->width; } break; } for (j = x; j < (x + width); j++) { switch (flags & BRIGHTON_DIRECTION_MASK) { default: /* Default case and reverse take same values here */ case 0: x1 = y1 + (j - x) * src->width / width; break; case BRIGHTON_REVERSE: /* * This is for button operations, and is only "half" * reversed. We should make this a rendering option? */ if (flags & BRIGHTON_HALF_REVERSE) { x1 = (j - x) / width * src->width; if (x1 < src->width / 2) x1 += y1 + src->width / 2; else x1 += y1 - src->width / 2; if (x1 >= src->width * src->height) x1 = src->width * src->height - 1; } else { x1 = y1 + src->width - (j - x) * src->width / width; } break; case BRIGHTON_VERTICAL: case (BRIGHTON_VERTICAL|BRIGHTON_REVERSE): x1 = y1 + (int) ((j - x) * src->height / width) * src->width; break; } ix1 = x1; /* * Set pixel. Since we are using brightonBitmaps we do not have to * go around using X library calls to set the pixel states. */ if (!isblue(ix1, palette, pixels)) dest->pixels[(int) (i * dest->width + j)] = src->pixels[ix1]; /* dest->pixels[(int) (i * dest->width + j)] = src->pixels[ix1]; * What I want to do here is take my source pixel and give it * some antialias. This should only be done if neighbouring * pixels are blue - primarily device edges and blueprints. * * The cheapest way to do this is just paint my pixel, then * temper it from 4 neighbors. if (i <= 0) n = src->pixels[ix1]; else n = dest->pixels[(int) ((i - 1) * dest->width + j)]; if (i >= dest->height - 1) s = src->pixels[ix1]; else s = dest->pixels[(int) ((i + 1) * dest->width + j)]; if (j <= 0) w = src->pixels[ix1]; else w = dest->pixels[(int) (i * dest->width + j - 1)]; if (j >= dest->width - 1) e = src->pixels[ix1]; else e = dest->pixels[(int) (i * dest->width + j + 1)]; */ } } } /* * This is not a true alpha layer in a bitmap. The function is similar, it * allows for fading bitmaps in and out. */ void brightonAlphaLayer(register brightonWindow *bwin, register brightonBitmap *src, register brightonBitmap *dest, register int dx, register int dy, register int width, register int height, register double rotation) { register int py, px, dp, sp, red, green, blue; register int i, j, ty, pindex; register brightonPalette *palette = bwin->display->palette; register float factor; /*printf("brightonAlphaLayer()\n"); */ for (py = 0; py < height; py+=1) { j = py * src->height / height; if (py >= dest->height) break; ty = (dy + py) * dest->width + dx; for (px = 0; px < width; px++) { i = px * src->width / width; if ((dp = dest->pixels[ty + px]) < 0) continue; sp = src->pixels[i + j * src->width]; /* if ((palette[sp].red == 0) */ /* && (palette[sp].green == 0) */ /* && (palette[sp].blue == 0xff)) */ if (isblue(i + j * src->width, palette, src->pixels)) continue; /* * The coloring wants to be white, but as the alpha layer gets * dimmer, the value tends back to the original: * * factor = (255 - palette[sp].red) / 255; * red = 255 * factor + palette[dp].red * (1.0 - factor); * red = 255 - ((255 - palette[sp].red) * palette[dp].red / 255); green = 255 - ((255 - palette[sp].green) * palette[dp].green / 255); blue = 255 - ((255 - palette[sp].blue) * palette[dp].blue / 255); red = (palette[dp].red + palette[sp].red) / 2; green = (palette[dp].green + palette[sp].green) / 2; blue = (palette[dp].blue + palette[sp].blue) / 2; red = 65535 * factor + palette[dp].red * (1.0 - factor); green = 65535 * factor + palette[dp].green * (1.0 - factor); blue = 65535 * factor + palette[dp].blue * (1.0 - factor); * * This works as a pure alpha layer scaling to white, I would * prefer the ability to add shadow. */ if ((factor = ((float) palette[sp].red) / 65535.0) > 0.5) { red = palette[dp].red + (65535 - palette[dp].red) * (factor - 0.5) * 2; green = palette[dp].green + (65535 - palette[dp].green) * (factor - 0.5) * 2; blue = palette[dp].blue + (65535 - palette[dp].blue) * (factor - 0.5) * 2; } else { red = palette[dp].red * factor * 2; green = palette[dp].green * factor * 2; blue = palette[dp].blue * factor * 2; } if ((pindex = brightonFindColor(palette, bwin->cmap_size, red, green, blue, bwin->quality)) >= 0) { palette[pindex].uses++; dest->pixels[ty + px] = pindex; continue; } /* * If we have no free colors, then palette[0] is the default */ if ((pindex = brightonFindFreeColor(palette, bwin->cmap_size)) < 0) { pindex = 0; dest->pixels[ty + px] = pindex; continue; } palette[pindex].red = red; palette[pindex].green = green; palette[pindex].blue = blue; palette[pindex].uses++; palette[pindex].flags &= ~BRIGHTON_INACTIVE_COLOR; palette[pindex].uses++; cacheInsertColor(red, green, blue, pindex); dest->pixels[ty + px] = pindex; } } } double roll = 0; double rinc = 0.04; /* * This could do with some XDrawPoints() optimisation as well. */ int brightonRotate(register brightonWindow *bwin, register brightonBitmap *src, register brightonBitmap *dest, register int dx, register int dy, register int width, register int height, register double rotation) { register int py, px; register double i, j; register int adjx, adjy, natx, naty; register double r, ho2, angle; register int x, y; register brightonPalette *palette = bwin->display->palette; register int *pixels; /*printf("brightonRotate(%i, %i, %i, %i)\n", */ /*dx, dy, src->width, src->height); */ if ((src == 0) || (dest == 0)) return(0); pixels = src->pixels; ho2 = src->height / 2; /* * Do not support rendering outside of the panel area, excepting where we * go over outer edges. */ if ((dx < 0) || (dx >= bwin->width) || (dy < 0) || (dy >= bwin->height)) { printf("bounds fail\n"); return(0); } if (width & 0x01) width--; if (height & 0x01) height--; /* * This is for 'wobble' on the pot cap as it rotates. */ if ((roll += rinc) > 0.3) rinc = -rinc; else if (roll < 0) { rinc = -rinc; roll = 0; } /* * We now have the test bitmap, and it should have generated a palette. * render the bits onto our background, and copy it over. */ for (py = 0; py < height; py+=1) { j = py * src->height / height; naty = j - ho2; if (py >= dest->height) break; for (px = 0; px < width; px++) { i = px * src->width / width; natx = i - ho2; if ((r = sqrttab[natx < 0?-natx:natx][naty < 0?-naty: naty]) > ho2) continue; /* * Rotate this point, and then put them back into native coords. * We need our own rounding algorithm - otherwise we get truncation. */ if (r < src->istatic) { /* * Want to do something here to make the centre 'wobble' x = brightonround(natx + ho2); y = brightonround(naty + ho2); */ /* * Take the angle of this point to the origin. */ if (naty < 0.0) { /*angle = asin(natx / r) + rotation; */ angle = asin(natx / r) + 2*M_PI - roll; adjx = r * sin(angle); adjy = -r * cos(angle); } else { /*angle = -asin(natx / r) + M_PI; */ angle = -asin(natx / r) + 2*M_PI - roll; adjx = -r * sin(angle); adjy = r * cos(angle); } x = brightonround(adjx + ho2); y = brightonround(adjy + ho2); /*x = brightonround(natx + ho2); */ /*y = brightonround(naty + ho2); */ } else if (r < src->ostatic) { /* * Take the angle of this point to the origin. */ if (naty < 0.0) { angle = asin(natx / r) + rotation; adjx = r * sin(angle); adjy = -r * cos(angle); } else { angle = -asin(natx / r) + rotation; adjx = -r * sin(angle); adjy = r * cos(angle); } x = brightonround(adjx + ho2); y = brightonround(adjy + ho2); } else { x = brightonround(natx + ho2); y = brightonround(naty + ho2); } if ((x < 0) || (x >= src->height) || (y < 0) || (y >= src->height)) continue; if (!isblue(x + y * src->width, palette, src->pixels)) dest->pixels[(int) (((dy + py) * dest->width) + dx + px)] = src->pixels[(int) (y * src->width + x)]; } } return(0); } bristol-0.60.11/libbrighton/brightonShadowMgt.c0000644000175000017500000002204711746476474016410 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include #include #include #include "brightoninternals.h" #define S_D 6 #define S_D2 20 #define S_D3 23 #define S_D4 8 /*#define S_DEPTH * 4 / 5 */ /*#define S_DEPTH2 / 2 */ /* * For now we only have cheap shading - puts a fixed shape of reduced intensity * pixels into the shadow layer. nc - 17/04/02. * Extended intensity gradients for smoother shadow. nc - 03/06/06. */ int brightonRenderShadow(brightonDevice *dev, int flags) { register int x, y, pf, py, po = 0, ys, xs, wr = 0, sfact = 0; register brightonWindow *bwin = dev->bwin; register brightonPalette *palette = bwin->display->palette; /* printf("brightonRenderShadow(%x, %i, %i, %i, %i, %i, %i)\n", dev, */ /* dev->x, dev->y, dev->width, dev->height, */ /* dev->bwin->app->resources[dev->panel].sx, */ /* dev->bwin->app->resources[dev->panel].sy); */ if ((bwin->app->resources[dev->panel].flags & BRIGHTON_WITHDRAWN) || (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_NOSHADOW) || (dev->device == -1)) return(0); if (dev->device == -1) return(0); /* * If it is a rotary: */ if (dev->device == 0) { int th, tw, xo = 0, salt; float yo, cy = 0, dy2 = dev->height / 4; ys = dev->y + dev->bwin->app->resources[dev->panel].sy; xs = dev->x + dev->bwin->app->resources[dev->panel].sx; /* tw = dev->width * 4/3; */ /* th = dev->height * 4/3; */ if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_HALFSHADOW) { tw = dev->width * 7 / 8; th = dev->height * 7 / 8; } else { tw = dev->width; th = dev->height; } th = tw = sqrtf(th * th / 2) + 1; /* * Rotary. This needs to be changed. I want to take an angle of 45 * degrees from the pot, full width, and tailor the shadow at both * ends. At the moment this only tails downwards. */ yo = th; for (x = 0; x < tw; x++) { for (y = 0; y < th - dy2; y++) { if (y < cy) sfact = 1; else if ((sfact = y - cy) < 2) sfact = 1; else if (sfact >= S_D4) sfact = S_D4 - 1; /* * As y reaches the end of the shadow we need to tail it off. * S_D4 - (th - y - 1) * Salt graduates the tip */ if ((salt = S_D4 - (th - y + 1)) < 2) salt = 1; else if (salt > S_D4) salt = S_D4 - 1; if (salt > sfact) sfact = salt; if ((x < 2) && (y < 2)) sfact = S_D4 - 1; if ((x < 2) && (y < 3)) sfact = S_D4 - 2; else if (((x == tw) || (x == tw - 1)) && (y == 0)) sfact = S_D4 - 1; pf = (ys + y + yo + 1) * bwin->slayer->width + xs + x + 2 + xo; bwin->slayer->pixels[pf] = brightonGetGC(bwin, palette[bwin->canvas->pixels[pf]].red *sfact/S_D4, palette[bwin->canvas->pixels[pf]].green *sfact/S_D4, palette[bwin->canvas->pixels[pf]].blue *sfact/S_D4); if (x != tw - 1) { bwin->slayer->pixels[pf + 1] = brightonGetGC(bwin, palette[bwin->canvas->pixels[pf + 1]].red *sfact/S_D4, palette[bwin->canvas->pixels[pf + 1]].green *sfact/S_D4, palette[bwin->canvas->pixels[pf + 1]].blue *sfact/S_D4); } xo++; } yo--; xo = 0; /* * This triangulates the shadow. */ if (x < tw / 2) cy+=2; else if (x > tw / 2) cy-=2; /* * This shortens the outer edges */ if (x > tw * 5 / 8) dy2 += 1.0; else if ((dy2 -= 1.0) < 0) dy2 = 0; } } else if (dev->device == 2) { int height = dev->height; int width = dev->width; if ((width < 5) || (height < 5)) return(0); /* * Buttons. These give their real size and shape but want light * shading as they are not really supposed to have a high profile. */ /* * for a brightonScale we have to cater for vertical and horizontal * movements. */ ys = dev->y + dev->bwin->app->resources[dev->panel].sy; xs = dev->x + dev->bwin->app->resources[dev->panel].sx; for (y = ys; y < ys + height; y++) { py = y * bwin->slayer->width; sfact = S_D; /* for (x = xs; x < xs + width + po; x++) */ for (x = xs + width + po; x != xs + 4; x--) { if (--sfact < 0) sfact = 0; pf = py + x; /* * Take whatever is in the canvas area, reduce its brightness, * put that into the shadow area. */ if (flags) bwin->slayer->pixels[pf] = -1; else bwin->slayer->pixels[pf] = brightonGetGC(bwin, palette[bwin->canvas->pixels[pf]].red *sfact/S_D, palette[bwin->canvas->pixels[pf]].green *sfact/S_D, palette[bwin->canvas->pixels[pf]].blue *sfact/S_D); } if (po < width / 6) po++; } for (; y < ys + height + width / 5; y++) { py = y * bwin->slayer->width; sfact = S_D; for (x = xs + width + po - wr; x != xs; x--) { if (--sfact < 0) sfact = 0; if (y == (ys + height + width / 5) - 3) sfact = S_D - 3; else if (y == (ys + height + width / 5) - 2) sfact = S_D - 2; if (y == (ys + height + width / 5) - 1) sfact = S_D - 1; else if (x == (xs + width + po - wr)) sfact = S_D - 1; else if (x == (xs + width + po - wr) - 1) sfact = S_D - 2; pf = py + x + wr; /* * Take whatever is in the canvas area, reduce its brightness, * put that into the shadow area. */ if (flags) bwin->slayer->pixels[pf] = -1; else bwin->slayer->pixels[pf] = brightonGetGC(bwin, palette[bwin->canvas->pixels[pf]].red *sfact/S_D, palette[bwin->canvas->pixels[pf]].green *sfact/S_D, palette[bwin->canvas->pixels[pf]].blue *sfact/S_D); } wr++; } } else { int height = dev->height; int width = dev->width; int div = 4; if ((width < 5) || (height < 5)) return(0); /* * for a brightonScale we have to cater for vertical and horizontal * movements. */ if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_VERTICAL) { height = dev->width * 2 / 3; width = dev->height * 2 / 3; xs = dev->x + dev->bwin->app->resources[dev->panel].sx + (int) dev->position; ys = dev->y + dev->bwin->app->resources[dev->panel].sy; } else { if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_HALFSHADOW) { ys = dev->y + dev->bwin->app->resources[dev->panel].sy + dev->height / 16 + (int) dev->position; div = 8; xs = dev->x + dev->bwin->app->resources[dev->panel].sx; } else { ys = dev->y + dev->bwin->app->resources[dev->panel].sy + (int) dev->position; xs = dev->x + dev->bwin->app->resources[dev->panel].sx; } } for (y = ys; y < ys + height / div - 1; y++) { py = y * bwin->slayer->width; sfact = S_D; /* for (x = xs; x < xs + width + po; x++) */ for (x = xs + width + po; x != xs + 4; x--) { if (--sfact < 0) sfact = 0; pf = py + x; /* * Take whatever is in the canvas area, reduce its brightness, * put that into the shadow area. */ if (flags) bwin->slayer->pixels[pf] = -1; else bwin->slayer->pixels[pf] = brightonGetGC(bwin, palette[bwin->canvas->pixels[pf]].red *sfact/S_D, palette[bwin->canvas->pixels[pf]].green *sfact/S_D, palette[bwin->canvas->pixels[pf]].blue *sfact/S_D); } if (po < width / 2) po++; } for (; y < ys + height / div + width / 2; y++) { py = y * bwin->slayer->width; sfact = S_D; /* for (x = xs; x < xs + width + po - wr; x++) */ for (x = xs + width + po - wr; x != xs; x--) { if (--sfact < 0) sfact = 0; if (y == (ys + height / div + width / 2) - 4) sfact = S_D - 4; else if (y == (ys + height / div + width / 2) - 3) sfact = S_D - 3; else if (y == (ys + height / div + width / 2) - 2) sfact = S_D - 2; if (y == (ys + height / div + width / 2) - 1) sfact = S_D - 1; else if (x == (xs + width + po - wr)) sfact = S_D - 1; else if (x == (xs + width + po - wr) - 1) sfact = S_D - 2; pf = py + x + wr; /* * Take whatever is in the canvas area, reduce its brightness, * put that into the shadow area. */ if (flags) bwin->slayer->pixels[pf] = -1; else bwin->slayer->pixels[pf] = brightonGetGC(bwin, palette[bwin->canvas->pixels[pf]].red *sfact/S_D, palette[bwin->canvas->pixels[pf]].green *sfact/S_D, palette[bwin->canvas->pixels[pf]].blue *sfact/S_D); } wr++; } } return(0); } bristol-0.60.11/libbrighton/brightonDisplayMgt.c0000644000175000017500000000373711746476474016575 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include #include #include "brightoninternals.h" #include "brightonX11.h" extern void initSqrtTab(); brightonDisplay * brightonOpenDisplay(char *displayname) { brightonDisplay *display; /* * This should be moved to a more generic init() procedure, it is not * required for each display connection, but at the same time we will * probably only connect to one anyway. */ initSqrtTab(); display = (brightonDisplay *) brightonmalloc(sizeof(brightonDisplay)); if (displayname == NULL) if ((displayname = getenv("DISPLAY")) == NULL) displayname = BRIGHTON_DEFAULT_DISPLAY; sprintf(&display->name[0], "%s", displayname); if ((display->display = (void *) BOpenDisplay(display, displayname)) == NULL) { printf("brightonOpenDisplay(): cannot open %s\n", displayname); brightonfree(display); return(0); } return(display); } brightonDisplay * brightonFindDisplay(brightonDisplay *dlist, brightonDisplay *display) { if (dlist == 0) return(0); if (dlist == display) return(display); return(brightonFindDisplay(dlist->next, display)); } int brightonCloseDisplay(brightonDisplay *display) { BCloseDisplay(display->display); brightonfree(display); return(0); } bristol-0.60.11/libbrighton/brightonDispatch.c0000644000175000017500000000564311746476474016255 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include "brightoninternals.h" brightonILocations * brightonDeviceLocator(register brightonIResource *panel, register int x, register int y) { register int index; register brightonILocations *locn; //printf("brightonDeviceLocator(%i, %i)\n", x, y); if (((panel->flags & BRIGHTON_ACTIVE) == 0) || (panel->flags & BRIGHTON_WITHDRAWN)) return(0); for (index = 0; index < panel->ndevices; index++) { locn = &panel->devlocn[index]; //printf("dev location %i %i %i %i\n", locn->ax, locn->ay, locn->aw, locn->ah); if ((locn->ax <= x) && ((locn->ax + locn->aw) > x) && (locn->ay <= y) && ((locn->ay + locn->ah) > y)) { //printf("found device %i\n", index); return(locn); } } return(0); } brightonIResource * brightonPanelLocator(brightonWindow *bwin, int x, int y) { register int index; register brightonIResource *locn; /* printf("brightonLocator(%i, %i)\n", x, y); */ for (index = 0; index < bwin->app->nresources; index++) { locn = &bwin->app->resources[index]; if (((locn->flags & BRIGHTON_ACTIVE) == 0) || (locn->flags & BRIGHTON_WITHDRAWN)) continue; if ((locn->sx <= x) && ((locn->sx + locn->sw) > x) && (locn->sy <= y) && ((locn->sy + locn->sh) > y)) { /*printf("found panel %i\n", index); */ /* * Found the panel. Now go look for the device */ return(locn); } } return(0); } /* * This will be called typically on button press, and attempts to locate * which device is under the given x/y co-ord. May have other uses. */ brightonILocations * brightonLocator(brightonWindow *bwin, int x, int y) { register int index; register brightonIResource *locn; /* printf("brightonLocator(%i, %i)\n", x, y); */ for (index = 0; index < bwin->app->nresources; index++) { locn = &bwin->app->resources[index]; if (((locn->flags & BRIGHTON_ACTIVE) == 0) || (locn->flags & BRIGHTON_WITHDRAWN)) continue; if ((locn->sx <= x) && ((locn->sx + locn->sw) > x) && (locn->sy <= y) && ((locn->sy + locn->sh) > y)) { /*printf("found panel %i\n", index); */ /* * Found the panel. Now go look for the device */ return(brightonDeviceLocator(locn, x - locn->sx, y - locn->sy)); } } return(0); } bristol-0.60.11/libbrighton/brightonkeymappings.h0000644000175000017500000001213511746476474017044 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* #define BRISTOL_FIXEDWIDTH */ /* * This needs to be changed to allow it to have a couple of different fonts, * at least to include another one for the menus - a little larger. This would * give access to 3 fonts, this one totally compact, the new one, and the new * one rendered in double res */ #define KEYTAB_SIZE 256 #define KEY_HEIGHT 5 #define BIT_ON 1 #define BIT_OFF 2 typedef struct Bkey { int map; int width; unsigned char bitmap[KEY_HEIGHT]; } bkey; bkey key[KEYTAB_SIZE]; void brightonsetkey(int index, int width, unsigned char ch0, unsigned char ch1, unsigned char ch2, unsigned char ch3, unsigned char ch4) { if (index >= KEYTAB_SIZE) return; key[index].map = index; #ifdef BRISTOL_FIXEDWIDTH key[index].width = 5; #else key[index].width = width; #endif key[index].bitmap[0] = ch0; key[index].bitmap[1] = ch1; key[index].bitmap[2] = ch2; key[index].bitmap[3] = ch3; key[index].bitmap[4] = ch4; } void initkeys() { int i; for (i = 0; i < KEYTAB_SIZE; i++) { key[i].map = -1; key[i].width = -1; } key[0].width = 4; key[0].bitmap[0] = 0xf0; key[0].bitmap[1] = 0xf0; key[0].bitmap[2] = 0xf0; key[0].bitmap[3] = 0xf0; key[0].bitmap[4] = 0xf0; brightonsetkey(' ', 3, 0x00, 0x00, 0x00, 0x00, 0x00); brightonsetkey('A', 5, 0x20, 0x50, 0x50, 0xa8, 0x88); brightonsetkey('B', 4, 0xe0, 0x90, 0xe0, 0x90, 0xe0); brightonsetkey('C', 4, 0x60, 0x90, 0x80, 0x90, 0x60); brightonsetkey('D', 4, 0xe0, 0x90, 0x90, 0x90, 0xe0); brightonsetkey('E', 3, 0xf0, 0x80, 0xd0, 0x80, 0xf0); brightonsetkey('F', 3, 0xf0, 0x80, 0xd0, 0x80, 0x80); brightonsetkey('G', 4, 0x60, 0x90, 0x80, 0xb0, 0x60); brightonsetkey('H', 4, 0x90, 0x90, 0xf0, 0x90, 0x90); #ifdef BRISTOL_FIXEDWIDTH brightonsetkey('I', 1, 0x70, 0x20, 0x20, 0x20, 0x70); #else brightonsetkey('I', 1, 0x80, 0x80, 0x80, 0x80, 0x80); #endif brightonsetkey('J', 4, 0x70, 0x20, 0x20, 0xa0, 0x40); brightonsetkey('K', 4, 0x90, 0xa0, 0xc0, 0xa0, 0x90); brightonsetkey('L', 4, 0x80, 0x80, 0x80, 0x80, 0xf0); brightonsetkey('M', 5, 0x88, 0xd8, 0xa8, 0x88, 0x88); brightonsetkey('N', 4, 0x90, 0xd0, 0xb0, 0x90, 0x90); brightonsetkey('O', 4, 0x60, 0x90, 0x90, 0x90, 0x60); brightonsetkey('P', 4, 0xe0, 0x90, 0xe0, 0x80, 0x80); brightonsetkey('Q', 4, 0x60, 0x90, 0x90, 0xb0, 0x70); brightonsetkey('R', 4, 0xe0, 0x90, 0xe0, 0xa0, 0x90); brightonsetkey('S', 4, 0x70, 0x80, 0x60, 0x10, 0xe0); brightonsetkey('T', 5, 0xf8, 0x20, 0x20, 0x20, 0x20); brightonsetkey('U', 4, 0x90, 0x90, 0x90, 0x90, 0x60); brightonsetkey('V', 5, 0x88, 0x88, 0x50, 0x50, 0x20); brightonsetkey('W', 5, 0x88, 0x88, 0xa8, 0xd8, 0x88); brightonsetkey('X', 4, 0x90, 0x90, 0x60, 0x60, 0x90); brightonsetkey('Y', 5, 0x88, 0x50, 0x20, 0x20, 0x20); brightonsetkey('Z', 4, 0xf0, 0x10, 0x20, 0x40, 0xf0); brightonsetkey('0', 4, 0x60, 0x90, 0x90, 0x90, 0x60); #ifdef BRISTOL_FIXEDWIDTH brightonsetkey('1', 5, 0x60, 0x20, 0x20, 0x20, 0x70); #else brightonsetkey('1', 3, 0x40, 0xc0, 0x40, 0x40, 0xe0); #endif brightonsetkey('2', 4, 0x60, 0x90, 0x20, 0x40, 0xf0); brightonsetkey('3', 4, 0x60, 0x90, 0x20, 0x90, 0x60); brightonsetkey('4', 4, 0x10, 0x30, 0x50, 0xf0, 0x10); brightonsetkey('5', 4, 0xf0, 0x80, 0xe0, 0x10, 0xe0); brightonsetkey('6', 4, 0x60, 0x80, 0xe0, 0x90, 0x60); brightonsetkey('7', 4, 0xf0, 0x10, 0x20, 0x40, 0x40); brightonsetkey('8', 4, 0x60, 0x90, 0x60, 0x90, 0x60); brightonsetkey('9', 4, 0x60, 0x90, 0x70, 0x10, 0x60); brightonsetkey('-', 3, 0x00, 0x00, 0xe0, 0x00, 0x00); brightonsetkey('_', 3, 0x00, 0x00, 0x00, 0x00, 0x70); brightonsetkey(':', 1, 0x00, 0x80, 0x00, 0x80, 0x00); brightonsetkey(';', 1, 0x00, 0x80, 0x00, 0x80, 0x00); brightonsetkey('?', 4, 0x60, 0x90, 0x20, 0x00, 0x20); brightonsetkey('/', 5, 0x08, 0x10, 0x20, 0x40, 0x80); brightonsetkey('.', 1, 0x00, 0x00, 0x00, 0x00, 0x80); brightonsetkey('+', 3, 0x00, 0x40, 0xe0, 0x40, 0x00); key['a'].map = 'A'; key['b'].map = 'B'; key['c'].map = 'C'; key['d'].map = 'D'; key['e'].map = 'E'; key['f'].map = 'F'; key['g'].map = 'G'; key['h'].map = 'H'; key['i'].map = 'I'; key['j'].map = 'J'; key['k'].map = 'K'; key['l'].map = 'L'; key['m'].map = 'M'; key['n'].map = 'N'; key['o'].map = 'O'; key['p'].map = 'P'; key['q'].map = 'Q'; key['r'].map = 'R'; key['s'].map = 'S'; key['t'].map = 'T'; key['u'].map = 'U'; key['v'].map = 'V'; key['w'].map = 'W'; key['x'].map = 'X'; key['y'].map = 'Y'; key['z'].map = 'Z'; } bristol-0.60.11/libbrighton/brightonBitmaps.c0000644000175000017500000001047311746476474016112 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include #include #include "brightoninternals.h" extern brightonBitmap *xpmread(brightonWindow *, char *); char *brightonhome = 0; brightonBitmap * brightonCreateBitmap(brightonWindow *bwin, int width, int height) { brightonBitmap *bitmap; bitmap = brightonmalloc((size_t) sizeof(struct BrightonBitmap)); bitmap->width = width; bitmap->height = height; bitmap->pixels = (int *) brightonmalloc((2 + width) * (2 + height) * sizeof(int)); bitmap->ncolors = 0; bitmap->ctabsize = BRIGHTON_QR_COLORS; bitmap->colormap = (int *) brightonmalloc(BRIGHTON_QR_COLORS * sizeof(int)); bitmap->uses = 1; /* * Link it in to our window. */ if (bwin->bitmaps != NULL) bwin->bitmaps->last = bitmap; bitmap->next = bwin->bitmaps; bwin->bitmaps = bitmap; return(bitmap); } brightonBitmap * brightonCreateNamedBitmap(brightonWindow *bwin, int width, int height, char *name) { brightonBitmap *bitmap; bitmap = brightonCreateBitmap(bwin, bwin->width, bwin->height); bitmap->name = brightonmalloc(strlen(name) + 1); sprintf(bitmap->name, "%s", name); return(bitmap); } brightonBitmap * brightonReadImage(brightonWindow *bwin, char *filename) { char *extension, file[256]; brightonBitmap *bitmap = bwin->bitmaps; /* printf("brightonReadImage(%x, %s)\n", bwin, filename); */ if (filename == 0) return(0); if (filename[0] == '/') sprintf(file, "%s", filename); else { if (brightonhome == 0) brightonhome = getenv("BRIGHTON"); sprintf(file, "%s/%s", brightonhome, filename); } /* * See if we already have this image loaded on this screen. We cannot have * global bitmap assignments since if we are working on different screens * then we might not have the full set of GCs to render this image. */ while (bitmap != 0) { if ((bitmap->name != 0) && (strcmp(file, bitmap->name) == 0)) { bitmap->uses++; /* printf("ReUse Bitmap: %s %i\n", bitmap->name, bitmap->uses); */ return(bitmap); } bitmap = bitmap->next; } /* * See if we have this already loaded. If so, pass back a handle, otherwise * determine the type from the name and pass the brightonBitmap back to * the caller. */ if ((extension = rindex(file, (int) '.')) == 0) return(0); if (strcmp(".xpm", extension) == 0) return(xpmread(bwin, file)); /* * Add in any other handlers for gif/bmp, etc. */ return(0); } brightonBitmap * brightonFreeBitmap(brightonWindow *bwin, brightonBitmap *bitmap) { brightonBitmap *bitmaplist = bwin->bitmaps, *next = NULL; if (bitmap == 0) return(0); /* printf("brightonFreeBitmap(%x)\n", bitmap->name); */ while (bitmaplist != 0) { if (bitmap == bitmaplist) { int i; if (--bitmap->uses <= 0) { /*printf("freeing %x (%s)\n", bitmaplist, bitmaplist->name); */ /* * Unlink the bitmap */ if (bitmaplist->next) bitmaplist->next->last = bitmaplist->last; if (bitmaplist->last) bitmaplist->last->next = bitmaplist->next; else bwin->bitmaps = bitmaplist->next; if (bitmaplist->colormap) for (i = 0; i < bitmaplist->ncolors;i++) { brightonFreeGC(bwin, bitmaplist->colormap[i]); } if (bitmaplist->colormap) brightonfree(bitmaplist->colormap); if (bitmaplist->pixels) brightonfree(bitmaplist->pixels); if (bitmaplist->name) brightonfree(bitmaplist->name); next = bitmaplist->next; brightonfree(bitmaplist); } #ifdef DEBUG else { printf("bitmap %s has uses %i\n", bitmaplist->name, bitmaplist->uses); } #endif return(next); } bitmaplist = bitmaplist->next; } return(0); } bristol-0.60.11/libbrighton/brightonMenu.c0000644000175000017500000000562511746476474015422 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include #include #include "brightonX11.h" #include "brightoninternals.h" /* * This will eventually go into a header file and be placed inside the bwin * structure. */ #define BRIGHTON_MENUPOSTED 0x0001 typedef struct BrightonMenuCtl { unsigned int flags; int origx, origy; int postx, posty; int postw, posth; void *deviceMenu; /* menu entries and source data, etc */ int panel, device; } brightonMenuCtl; brightonMenuCtl menu; int brightonMenu(brightonWindow *bwin, int x, int y, int w, int h) { int dx, dy, cw, ch = h, color; brightonBitmap *mlayer = bwin->mlayer; if (menu.flags && BRIGHTON_MENUPOSTED) { brightonInitBitmap(bwin->mlayer, -1); brightonDoFinalRender(bwin, menu.postx, menu.posty, menu.postw, menu.posth); menu.flags &= ~BRIGHTON_MENUPOSTED; return(-1); } menu.origx = x; menu.origy = y; menu.postw = w; menu.posth = h; /* * Do some bounds checking to make sure the menubox even fits the window. * The rhodesbass is small and all can be resized. */ if (((y + h) >= bwin->height) && ((y = bwin->height - h - 1) < 0)) return(-1); if (((x + w) >= bwin->width) && ((x = bwin->width - w - 1) < 0)) return(-1); /* * Put a box in to represent a menu, just to test the results. */ dy = y * mlayer->width; dx = x; /* * Color of the border should be a parameter and we should consider finding * if not inserting it. */ if ((color = brightonGetGC(bwin, 0xff00, 0xff00, 0x0000)) < 0) { printf("missed color\n"); color = 1; } for (; h > 0; h--) { for (cw = 0; cw < w; cw++) mlayer->pixels[dy + dx + cw] = color; dy += mlayer->width; } dy = (y + 1) * mlayer->width; dx = x + 1; /* * Color of the background should be a parameter and we should consider * finding if not inserting it. */ if ((color = brightonGetGC(bwin, 0, 0, 0)) < 0) { printf("missed color\n"); color = 1; } for (h = ch; h > 2; h--) { for (cw = 0; cw < (w - 2); cw++) mlayer->pixels[dy + dx + cw] = color; dy += mlayer->width; } brightonDoFinalRender(bwin, x, y, w, ch); menu.postx = x; menu.posty = y; menu.flags |= BRIGHTON_MENUPOSTED; return(-1); } bristol-0.60.11/libbrighton/brightonWindowMgt.c0000644000175000017500000000723011746476474016427 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include #include "brightoninternals.h" #include "brightonX11.h" static int id = 0; brightonWindow *winlist = 0; extern void clearout(); extern int brightonCloseDisplay(brightonDisplay *); extern int BGetGeometry(brightonDisplay *, brightonWindow *); brightonWindow * brightonCreateWindow(brightonDisplay *display, brightonApp *app, int cmapsize, int flags, int quality, int gs, int x, int y) { brightonWindow *bwin; bwin = brightonmalloc(sizeof(brightonWindow)); bwin->cmap_size = cmapsize; bwin->quality = quality; bwin->grayscale = gs; bwin->id = ++id; display->bwin = bwin; ((brightonWindow *) display->bwin)->display = (brightonDisplay *) display; printf("display is %i by %i pixels (%i, %i)\n", display->width, display->height, x, y); if (BGetGeometry(display, bwin) < 0) printf("cannot get root window geometry\n"); else printf("Window is w %i, h %i, d %i, %i %i %i\n", bwin->width, bwin->height, bwin->depth, bwin->x, bwin->y, bwin->border); if ((display->palette = brightonInitColormap(bwin, bwin->cmap_size)) == NULL) clearout(-1); bwin->image = brightonReadImage(bwin, app->image); bwin->surface = brightonReadImage(bwin, app->surface); if (bwin->image) { bwin->width = bwin->image->width; bwin->height = bwin->image->height; } else { bwin->width = app->width; bwin->height = app->height; } bwin->aspect = ((float) bwin->width) / bwin->height; if (x > 0) bwin->x = x; else if (x < 0) bwin->x = display->width + x - app->width; if (y > 0) bwin->y = y; else if (y < 0) bwin->y = display->height + y - app->height; if (app->flags & BRIGHTON_POST_WINDOW) bwin->flags |= _BRIGHTON_POST; if (BOpenWindow(display, bwin, app->name) == 0) { brightonfree(bwin); bwin = 0; clearout(-1); return(0); } bwin->flags |= BRIGHTON_ACTIVE; brightonInitDefHandlers(bwin); bwin->next = winlist; winlist = bwin; /* * Force a fake size to ensure the first configure notify is picked up. */ bwin->width = bwin->height = 10; BFlush((brightonDisplay *) display); return(bwin); } void brightonDestroyWindow(brightonWindow *bwin) { brightonBitmap *bitmap; printf("brightonDestroyWindow()\n"); BFlush((brightonDisplay *) bwin->display); BCloseWindow((brightonDisplay *) bwin->display, bwin); if (brightonCloseDisplay((brightonDisplay *) bwin->display)) { bwin->flags = 0; brightonfree(bwin); clearout(0); } brightonFreeBitmap(bwin, bwin->image); brightonFreeBitmap(bwin, bwin->surface); brightonFreeBitmap(bwin, bwin->canvas); brightonFreeBitmap(bwin, bwin->dlayer); brightonFreeBitmap(bwin, bwin->slayer); brightonFreeBitmap(bwin, bwin->tlayer); brightonFreeBitmap(bwin, bwin->render); bitmap = bwin->bitmaps; while (bitmap) { bitmap = brightonFreeBitmap(bwin, bitmap); } if (bwin->bitmaps) printf("Bitmap list is not empty on window exit: %s\n", bwin->bitmaps->name); bwin->flags = 0; brightonfree(bwin); } bristol-0.60.11/libbrighton/brightonPic.c0000644000175000017500000000622611746476474015227 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* * Render a brightonBitmap into an area. */ #include "brightoninternals.h" int destroyPic(brightonDevice *dev) { printf("destroyPic()\n"); if (dev->image) brightonFreeBitmap(dev->bwin, dev->image); dev->image = NULL; return(0); } static int displayPic(brightonDevice *dev) { brightonIResource *panel; /*printf("displayPic\n"); */ /* * We should render any text we desire into the bmap, and then have it * painted */ if (dev->bwin->app->resources[dev->panel].flags & BRIGHTON_WITHDRAWN) return(0); panel = &dev->bwin->app->resources[dev->panel]; brightonDevUndraw(dev->bwin, dev->bwin->dlayer, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width, dev->height); /* * Only draw fixed number of steps. */ brightonStretch(dev->bwin, dev->image, dev->bwin->dlayer, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width, dev->height, dev->position); brightonFinalRender(dev->bwin, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width, dev->height); return(0); } static int configure(brightonDevice *dev, brightonEvent *event) { /*printf("configurePic(%i)\n", event->command); */ if (event->command == -1) return(-1); if (event->command == BRIGHTON_RESIZE) { dev->originx = event->x; dev->originy = event->y; dev->x = event->x; dev->y = event->y; dev->width = event->w; dev->height = event->h; displayPic(dev); return(0); } if (event->command == BRIGHTON_PARAMCHANGE) { /* * This will be used to configure different background images */ if ((event->type == BRIGHTON_MEM) && (event->m != 0)) { if (dev->image) brightonFreeBitmap(dev->bwin, dev->image); dev->image = brightonReadImage(dev->bwin, event->m); displayPic(dev); } } return(0); } int * createPic(brightonWindow *bwin, brightonDevice *dev, int index, char *bitmap) { /*printf("createPic(%s)\n", bitmap); */ dev->destroy = destroyPic; dev->configure = configure; dev->bwin = bwin; if (bitmap != 0) { if (dev->image) brightonFreeBitmap(bwin, dev->image); dev->image = brightonReadImage(bwin, bitmap); } /* * These will force an update when we first display ourselves. */ dev->value = 0; dev->lastvalue = -1; dev->lastposition = -1; return(0); } bristol-0.60.11/libbrighton/brightonTouchpanel.c0000644000175000017500000002055311746476474016615 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include "brightoninternals.h" static float winwidth, winheight; static float sx = -1, sy = -1; int destroyTouch(brightonDevice *dev) { printf("destroyTouch()\n"); if (dev->image) brightonFreeBitmap(dev->bwin, dev->image); dev->image = NULL; return(0); } static int displaytouch(brightonDevice *dev) { brightonIResource *panel; float dv, dv2; if (dev->bwin->app->resources[dev->panel].flags & BRIGHTON_WITHDRAWN) return(0); panel = &dev->bwin->app->resources[dev->panel]; if (dev->value < 0) { if ((dev->lastposition >= 0) && (dev->lastposition2 >= 0)) { brightonDevUndraw(dev->bwin, dev->bwin->dlayer, dev->x + ((int) dev->lastposition2) + dev->bwin->app->resources[dev->panel].sx, dev->y + ((int) dev->lastposition) + dev->bwin->app->resources[dev->panel].sy, dev->image->width, dev->image->height); brightonFinalRender(dev->bwin, dev->x + dev->lastposition2 + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->lastposition + dev->bwin->app->resources[dev->panel].sy, dev->image->width, dev->image->height); return(0); } } /* * Build up a smooth position for the pot. We may need to adjust this based * on the to/from values. */ if ((dev->value == dev->lastvalue) && (dev->value2 == dev->lastvalue2)) return(0); dv = dev->value; dv2 = 1 - dev->value2; if ((dev->lastposition >= 0) && (dev->lastposition2 >= 0)) brightonDevUndraw(dev->bwin, dev->bwin->dlayer, dev->x + ((int) dev->lastposition2) + dev->bwin->app->resources[dev->panel].sx, dev->y + ((int) dev->lastposition) + dev->bwin->app->resources[dev->panel].sy, dev->image->width, dev->image->height); brightonFinalRender(dev->bwin, dev->x + dev->lastposition2 + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->lastposition + dev->bwin->app->resources[dev->panel].sy, dev->image->width, dev->image->height); dev->position = dv * (dev->height - dev->image->height); dev->position2 = dv2 * (dev->width - dev->image->width); /* * Only draw fixed number of steps. */ brightonRender(dev->bwin, dev->image, dev->bwin->dlayer, (int) (dev->x + dev->position2 + dev->bwin->app->resources[dev->panel].sx), (int) (dev->y + dev->position + dev->bwin->app->resources[dev->panel].sy), dev->image->width, dev->image->height, dev->position); brightonFinalRender(dev->bwin, dev->x + dev->position2 + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->position + dev->bwin->app->resources[dev->panel].sy, dev->image->width, dev->image->height); dev->lastvalue = dev->value; dev->lastposition = dev->position; dev->lastvalue2 = dev->value2; dev->lastposition2 = dev->position2; return(0); } static void considercallback(brightonDevice *dev) { brightonIResource *panel = &dev->bwin->app->resources[dev->panel]; if ((dev->value < 0) || (dev->value2 < 0)) return; /* * Due to the co-ordinate system, if we do NOT have the reverse flags * then we need to reverse the value. if ((dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_REVERSE) == 0) dev->value = 1.0 - dev->value; */ if ((dev->lastvalue != dev->value) || (dev->lastvalue2 != dev->value2)) { if (panel->devlocn[dev->index].callback) { panel->devlocn[dev->index].callback(dev->bwin, dev->panel, dev->index, 1 - dev->value); panel->devlocn[dev->index].callback(dev->bwin, dev->panel, dev->index + 1, 1 - dev->value2); } else { if (panel->callback) panel->callback(dev->bwin, dev->panel, dev->index, 1 - dev->value); if (panel->callback) panel->callback(dev->bwin, dev->panel, dev->index + 1, 1 - dev->value2); } } } static int configure(brightonDevice *dev, brightonEvent *event) { /*printf("configureTouch(%i)\n", event->command); */ if (event->command == -1) return(-1); if (event->command == BRIGHTON_RESIZE) { dev->originx = event->x; dev->originy = event->y; dev->x = event->x; dev->y = event->y; dev->width = event->w; dev->height = event->h; /* * We should now rework our parent understanding of our window, since * it will have altered. NOT NECESSARY FOR SCALE. brightonPanelLocation(dev->bwin, dev->panel, dev->index, dev->x, dev->y, dev->width, dev->height); considercallback(dev); */ /* * Highlights need to be rendered dynamically in displaytouch(). renderHighlights(dev->bwin, dev); */ dev->lastvalue = -1; displaytouch(dev); return(0); } if (event->command == BRIGHTON_BUTTONRELEASE) { if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_CENTER) { dev->value = 0.5; dev->value2 = 0.5; considercallback(dev); displaytouch(dev); } else { if ((dev->flags & BRIGHTON_WIDE) == 0) dev->value = -1; displaytouch(dev); } sx = sy = -1; return(0); } if (event->command == BRIGHTON_MOTION) { if (dev->flags & BRIGHTON_WIDE) { if (sx == -1) { sx = event->x; sy = event->y; } /*printf("aks motion %i %i, %i %i, %i %i: %f\n", */ /*event->x, event->y, dev->x, dev->y, winwidth, winheight, dev->value); */ if ((dev->value = ((float) event->y - sy) / winheight + 0.5) < 0) dev->value = 0; else if (dev->value > 1.0) dev->value = 1.0; /* * Our motion started from sx, we should look for a value * such as * sx + event->x / winwidth */ if ((dev->value2 = ((float) event->x - sx) / winwidth + 0.5) < 0) dev->value2 = 0; else if (dev->value2 > 1.0) dev->value2 = 1.0; /* * Need to to reverse value due to co-ordinate space */ dev->value2 = 1.0 - dev->value2; } else { if ((dev->value = (((float) (event->y - dev->y)) / dev->height)) < 0) dev->value = 0; else if (dev->value > 1.0) dev->value = 1.0; if ((dev->value2 = (((float) (event->x - dev->x)) / dev->width)) < 0) dev->value2 = 0; else if (dev->value2 > 1.0) dev->value2 = 1.0; dev->value2 = 1.0 - dev->value2; } /*printf("touch motion %i %i, %i %i, %i %i: %f\n", */ /*event->x, event->y, dev->x, dev->y, dev->width, dev->height, dev->value); */ considercallback(dev); displaytouch(dev); return(0); } return(0); } int * createTouch(brightonWindow *bwin, brightonDevice *dev, int index, char *bitmap) { /*printf("createTouch(%s)\n", bitmap); */ winwidth = bwin->display->width / 2; winheight = bwin->display->height / 2; dev->destroy = destroyTouch; dev->configure = configure; dev->index = index; dev->bwin = bwin; /* * Notch has been reused, should give it another name here */ if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_WIDE) dev->flags |= BRIGHTON_WIDE; if (bitmap == 0) { if (dev->image) brightonFreeBitmap(bwin, dev->image); /* * Open the default bitmap */ if (bwin->app->resources[dev->panel].devlocn[dev->index].image != 0) dev->image = bwin->app->resources[dev->panel].devlocn[dev->index].image; if (dev->image == 0) dev->image = brightonReadImage(bwin, "bitmaps/images/pointer.xpm"); } else { if (dev->image) brightonFreeBitmap(bwin, dev->image); dev->image = brightonReadImage(bwin, bitmap); if (dev->image == 0) dev->image = brightonReadImage(bwin, "bitmaps/images/pointer.xpm"); } /* * These will force an update when we first display ourselves. */ if (bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_CENTER) { dev->value = 0.5; dev->value2 = 0.5; } else dev->value = 0; if (dev->flags & BRIGHTON_WIDE) { dev->value = 0.5; dev->value2 = 0.5; } else dev->value = -1; dev->lastvalue = -1; dev->lastposition = 0; dev->lastvalue2 = -1; dev->lastposition2 = 0; return(0); } bristol-0.60.11/libbrighton/brightonC.c0000644000175000017500000000515211746476474014673 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include #include #include #include #include #include #include void * brightonmalloc(size_t size) { void *mem; /* * Man, this is an ugly workaround. Somewhere in the app I am writing * past the end of a memory block, leading to heap corruption and it is * naturally causing segfaults in malloc(). This works around the issue * until I can track it down. * * We could use calloc here and let -O3 remove the whole shim. */ if ((mem = malloc(size)) == NULL) { printf("NULL malloc, exiting\n"); exit(-10); } bzero(mem, size); return(mem); } void brightonfree(void *mem) { if (mem) free(mem); } FILE * brightonfopen(char *filename, char *permissions) { return(fopen(filename, permissions)); } char * brightonfgets(char *line, int size, FILE *fd) { return(fgets(line, size, fd)); } int brightonfclose(FILE *fd) { /* * This may or may not cause a fault at some point. */ return(fclose(fd)); } #ifdef nothing /* * This was really just to debug the heap corruption. */ FILE * brightonfopen(char *filename, char *permissions) { /* * We only use fopen for reading work, it was easy but gave problems */ return((FILE *) open(filename, O_RDONLY)); } char * brightonfgets(char *line, int size, FILE *FD) { int fd = (int) FD, count = 0; /* * This is not going to be the fastest code, we can work on buffer * optimisation later. */ while (count < size) { if (read(fd, &line[count], 1) < 0) { if (count == 0) return(NULL); line[count] = '\0'; return(line); } if ((line[count] == '\n') || (line[count] == '\r')) { line[count] = '\0'; return(line); } count++; } return(line); } int brightonfclose(FILE *fd) { /* * This may or may not cause a fault at some point. */ return(close((int) fd)); } #endif bristol-0.60.11/libbrighton/brightonScale.c0000644000175000017500000004136611746476474015547 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* * This will be a linear potmeter. Takes a bitmap and locates it according to * input from the mouse/keyboard. Previous positions need to be unmapped, since * there is total repositioning of the image bitmap. */ #include "brightoninternals.h" int destroyScale(brightonDevice *dev) { printf("destroyScale()\n"); if (dev->image) brightonFreeBitmap(dev->bwin, dev->image); dev->image = NULL; return(0); } static int displayscale(brightonDevice *dev) { brightonIResource *panel; float displayvalue; if (dev->bwin->app->resources[dev->panel].flags & BRIGHTON_WITHDRAWN) return(0); if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_WITHDRAWN) return(0); panel = &dev->bwin->app->resources[dev->panel]; /* * Build up a smooth position for the pot. We may need to adjust this based * on the to/from values. */ if (dev->value == dev->lastvalue) return(0); displayvalue = dev->value; /* brightonFinalRender(dev->bwin, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->lastposition + dev->bwin->app->resources[dev->panel].sy, dev->width, dev->height / 4); */ /* * This seems odd, the vertical flag refers to the scrolled item, not the * direction of movement. Perhaps that should change as the direction of * movement is counterintuitive */ if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_VERTICAL) { if (dev->lastposition >= 0) { brightonDevUndraw(dev->bwin, dev->bwin->dlayer, dev->x + ((int) dev->lastposition) + dev->bwin->app->resources[dev->panel].sx - 5, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width / 8 + 5, dev->height); brightonRenderShadow(dev, 1); } dev->position = displayvalue * (dev->width - dev->width / 4); /* * Only draw fixed number of steps. Panned. Just draw it..... */ brightonStretch(dev->bwin, dev->image, dev->bwin->dlayer, (int)(dev->x + dev->position + dev->bwin->app->resources[dev->panel].sx), dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width / 8, dev->height, 1); brightonRenderShadow(dev, 0); /* * And request the panel to put this onto the respective image. */ if (dev->position > dev->lastposition) { /* * We have to render from the last position up to the current one * adding in bits for shade. */ brightonFinalRender(dev->bwin, dev->x + dev->lastposition + dev->bwin->app->resources[dev->panel].sx - 7, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->position - dev->lastposition + (dev->width >> 2) + 5, dev->height + 9); } else { brightonFinalRender(dev->bwin, dev->x + dev->position + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->lastposition - dev->position + (dev->width >> 2), dev->height + 7); } } else { if (dev->lastposition >= 0) { brightonDevUndraw(dev->bwin, dev->bwin->dlayer, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + ((int) dev->lastposition) + dev->bwin->app->resources[dev->panel].sy - 1, dev->width, dev->height / 4 + 1); brightonRenderShadow(dev, 1); } dev->position = displayvalue * (dev->height - dev->height / 4); /* * Drawbars are only ever rendered vertically. */ if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_HSCALE) { brightonDevUndraw(dev->bwin, dev->bwin->dlayer, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width, dev->height); brightonStretch(dev->bwin, dev->image2, dev->bwin->dlayer, (int) (dev->x + dev->bwin->app->resources[dev->panel].sx), (int) (dev->y + dev->bwin->app->resources[dev->panel].sy), dev->width, (int) dev->position, 0); brightonFinalRender(dev->bwin, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width, (int) dev->height); } /* * Only draw fixed number of steps. Panned. Just draw it..... */ brightonStretch(dev->bwin, dev->image, dev->bwin->dlayer, dev->x + dev->bwin->app->resources[dev->panel].sx, (int)(dev->y + dev->position + dev->bwin->app->resources[dev->panel].sy), dev->width, dev->height / 4, 0); brightonRenderShadow(dev, 0); /* * And request the panel to put this onto the respective image. */ if (dev->position > dev->lastposition) { brightonFinalRender(dev->bwin, dev->x + dev->bwin->app->resources[dev->panel].sx - 1, dev->y + dev->lastposition + dev->bwin->app->resources[dev->panel].sy - 1, dev->width * 2 + 1, dev->position - dev->lastposition + (dev->height >> 2) + (dev->width >> 1) + 1); } else { brightonFinalRender(dev->bwin, dev->x + dev->bwin->app->resources[dev->panel].sx - 1, dev->y + dev->position + dev->bwin->app->resources[dev->panel].sy, dev->width * 2 + 1, dev->lastposition - dev->position + (dev->height >> 2) + 1 + (dev->width >> 1)); } } dev->lastvalue = dev->value; dev->lastposition = dev->position; return(0); } static void considercallback(brightonDevice *dev) { brightonIResource *panel = &dev->bwin->app->resources[dev->panel]; float callvalue; if (dev->bwin->flags & BRIGHTON_NO_DRAW) return; if (dev->value > 1.0) dev->value = 1.0; else if (dev->value < 0) dev->value = 0.0; /* * Due to the co-ordinate system, if we do NOT have the reverse flags * then we need to reverse the value. */ if ((dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_REVERSE) == 0) callvalue = 1.0 - dev->value; else callvalue = dev->value; if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].to != 1.0) { callvalue = (callvalue * dev->bwin->app->resources[dev->panel].devlocn[dev->index].to); if ((callvalue - ((int) callvalue)) > 0.5) callvalue = ((float) ((int) callvalue) + 1); else callvalue = ((float) ((int) callvalue)); } if (dev->lastvalue != dev->value) { if (panel->devlocn[dev->index].callback) { panel->devlocn[dev->index].callback(dev->bwin, dev->panel, dev->index, callvalue); } else { if (panel->callback) panel->callback(dev->bwin, dev->panel, dev->index, callvalue); } } } static int cx, cy; static float sval; static int configure(brightonDevice *dev, brightonEvent *event) { /* printf("configureScale(%i, %f)\n", event->command, event->value); */ if (event->command == -1) return(-1); if (event->command == BRIGHTON_RESIZE) { dev->originx = event->x; dev->originy = event->y; dev->x = event->x; dev->y = event->y; dev->width = event->w; dev->height = event->h; /* * We should now rework our parent understanding of our window, since * it will have altered. NOT NECESSARY FOR SCALE. brightonPanelLocation(dev->bwin, dev->panel, dev->index, dev->x, dev->y, dev->width, dev->height); considercallback(dev); */ /* * Highlights need to be rendered dynamically in displayscale(). */ dev->lastvalue = -1; displayscale(dev); return(0); } if (event->command == BRIGHTON_KEYRELEASE) { /* * This is a little bit 'happens they work'. We should fix these key * mappings for keycodes. */ switch(event->key) { default: break; case 37: case 66: case 109: case 65508: case 65507: dev->flags &= ~BRIGHTON_CONTROLKEY; cx = cy = sval = -1; break; case 50: case 62: case 65505: dev->flags &= ~BRIGHTON_SHIFTKEY; break; } } if (event->command == BRIGHTON_BUTTONPRESS) { /* * This is hard coded, it calls back to the GUI. This is incorrect as * the callback dispatcher should be requested by the GUI. * * Perhaps the MIDI code should actually be in the same library? Why * does the GUI need to know about this? */ if (event->key == BRIGHTON_BUTTON2) brightonRegisterController(dev); cx = event->x; cy = event->y; return(0); } if (event->command == BRIGHTON_BUTTONRELEASE) { cx = cy = sval = -1; dev->flags &= ~BRIGHTON_CONTROLKEY; if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_CENTER) { dev->value = 0.5; considercallback(dev); displayscale(dev); } return(0); } if (event->command == BRIGHTON_KEYPRESS) { switch(event->key) { default: break; case 37: case 66: case 109: case 65508: case 65507: cx = event->x; cy = event->y; sval = dev->value; dev->flags |= BRIGHTON_CONTROLKEY; break; case 50: case 62: case 65505: dev->flags |= BRIGHTON_SHIFTKEY; break; case 0x6a: case 0xff54: if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_VERTICAL) { if (dev->flags & BRIGHTON_SHIFTKEY) dev->value -= ((float) 256) / 16384; else dev->value -= ((float) 1) / 16384; } else { if (dev->flags & BRIGHTON_SHIFTKEY) dev->value += ((float) 256) / 16384; else dev->value += ((float) 1) / 16384; } break; case 0x6b: case 0xff52: /*if (dev->flags & BRIGHTON_VERTICAL) */ if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_VERTICAL) { if (dev->flags & BRIGHTON_SHIFTKEY) dev->value += ((float) 256) / 16384; else dev->value += ((float) 1) / 16384; } else { if (dev->flags & BRIGHTON_SHIFTKEY) dev->value -= ((float) 256) / 16384; else dev->value -= ((float) 1) / 16384; } break; case 0xff51: if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_VERTICAL) { if (dev->flags & BRIGHTON_SHIFTKEY) dev->value -= ((float) 2048) / 16384; else dev->value -= ((float) 32) / 16384; } else { if (dev->flags & BRIGHTON_SHIFTKEY) dev->value += ((float) 2048) / 16384; else dev->value += ((float) 32) / 16384; } break; case 0xff53: /*if (dev->flags & BRIGHTON_VERTICAL) */ if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_VERTICAL) { if (dev->flags & BRIGHTON_SHIFTKEY) dev->value += ((float) 2048) / 16384; else dev->value += ((float) 32) / 16384; } else { if (dev->flags & BRIGHTON_SHIFTKEY) dev->value -= ((float) 2048) / 16384; else dev->value -= ((float) 32) / 16384; } break; } considercallback(dev); displayscale(dev); } if (event->command == BRIGHTON_MOTION) { if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_VERTICAL) { /* * Need to add in an optional central dead spot. This should be a * small fraction of either side of the pot. It will be where * position deviates from mouse location. if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_NOTCH) { } else */ if (dev->flags & BRIGHTON_CONTROLKEY) { float deltax; if (cx == -1) { sval = dev->value; cx = event->x; cy = event->y; } deltax = ((float) (event->x - cx)) / 16383.0f; dev->value = sval + deltax; } else if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_NOTCH) { /* * When we are passing zero we should hold for a bit. */ dev->value = (((float) (event->x + 5 - dev->x - (dev->width / 8))) / (dev->width - dev->width / 4)); if (dev->value > 0.6) dev->value -= 0.1; else if (dev->value < 0.4) dev->value += 0.1; else dev->value = 0.5; } else { /* Fanning scaler controls */ if ((event->y - dev->y) > dev->height) { dev->value = (((float) (cx - dev->x - (dev->width / 8))) / (dev->width - dev->width / 4)); dev->value += (event->x - cx) / (16.0 * (1.0 + event->y - dev->y - dev->height/2)); } else if ((event->y - dev->y) < -dev->height) { dev->value = (((float) (cx - dev->x - (dev->width / 8))) / (dev->width - dev->width / 4)); dev->value -= (event->x - cx) / (16.0 * (1.0 + event->y - dev->y - dev->height/2)); } else { cx = event->x; dev->value = (((float) (event->x + 5 - dev->x - (dev->width / 8))) / (dev->width - dev->width / 4)); } } } else { if (dev->flags & BRIGHTON_CONTROLKEY) { float deltax; if (cx == -1) { sval = dev->value; cx = event->x; cy = event->y; } deltax = ((float) (event->y - cy)) / 16383.0f; dev->value = sval + deltax; } else if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_NOTCH) { dev->value = (((float) (event->y - dev->y - (dev->height / 8))) / (dev->height - dev->height / 4)); if (dev->value > 0.6) dev->value -= 0.1; else if (dev->value < 0.4) dev->value += 0.1; else dev->value = 0.5; } else { /* Fanning scaler controls */ // } else if (dev->bwin->flags & BRIGHTON_ROTARY_UD) { if ((event->x - dev->x) > dev->width) { dev->value = (((float) (cy - dev->y - (dev->height / 8))) / (dev->height - dev->height / 4)); dev->value += (event->y - cy) / (16.0 * (1.0 + event->x - dev->x - dev->width/2)); } else if ((event->x - dev->x) < -dev->width) { dev->value = (((float) (cy - dev->y - (dev->height / 8))) / (dev->height - dev->height / 4)); dev->value -= (event->y - cy) / (16.0 * (1.0 + event->x - dev->x - dev->width/2)); } else { cy = event->y; dev->value = (((float) (event->y - dev->y - (dev->height / 8))) / (dev->height - dev->height / 4)); } } } /*printf("scale motion %i %i, %i %i, %i %i: %f\n", */ /*event->x, event->y, dev->x, dev->y, dev->width, dev->height, dev->value); */ /* * We now need to consider rounding this to the resolution of this * device. If the max value is not 1.0 then we need to put fixed steps * into our new device value. */ if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].to != 1.0) { dev->value = (float) ((int) (dev->value * dev->bwin->app->resources[dev->panel].devlocn[dev->index].to)) / dev->bwin->app->resources[dev->panel].devlocn[dev->index].to; } considercallback(dev); displayscale(dev); return(0); } if (event->command == BRIGHTON_PARAMCHANGE) { if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_REVERSE) dev->value = event->value / dev->bwin->app->resources[dev->panel].devlocn[dev->index].to; else { if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].to != 1.0) { dev->value = (dev->bwin->app->resources[dev->panel].devlocn[dev->index].to - event->value) / dev->bwin->app->resources[dev->panel].devlocn[dev->index].to; } else { dev->value = (1.0 - event->value) / dev->bwin->app->resources[dev->panel].devlocn[dev->index].to; } } considercallback(dev); displayscale(dev); return(0); } return(0); } int * createScale(brightonWindow *bwin, brightonDevice *dev, int index, char *bitmap) { /* printf("createScale(%s)\n", bitmap); */ dev->destroy = destroyScale; dev->configure = configure; dev->index = index; dev->bwin = bwin; if (bitmap == 0) { if (dev->image) brightonFreeBitmap(bwin, dev->image); /* * Open the default bitmap */ if (bwin->app->resources[dev->panel].devlocn[dev->index].image != 0) dev->image = bwin->app->resources[dev->panel].devlocn[dev->index].image; else dev->image = brightonReadImage(bwin, "bitmaps/knobs/slider1.xpm"); } else { if (dev->image) brightonFreeBitmap(bwin, dev->image); dev->image = brightonReadImage(bwin, bitmap); } if (bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_HSCALE) { if (dev->image2) brightonFreeBitmap(bwin, dev->image2); dev->image2 = brightonReadImage(bwin, "bitmaps/knobs/extend.xpm"); } /* * These will force an update when we first display ourselves. */ if (bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_CENTER) dev->value = 0.5; else dev->value = 0; dev->value = 0.500001; dev->lastvalue = -1; dev->lastposition = 0; return(0); } bristol-0.60.11/libbrighton/brightonFastTimer.c0000644000175000017500000000775711746476474016424 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* * Fast timer events. * * Devices are registered for fast timers, the callback should occur on the * clock cycle. */ #include "brightoninternals.h" #define _BRIGHTON_FT_GO 0x0001 #define _BRIGHTON_FT_ON 0x0002 #define _BRIGHTON_FT_COUNT 128 static struct { struct { brightonWindow *win; int panel; int index; } ftl[_BRIGHTON_FT_COUNT]; int tick, duty; int current; int in, out, total; int flags; } brightonFTL; static void brightonScanTimerList(int ms) { brightonEvent event; //printf("ScanFastTimerList(%i): %i/%i\n", ms, brightonFTL.tick, brightonFTL.duty); if (brightonFTL.total == 0) return; if ((brightonFTL.current += ms) >= brightonFTL.tick) { event.command = BRIGHTON_FAST_TIMER; if (brightonFTL.flags & _BRIGHTON_FT_ON) { /* Previous led is still on */ event.value = 0; brightonParamChange( brightonFTL.ftl[brightonFTL.out].win, brightonFTL.ftl[brightonFTL.out].panel, brightonFTL.ftl[brightonFTL.out].index, &event); } if (++brightonFTL.out >= brightonFTL.total) brightonFTL.out = 0; brightonFTL.current = 0; brightonFTL.flags |= _BRIGHTON_FT_ON; /* * Send ON event */ event.value = 1.0; brightonParamChange( brightonFTL.ftl[brightonFTL.out].win, brightonFTL.ftl[brightonFTL.out].panel, brightonFTL.ftl[brightonFTL.out].index, &event); } else { if ((brightonFTL.current >= brightonFTL.duty) && (brightonFTL.flags & _BRIGHTON_FT_ON)) { brightonFTL.flags &= ~_BRIGHTON_FT_ON; /* * Send OFF event */ event.command = BRIGHTON_FAST_TIMER; event.value = 0; brightonParamChange( brightonFTL.ftl[brightonFTL.out].win, brightonFTL.ftl[brightonFTL.out].panel, brightonFTL.ftl[brightonFTL.out].index, &event); } } } static int brightonFTRegister(brightonWindow *win, int panel, int index) { //printf("Req: %i %i/%i\n", brightonFTL.in, panel, index); if (brightonFTL.in >= _BRIGHTON_FT_COUNT) return(-1); brightonFTL.ftl[brightonFTL.in].win = win; brightonFTL.ftl[brightonFTL.in].panel = panel; brightonFTL.ftl[brightonFTL.in++].index = index; return(++brightonFTL.total); } static int brightonFTDegister(brightonWindow *win, int panel, int index, int id) { brightonFTL.flags = 0; brightonFTL.in = 0; brightonFTL.out = 0; brightonFTL.total = 0; brightonFTL.current = 0; return(-1); } int brightonFastTimer(brightonWindow *win, int panel, int index, int command, int ms) { //printf("brightonFastTimer(%i, %i)\n", command, ms); switch (command) { case BRIGHTON_FT_CLOCK: if (brightonFTL.flags & _BRIGHTON_FT_GO) brightonScanTimerList(ms); break; case BRIGHTON_FT_TICKTIME: brightonFTL.tick = ms; break; case BRIGHTON_FT_DUTYCYCLE: brightonFTL.duty = ms; break; case BRIGHTON_FT_START: if (brightonFTL.flags & _BRIGHTON_FT_GO) brightonFTL.flags &= ~_BRIGHTON_FT_GO; else brightonFTL.flags |= _BRIGHTON_FT_GO; break; case BRIGHTON_FT_STOP: default: brightonFTL.flags &= ~_BRIGHTON_FT_GO; brightonFTL.out = 0; brightonFTL.current = 0; break; case BRIGHTON_FT_REQ: return(brightonFTRegister(win, panel, index)); case BRIGHTON_FT_CANCEL: return(brightonFTDegister(win, panel, index, command)); case BRIGHTON_FT_STEP: break; } return(0); } bristol-0.60.11/libbrighton/brightonXpmRead.c0000644000175000017500000002735611746476474016063 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include #include #include #include #include #include #include "brightoninternals.h" static int hex2num(char); static int xpmchar2num(brightonBitmap *,char); static int convertindex(brightonBitmap *, char *, int); static int convertcolor(char *); extern void brightonSprintColor(brightonWindow *, char *, int); #define BUFSIZE 8192 #define CTAB_SIZE 2048 /* * In the next peice of code we are calling brightonfopen(), brightonfgets() * and brightonfclose(), these are empty stubs that would get removed at * -O3 or so however I have used them at times for debugging heap corruption * and the overhead is minimal and only affects startup, not runtime. */ brightonBitmap * xpmread(brightonWindow *bwin, char *filename) { int color, width = 0, height = 0, colors = 0, bpcolor = 0, i = 1, j; int innerstatic = -1, outerstatic = -1; FILE *fd; char line[BUFSIZE]; int *colormap; brightonBitmap *bitmap; /* * This code was added to allow using compressed images reducing the size * of the installation to about 1/5th. It spools the gz to /tmp if the xpm * is not found and gunzips. */ if ((fd = brightonfopen(filename, "r")) == (FILE *) NULL) { int status; char tfn[256];; pid_t child; char *params[10]; sprintf(line, "%s.gz", filename); sprintf(tfn, "/tmp/bbm_%i.xpm.gz", getpid()); if ((fd = brightonfopen(line, "r")) == (FILE *) NULL) return(NULL); brightonfclose(fd); if ((child = fork()) == 0) { params[0] = "cp"; params[1] = "-f"; params[2] = line; params[3] = tfn; params[4] = NULL; if ((child = execvp("cp", params)) < 0) { printf("\nCannot spool the compressed source bitmap\n\n"); } exit(1); } else waitpid(child, &status, 0); if (status) { printf("Error copying %s to %s: %i\n", line, tfn, status); exit(1); } if ((child = fork()) == 0) { params[0] = "gunzip"; params[1] = "-f"; params[2] = tfn; params[3] = NULL; if ((child = execvp("gunzip", params)) < 0) { printf("\nCannot finding the gunzip binary, install it or "); printf("email author for an\nalternative resolution\n\n"); } exit(1); } else waitpid(child, &status, 0); if (status) exit(1); unlink(tfn); /* unlink the zipped file - on error may exist */ sprintf(tfn, "/tmp/bbm_%i.xpm", getpid()); if ((fd = brightonfopen(tfn, "r")) == (FILE *) NULL) { unlink(tfn); return(NULL); } unlink(tfn); } /* printf("xpmread(\"%s\")\n", filename); */ while ((brightonfgets(line, BUFSIZE, fd)) != 0) { /* * We are looking for numbers: */ if (!isdigit(line[1])) continue; else { /* * Should be able to get width, height, colors and planes from this * line of text. */ while (isdigit(line[i])) width = width * 10 + line[i++] - '0'; if (line[i++] != ' ') { brightonfclose(fd); return(0); } while (isdigit(line[i])) height = height * 10 + line[i++] - '0'; if (line[i++] != ' ') { brightonfclose(fd); return(0); } while (isdigit(line[i])) colors = colors * 10 + line[i++] - '0'; if (line[i++] != ' ') { brightonfclose(fd); return(0); } while (isdigit(line[i])) bpcolor = bpcolor * 10 + line[i++] - '0'; if (line[i] != '"') { while (line[i] == ' ') i++; innerstatic = 0; while (isdigit(line[i])) innerstatic = innerstatic * 10 + line[i++] - '0'; if (line[i] != '"') { while (line[i] == ' ') i++; outerstatic = 0; while (isdigit(line[i])) outerstatic = outerstatic * 10 + line[i++] - '0'; } if (line[i] != '"') { brightonfclose(fd); return(0); } } break; } } bitmap = brightonCreateBitmap(bwin, width, height); if (bitmap->pixels == NULL) bitmap->pixels = (int *) brightonmalloc((2 + width) * (2 + height) * sizeof(int)); bitmap->width = width; bitmap->height = height; bitmap->ncolors = colors; bitmap->ctabsize = colors; bitmap->uses = 0; bitmap->istatic = innerstatic; bitmap->ostatic = width > height? height / 2: width /2; if (outerstatic != -1) { if (width > height) { if (outerstatic < (height / 2)) bitmap->ostatic = outerstatic; } else { if (outerstatic < (width / 2)) bitmap->ostatic = outerstatic; } } colormap = (int *) brightonmalloc(colors * sizeof(int)); if (bitmap->colormap) brightonfree(bitmap->colormap); bitmap->colormap = colormap; /* * We now have some reasonable w, h, c and p. Need to parse c color lines. * We have to build a table of the character indeces from the XPM file. To * do this we need a character table and index. Rather than define them in * this file I am going to re-use some parts of the bitmap structure. */ bitmap->name = brightonmalloc(CTAB_SIZE * sizeof(char)); for (i = 0; i < colors;i++) { short r, g, b; if (brightonfgets(line, BUFSIZE, fd) == 0) { brightonfclose(fd); printf("e1: %s\n", filename); return(bitmap); } if (((line[bpcolor + 1] != '\t') && (line[bpcolor + 1] != ' ')) || ((line[bpcolor + 2] != 'c') && (line[bpcolor + 2] != 'g'))) { brightonfclose(fd); printf("e2: %s: %i %i, %s\n", filename, bpcolor, colors, line); return(bitmap); } if (strncmp("None", &line[4 + bpcolor], 4) == 0) { color = convertindex(bitmap, &line[1], bpcolor); colormap[i] = brightonGetGCByName(bwin, "Blue"); continue; } /* * We need to make a new convertindex that builds its own index table * based on the characters in the xpm file. */ color = convertindex(bitmap, &line[1], bpcolor); if ((color = convertcolor(&line[bpcolor + 4])) < 0) { line[strlen(line) - 3] = '\0'; colormap[i] = brightonGetGCByName(bwin, &line[bpcolor + 4]); } else { /* * Call the color manager to get a GC with this color for eventual * rendering. * * XPM has color from 0 to 255. getGC wants 16 bit values. */ r = (color >> 16) * 256; g = ((color >> 8) & 0xff) * 256; b = (color & 0x00ff) * 256; /* * Brighton color manager is going to find this color, and return * it if found, return a new GC if there is space, or a best match * if not. */ colormap[i] = brightonGetGC(bwin, r, g, b); } } for (i = 0; i < height;i++) { if (brightonfgets(line, BUFSIZE, fd) == 0) { brightonfclose(fd); printf("e3: %s\n", filename); return(bitmap); } if (line[0] != '\"') continue; for (j = 0; j < width * bpcolor; j+=bpcolor) { color = convertindex(bitmap, &line[j + 1], bpcolor); if (color < 0) { brightonfclose(fd); printf("e4: %s, %i/%i\n", filename, color, colors); return(bitmap); } else if (color >= colors) { // printf("e5: %s, %i/%i\n", filename, color, colors); bitmap->pixels[i * width + j / bpcolor] = colormap[colors - 1]; } else { bitmap->pixels[i * width + j / bpcolor] = colormap[color]; } } } /* Free this temporary holder */ brightonfree(bitmap->name); bitmap->name = (char *) brightonmalloc(strlen(filename) + 1); sprintf(bitmap->name, "%s", filename); /* bitmap->colormap = colormap; */ bitmap->uses = 1; brightonfclose(fd); return(bitmap); } static int hex2num(char c) { if (isxdigit(c)) { switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': return(c - '0'); case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': return(c - 'a' + 10); default: return(c - 'A' + 10); } } return(-1); } static int convertcolor(char *line) { int i = 0, color = 0, digit; if (strcmp(line, "none") == 0) return(0); else if (strcmp(line, "None") == 0) return(0); if (line[0] != '#') return(-1); line++; while (line[i] != '"') { if ((digit = hex2num(line[i])) < 0) return(0); color = color * 16 + digit; i++; } return(color); } static int convertindex(brightonBitmap *bitmap, char *line, int bpc) { int cindex = 0, i = 0, j = 1; while (i < bpc) { cindex = cindex + xpmchar2num(bitmap, line[i]) * j; j += 91; i++; } return(cindex); } int xpmchar2num(brightonBitmap *bitmap, char c) { int i; for (i = 0; i < bitmap->uses; i++) if (c == bitmap->name[i]) return(i); /*printf("", bitmap->uses, i); */ /* * If we got here then the character has not been assigned yet. */ bitmap->name[bitmap->uses] = (int) c; bitmap->uses++; return(i); } int writeLine(int fd, char *line) { return(write(fd, line, strlen(line))); } #define SAVE_IMAGE #ifdef SAVE_IMAGE #include #include #include int brightonXpmWrite(brightonWindow *bwin, char *file) { int fd, x, y, color, lindex; int colors[4096], cindex = 0, ccnt = 0, coff = 0, cagg = 0; long *points; char *line; char cstring[16], filename[64]; sprintf(filename, "/tmp/%s.xpm", bwin->template->name); if ((fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0770)) < 0) return(0); points = brightonmalloc(sizeof(long) * bwin->width * bwin->height); line = brightonmalloc(sizeof(char) * (bwin->width + 10) * 2); writeLine(fd, "/* XPM */\n"); writeLine(fd, "static char * brighton_xpm[] = {\n"); /* * We need to scan the image to see how many colors it implements. From this * we should build a character table, and then we should scan through the * image printing these characters. */ for (y = 0; y < bwin->render->height; y++) { for (x = 0; x < bwin->render->width; x++) { color = bwin->render->pixels[x + y * bwin->render->width]; for (cindex = 0; cindex < ccnt; cindex++) { if (color == colors[cindex]) { /* * This can't work: points[x][y] = cindex; hence */ points[x + y * bwin->render->width] = cindex; break; } } if (cindex == ccnt) { colors[cindex] = color; ccnt++; } /* * This can't work: points[x][y] = cindex; hence */ points[x + y * bwin->render->width] = cindex; } } sprintf(line, "\"%i %i %i %i\",\n", bwin->width, bwin->height, ccnt, 2); writeLine(fd, line); for (cindex = 0; cindex < ccnt; cindex++) { /* * We have to be reasonably intelligent with the color indeces. The * first attempt failed when we went over about 80 colors. The index * needs to become a string. We could go for two digits immediately? */ brightonSprintColor(bwin, cstring, colors[cindex]); sprintf(line, "\"%c%c c %s\",\n", coff + 35, cagg + 35, cstring); if (++cagg >= 90) { cagg = 0; coff++; } writeLine(fd, line); } for (y = 0; y < bwin->height; y++) { lindex = 1; sprintf(line, "\""); for (x = 0; x < bwin->width; x++) { cagg = points[x + y * bwin->render->width] % 90; coff = points[x + y * bwin->render->width] / 90; sprintf(&line[lindex], "%c%c", coff + 35, cagg + 35); lindex+=2; } sprintf(&line[lindex], "\"\n"); writeLine(fd, line); } writeLine(fd, "};\n\n"); brightonfree(points); brightonfree(line); close(fd); printf("Image written to %s, %i colors\n", filename, ccnt); printf("Width %i, Height %i\n", bwin->width, bwin->height); return(0); } #endif /* SAVE_IMAGE */ bristol-0.60.11/libbrighton/brightonHButton.c0000644000175000017500000002307711746476474016102 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* * This will be a highlighted button. Primarily used for the Bit emulators. */ #include #include "brightoninternals.h" extern int brightonPanelLocation(); char *tbm; int destroyHButton(brightonDevice *dev) { printf("destroyHButton()\n"); if (dev->image) brightonFreeBitmap(dev->bwin, dev->image); if (dev->image2) brightonFreeBitmap(dev->bwin, dev->image2); dev->image = NULL; dev->image2 = NULL; return(0); } static void displayhbutton(brightonDevice *dev) { int flags = dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags; if (dev->bwin->app->resources[dev->panel].flags & BRIGHTON_WITHDRAWN) return; if (flags & BRIGHTON_WITHDRAWN) return; /* * This is not needed except for moving parts - sliders primarily, but * also touch panels. Rotary and hbuttons are located and stay that way. */ brightonDevUndraw(dev->bwin, dev->bwin->dlayer, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + ((int) dev->lastposition) + dev->bwin->app->resources[dev->panel].sy, dev->width, dev->height); /* if (dev->value) id = brightonPut(dev->bwin, "bitmaps/buttons/green.xpm", dev->x, dev->y, dev->width, dev->height); else brightonRemove(dev->bwin, id); */ if (dev->value) brightonStretch(dev->bwin, dev->image2, dev->bwin->dlayer, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width, dev->height, flags); else brightonStretch(dev->bwin, dev->image, dev->bwin->dlayer, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width, dev->height, flags); brightonFinalRender(dev->bwin, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width, dev->height); dev->lastvalue = dev->value; dev->lastposition = dev->position; } /* * This will go into brighton render */ static int renderHighlights(brightonWindow *bwin, brightonDevice *dev) { float d, streak, dx, dy; brightonCoord p[8]; if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & (BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN)) return(0); dx = dev->x - bwin->lightX; dy = dev->y - bwin->lightY; d = sqrt((double) (dx * dx + dy * dy)); streak = (dev->width * 2.0 * d / bwin->lightH) / (1 - dev->width * 2.0 / bwin->lightH); p[0].x = dev->x; p[0].y = dev->y + dev->height; p[1].x = dev->x + dev->width; p[1].y = dev->y; p[2].x = dev->x + dx * streak / d; p[2].y = dev->y + dy * streak / d; /* XFillPolygon(bwin->display, bwin->background, bwin->cheap_shade, */ /* (XPoint *) &p, 3, Complex, CoordModeOrigin); */ return(0); } static int considercallback(brightonDevice *dev) { brightonIResource *panel = &dev->bwin->app->resources[dev->panel]; if ((dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_WITHDRAWN) || (dev->bwin->flags & BRIGHTON_NO_DRAW)) return(0); if ((dev->lastvalue != dev->value) || (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_CHECKBUTTON)) { if (panel->devlocn[dev->index].callback) { panel->devlocn[dev->index].callback(dev->bwin, dev->panel, dev->index, dev->value); } else { if (panel->callback) panel->callback(dev->bwin, dev->panel, dev->index, dev->value); } } return(0); } static int configure(brightonDevice *dev, brightonEvent *event) { /* printf("configureHButton(%i, %f)\n", dev->index, dev->value); */ if (dev->bwin->app->resources[dev->panel].flags & BRIGHTON_WITHDRAWN) return(0); if (event->command == -1) return(-1); if (event->command == BRIGHTON_RESIZE) { dev->x = event->x; dev->y = event->y; dev->width = event->w; dev->height = event->h; /* * We should consider altering the locations structure, so that * event dispatching is correct. */ if ((dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_CHECKBUTTON) == 0) considercallback(dev); brightonPanelLocation(dev->bwin, dev->panel, dev->index, dev->x, dev->y, dev->width, dev->height); /* * We need to build in some shadow, to prevent the hbutton from looking * like it is hanging in mid air. renderHighlights(dev->bwin, dev); */ dev->lastvalue = -1; displayhbutton(dev); return(0); } if (event->command == BRIGHTON_LEAVE) { if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_CHECKBUTTON) { dev->value = 0; displayhbutton(dev); } return(0); } if (event->command == BRIGHTON_ENTER) { if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_CHECKBUTTON) { dev->value = 1; displayhbutton(dev); } return(0); } if (event->command == BRIGHTON_BUTTONRELEASE) { if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_CHECKBUTTON) { dev->value = 0; displayhbutton(dev); if ((event->x >= dev->x) && (event->y >= dev->y) && (event->x < (dev->x + dev->width)) && (event->y < (dev->y + dev->height))) considercallback(dev); } return(0); } if (event->command == BRIGHTON_BUTTONPRESS) { brightonIResource *panel = &dev->bwin->app->resources[dev->panel]; if (event->key == BRIGHTON_BUTTON2) { brightonRegisterController(dev); return(0); } if (dev->value == 0) dev->value = panel->devlocn[dev->index].to; else dev->value = panel->devlocn[dev->index].from; if ((dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_CHECKBUTTON) == 0) considercallback(dev); displayhbutton(dev); return(0); } if (event->command == BRIGHTON_KEYPRESS) { brightonIResource *panel = &dev->bwin->app->resources[dev->panel]; if (event->key == 0x20) { if (dev->value == 0) dev->value = panel->devlocn[dev->index].to; else dev->value = panel->devlocn[dev->index].from; considercallback(dev); displayhbutton(dev); return(0); } /* * If this was not a space bar which we use to activate and de-activate * any arbitrary hbutton then it could be that we pressed some key that * can otherwise be interpretted. * This is awkward since here we are in a single hbutton and I would * like to use keypress to emulate a piano keyboard from the computer. * These events would have to be delivered to the parent, not to the * device, and the parent would then decide to which device the event * should be delivered. */ } if (event->command == BRIGHTON_KEYRELEASE) { /* * This is just to clear the event and repaint the key, we should not * be bothered with the callback. */ if (event->key == 0x20) { if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_CHECKBUTTON) { dev->value = 0; displayhbutton(dev); /* considercallback(dev); */ } } return(0); } if (event->command == BRIGHTON_PARAMCHANGE) { if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_CHECKBUTTON) { dev->value = 0; displayhbutton(dev); considercallback(dev); return(0); } dev->value = event->value; dev->lastvalue = -1; if ((dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_CHECKBUTTON) == 0) considercallback(dev); displayhbutton(dev); return(0); } return(0); } int * createHButton(brightonWindow *bwin, brightonDevice *dev, int index, char *bitmap) { brightonIResource *panel = &bwin->app->resources[dev->panel]; dev->destroy = destroyHButton; dev->configure = configure; dev->bwin = bwin; if (bitmap == NULL) { if (dev->image) brightonFreeBitmap(bwin, dev->image); /* * If we have been passed a specific image name for this device then * use it. */ if (panel->devlocn[dev->index].image != 0) dev->image = bwin->app->resources[dev->panel].devlocn[dev->index].image; else dev->image = brightonReadImage(bwin, "bitmaps/hbuttons/rockerred.xpm"); if (panel->devlocn[dev->index].image2 != 0) dev->image2 = bwin->app->resources[dev->panel].devlocn[dev->index].image2; else dev->image = brightonReadImage(bwin, "bitmaps/hbuttons/rockerred.xpm"); tbm = bitmap; } else { if (dev->image) brightonFreeBitmap(bwin, dev->image); if (panel->devlocn[dev->index].image != 0) dev->image = bwin->app->resources[dev->panel].devlocn[dev->index].image; else dev->image = brightonReadImage(bwin, bitmap); if (dev->image2) brightonFreeBitmap(bwin, dev->image2); dev->image2 = brightonReadImage(bwin, bwin->template->resources[dev->panel].devlocn[dev->index].image2); /* if (panel->devlocn[dev->index].image2 != 0) dev->image2 = bwin->app->resources[dev->panel].devlocn[dev->index].image2; */ } /* * These will force an update when we first display ourselves. */ dev->value = 0; dev->lastvalue = -1; dev->lastposition = -1; return(0); } bristol-0.60.11/libbrighton/brightonInterface.c0000644000175000017500000001320111746476474016403 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include #include "brightoninternals.h" extern void cleanout(brightonWindow *); brightonDisplay *dlist = 0; brightonWindow * brightonInterface(brightonApp *app, int quality, int library, int aa, float aad, int gs, int x, int y) { brightonDisplay *display; /* * Connect to the display. */ #ifdef BRIGHTON_HAS_X11 if (app->flags & BRIGHTON_WINDOW) { printf("brightonInterface(cli)\n"); display = brightonOpenDisplay("cli"); display->flags |= _BRIGHTON_WINDOW; } else if ((display = brightonOpenDisplay(NULL)) == 0) { printf("brightonInterface() failed\n"); return(0); } #else app->flags |= BRIGHTON_WINDOW; printf("brightonInterface(cli)\n"); display = brightonOpenDisplay("cli"); display->flags |= _BRIGHTON_WINDOW; #endif /* * Link it into our list. */ display->next = dlist; if (dlist) dlist->last = display; dlist = display; /* This should be made into an option and needs to be stuffed early */ if ((library != 0) && (display->flags & BRIGHTON_BIMAGE)) display->flags |= BRIGHTON_BIMAGE; else display->flags &= ~BRIGHTON_BIMAGE; if (aa & BRIGHTON_LIB_DEBUG) { printf("libbrighton debuging enabled\n"); display->flags |= BRIGHTON_LIB_DEBUG; } aa &= ~BRIGHTON_LIB_DEBUG; switch (aa) { case 1: display->flags |= BRIGHTON_ANTIALIAS_1; break; case 2: display->flags |= BRIGHTON_ANTIALIAS_2; break; case 3: display->flags |= BRIGHTON_ANTIALIAS_3; break; case 4: display->flags |= BRIGHTON_ANTIALIAS_4; break; case 5: display->flags |= BRIGHTON_ANTIALIAS_5; break; }; printf("brighton %p %i %i\n", app, app->width, app->height); /* * Request a new toplevel window for this app. */ if ((display->bwin = brightonCreateWindow(display, app, BRIGHTON_CMAP_SIZE, BRIGHTON_DEFAULT_ICON, quality, gs, x, y))) { if (display->flags & BRIGHTON_LIB_DEBUG) display->bwin->flags |= BRIGHTON_DEBUG; if ((display->bwin->quality = quality) < 2) display->bwin->quality = 2; else if (display->bwin->quality > 8) display->bwin->quality = 8; if (app->init) app->init(display->bwin); ((brightonWindow *) display->bwin)->display = display; /* * Map its panels and devices. Devices can be menus as well. */ brightonCreateInterface((brightonWindow *) display->bwin, app); display->bwin->antialias = aad; /*brightonEventLoop(&dlist); */ return(display->bwin); } return(0); } int brightonEventMgr() { return(brightonEventLoop(&dlist)); } int brightonRemoveInterface(brightonWindow *bwin) { brightonDisplay *d; printf("brightonRemoveInterface(%p)\n", bwin); bwin->flags |= BRIGHTON_EXITING; if ((d = brightonFindDisplay(dlist, (brightonDisplay *) bwin->display)) == 0) return(0); if (bwin->template->destroy != 0) bwin->template->destroy(bwin); BAutoRepeat(bwin->display, 1); brightonDestroyInterface(bwin); /* * Unlink the display */ if (d->next) d->next->last = d->last; if (d->last) d->last->next = d->next; else dlist = d->next; if (dlist == 0) { brightonDestroyWindow(bwin); cleanout(bwin); } /* * Remove window and its contents. */ brightonDestroyWindow(bwin); return(0); } /* * This will cover a bit of code will cover the timing for double click. It * will be tested here and should eventually go into the brighton library. * * First open a 'double click handle', send events that need to be checked, * and close the handle when no longer required. Closing is actually not * trivial here if we do not have a destroy routine. */ #include #define DC_TIMERS 128 struct { struct timeval time; int timeout; } dc_timers[DC_TIMERS]; int brightonGetDCTimer(int timeout) { int dcth; for (dcth = 0; dcth < DC_TIMERS; dcth++) if (dc_timers[dcth].timeout == 0) { dc_timers[dcth].time.tv_sec = timeout / 1000000; dc_timers[dcth].time.tv_usec = timeout % 1000000; // dc_timers[dcth].time.tv_usec = 0; dc_timers[dcth].timeout = timeout; return(dcth); } return(0); } void brightonFreeDCTimerHandle(int dcth) { dc_timers[dcth].time.tv_sec = 0; } int brightonDoubleClick(int dcth) { struct timeval current; int delta_uS; if ((dcth < 0) || (dcth >= DC_TIMERS)) return(0); gettimeofday(¤t, NULL); if ((current.tv_sec - dc_timers[dcth].time.tv_sec) > 1) { /* Not a double click */ dc_timers[dcth].time.tv_sec = current.tv_sec; dc_timers[dcth].time.tv_usec = current.tv_usec; return(0); } /* * So now build a delta of the time of the two clicks and see if it is * within the limit of the timer. */ if (current.tv_sec == dc_timers[dcth].time.tv_sec) delta_uS = current.tv_usec - dc_timers[dcth].time.tv_usec; else delta_uS = current.tv_usec + (1000000 - dc_timers[dcth].time.tv_usec); if (delta_uS < dc_timers[dcth].timeout) return(1); dc_timers[dcth].time.tv_sec = current.tv_sec; dc_timers[dcth].time.tv_usec = current.tv_usec; return(0); } /* * End of double click timer code. */ bristol-0.60.11/libbrighton/brightonPanelMgt.c0000644000175000017500000003732711746476474016231 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include "brightoninternals.h" extern void bvgRenderInt(brightonWindow *, char *, brightonBitmap *); #define MY_CALL 0x01 struct { unsigned int flags; int px, py; brightonBitmap frame; brightonPanel *panel; } window; void brightonCreatePanel(int x, int y, char *image) { window.px = x; window.py = y; window.flags |= MY_CALL; } int brightonDevUndraw(brightonWindow *bwin, brightonBitmap *dest, int ix, int iy, int w, int h) { int x, y, z, dy, s = dest->width * dest->height; /*printf("undraw %x %x %x, %i %i %i %i\n", */ /*bwin, dest, dest->pixels, ix, iy, w, h); */ for (y = iy; y <= (iy + h - 1); y++) { dy = y * dest->width; for (x = ix; x <= (ix + w - 1); x++) { if (((z = dy + x) < 0) || (z > s)) continue; dest->pixels[z] = -1; } } return(0); } void brightonPanelLocation(brightonWindow *bwin, int panel, int index, int x, int y, int width, int height) { bwin->app->resources[panel].devlocn[index].ax = x; bwin->app->resources[panel].devlocn[index].ay = y; bwin->app->resources[panel].devlocn[index].aw = width; bwin->app->resources[panel].devlocn[index].ah = height; } static brightonILocations *ldid = 0; static int configurePanel(brightonWindow *bwin, brightonIResource *panel, brightonEvent *event) { int dev; brightonILocations *device; /* printf("configure panel: %i\n", event->command); */ if (event->command == BRIGHTON_PARAMCHANGE) { if (event->type == BRIGHTON_EXPOSE) { if (event->intvalue) { //printf(" REQ EXPOSE %x %x\n", (size_t) event, (size_t) panel); panel->flags &= ~BRIGHTON_WITHDRAWN; event->command = BRIGHTON_RESIZE; event->x = panel->sx; event->y = panel->sy; event->w = panel->sw; event->h = panel->sh; brightonDevUndraw(bwin, bwin->dlayer, event->x, event->y, event->w, event->h); brightonDevUndraw(bwin, bwin->slayer, event->x, event->y, event->w, event->h); /* * We should also go through all the tools in the panel and * rerender their shadow. */ for (dev = 0; dev < panel->ndevices; dev++) { if (panel->devlocn[dev].type == 0) brightonRenderShadow( (brightonDevice *) panel->devlocn[dev].dev, 0); } } else { //printf(" REQ UNEXPOSE %x %x\n", (size_t) event, (size_t) panel); panel->flags |= BRIGHTON_WITHDRAWN; /* * On unexpose events we dont do any redraws? Conceptually we * only have overlapping panels, and EXPOSE/UNEXPOSE go in * pairs - the next event on another panel will draw over the * top of me. */ return(0); } } else return(0); } if (event->command == BRIGHTON_RESIZE) { panel->sx = event->x; panel->sy = event->y; panel->sw = event->w; panel->sh = event->h; /* * We need to configure our size and render any image and blueprints for * this panel. Then we need to call all our devices and make sure they * are also configured for their location within this panel. */ if (panel->canvas) brightonFreeBitmap(bwin, panel->canvas); panel->canvas = brightonCreateBitmap(bwin, event->w, event->h); if (panel->flags & BRIGHTON_WITHDRAWN) { /* * NOTE: * this was a fix for incorrect shadow rendering if panels are * resized whilst withdrawn. */ for (dev = 0; dev < panel->ndevices; dev++) { if (panel->devlocn[dev].type == -1) continue; event->x = (int) panel->devlocn[dev].x * panel->sw / 1000; event->y = (int) panel->devlocn[dev].y * panel->sh / 1000; event->w = (int) panel->devlocn[dev].width * panel->sw / 1000; event->h = (int) panel->devlocn[dev].height * panel->sh / 1000; brightonPanelLocation(bwin, panel->devlocn[dev].panel, panel->devlocn[dev].index, event->x, event->y, event->w, event->h); ((brightonDevice *) panel->devlocn[dev].dev)->configure( panel->devlocn[dev].dev, event); } return(0); } /* * Render our panel canvas. */ if (panel->surface == NULL) { /* * A few panels do not use a surface. This works, it gets filled as * 'Blue' and never gets rendered. It caused problems with the * prealiasing code since unless a surface is rendered then we * cannot do the antialiasing. To overcome this we paint the actual * content of the parent into the panel surface. * This is not as trivial as it seems as we actually want a window * into the backing store, most of which can be resolved by correct * placement of these elements in the image stacking order. */ brightonTesselate(bwin, bwin->canvas, panel->canvas, 0, 0, panel->sw, panel->sh, panel->flags); } else { if (panel->flags & BRIGHTON_STRETCH) brightonStretch(bwin, panel->surface, panel->canvas, 0, 0, panel->sw, panel->sh, panel->flags); else brightonTesselate(bwin, panel->surface, panel->canvas, 0, 0, panel->sw, panel->sh, panel->flags); } /* * This should be done with antialiasing since when it is scaled it * can look rather grizzly. Also, if we don't have a surface then we * should create a dummy one to allow for antialiasing. */ if ((bwin->display->flags & BRIGHTON_ANTIALIAS_5) || (bwin->display->flags & BRIGHTON_ANTIALIAS_2)) brightonStretchAlias(bwin, panel->image, panel->canvas, 0, 0, panel->sw, panel->sh, 0.2); else brightonStretch(bwin, panel->image, panel->canvas, 0, 0, panel->sw, panel->sh, 0); if (panel->image) bvgRenderInt(bwin, rindex(panel->image->name, '/'), panel->canvas); /* * And then render it onto the window cavas area */ brightonStretch(bwin, panel->canvas, bwin->canvas, panel->sx, panel->sy, panel->sw, panel->sh, BRIGHTON_ANTIALIAS); brightonFinalRender(bwin, panel->sx, panel->sy, panel->sw, panel->sh); for (dev = 0; dev < panel->ndevices; dev++) { if (panel->devlocn[dev].type == -1) continue; event->x = (int) panel->devlocn[dev].x * panel->sw / 1000; event->y = (int) panel->devlocn[dev].y * panel->sh / 1000; event->w = (int) panel->devlocn[dev].width * panel->sw / 1000; event->h = (int) panel->devlocn[dev].height * panel->sh / 1000; brightonPanelLocation(bwin, panel->devlocn[dev].panel, panel->devlocn[dev].index, event->x, event->y, event->w, event->h); ((brightonDevice *) panel->devlocn[dev].dev)->configure( panel->devlocn[dev].dev, event); } return(0); } device = brightonDeviceLocator(panel, event->x - panel->sx, event->y - panel->sy); if ((panel->flags & BRIGHTON_KEY_PANEL) || ldid) { brightonEvent nEv; //printf("keypanel\n"); /* * We may have to reinterpret some events. We want to have motion * tracking to move from key to key which means if the device ID changes * then send a BUTTONRELEASE on the previous ID and a BUTTONPRESS on * the new one. */ if (device != ldid) { //printf("release button\n"); memcpy(&nEv, event, sizeof(brightonEvent)); nEv.command = BRIGHTON_BUTTONRELEASE; nEv.x -= panel->sx; nEv.y -= panel->sy; if (bwin->activedev) ((brightonDevice *) bwin->activedev->dev)->configure (bwin->activedev->dev, &nEv); } if ((panel->flags & BRIGHTON_KEY_PANEL) && device) { if (ldid != device) { //printf("press button\n"); memcpy(&nEv, event, sizeof(brightonEvent)); nEv.command = BRIGHTON_BUTTONPRESS; nEv.x = event->x - panel->sx; nEv.y = event->y - panel->sy; ldid = bwin->activedev = device; ((brightonDevice *) device->dev)->configure (device->dev, &nEv); return(0); } } else { ldid = 0; bwin->activedev = 0; } } if (event->command == BRIGHTON_BUTTONRELEASE) { /*printf("panel button release: %i\n", bwin->activedev); */ if (bwin->activedev == 0) return(0); /* This should be simplified to Deliver the Event */ if ((bwin->app->resources[bwin->activedev->panel].devlocn[ bwin->activedev->index].flags & BRIGHTON_CENTER) || (bwin->app->resources[bwin->activedev->panel].devlocn[ bwin->activedev->index].type == 5)) { /* * Deliver the event. */ event->x -= panel->sx; event->y -= panel->sy; ((brightonDevice *) bwin->activedev->dev)->configure (bwin->activedev->dev, event); } else if (device == bwin->activedev) { /* * Deliver the event. */ event->x -= panel->sx; event->y -= panel->sy; ((brightonDevice *) bwin->activedev->dev)->configure (bwin->activedev->dev, event); } else { /* * Deliver the event. */ event->x -= panel->sx; event->y -= panel->sy; ((brightonDevice *) bwin->activedev->dev)->configure (bwin->activedev->dev, event); } bwin->activedev = 0; return(0); } if ((event->command == BRIGHTON_BUTTONPRESS) || (event->command == BRIGHTON_BUTTONRELEASE)) { /*printf("panel button press\n"); */ if ((bwin->activedev = device) == 0) return(0); /* * Deliver the event. */ event->x -= panel->sx; event->y -= panel->sy; ((brightonDevice *) bwin->activedev->dev)->configure (bwin->activedev->dev, event); return(0); } if (event->command == BRIGHTON_MOTION) { if (bwin->activedev) { /* * Deliver the event. */ event->x -= panel->sx; event->y -= panel->sy; if (bwin->activedev->flags & BRIGHTON_CHECKBUTTON) { if (device != bwin->activedev) { event->command = BRIGHTON_LEAVE; ((brightonDevice *) bwin->activedev->dev)->configure (bwin->activedev->dev, event); } else { event->command = BRIGHTON_ENTER; ((brightonDevice *) bwin->activedev->dev)->configure (bwin->activedev->dev, event); } } else { ((brightonDevice *) bwin->activedev->dev)->configure (bwin->activedev->dev, event); } } /* else { if (device->flags & BRIGHTON_TRACKING) { event->command = BRIGHTON_ENTER; device->configure(device, event); } } */ return(0); } if (event->command == BRIGHTON_KEYRELEASE) { /* * Deliver the event. */ event->x -= panel->sx; event->y -= panel->sy; if (bwin->activedev) { ((brightonDevice *) bwin->activedev->dev)->configure (bwin->activedev->dev, event); return(0); } if (device == 0) return(0); ((brightonDevice *) device->dev)->configure(device->dev, event); } if (event->command == BRIGHTON_KEYPRESS) { /* * Deliver the event. */ event->x -= panel->sx; event->y -= panel->sy; if (bwin->activedev) { ((brightonDevice *) bwin->activedev->dev)->configure (bwin->activedev->dev, event); return(0); } if (device == 0) return(0); ((brightonDevice *) device->dev)->configure(device->dev, event); } return(0); } static int brightonCreateDevices(brightonWindow *bwin, brightonResource *res, int index) { int i; brightonLocations *dev = res->devlocn; /*printf("brightonCreateDevices(%x, %x, %i)\n", bwin, res, index); */ bwin->app->resources[index].devlocn = (brightonILocations *) brightonmalloc(res->ndevices * sizeof(brightonILocations)); for (i = 0; i < res->ndevices; i++) { /*printf(" %s %i (%f,%f)/(%f,%f)\n %s, %s\n", */ /* dev[i].name, dev[i].device, */ /* dev[i].x, dev[i].y, dev[i].width, dev[i].height, */ /* dev[i].image, dev[i].image2); */ bwin->app->resources[index].devlocn[i].type = dev[i].device; bwin->app->resources[index].devlocn[i].index = i; bwin->app->resources[index].devlocn[i].panel = index; bwin->app->resources[index].devlocn[i].x = dev[i].x; bwin->app->resources[index].devlocn[i].y = dev[i].y; bwin->app->resources[index].devlocn[i].width = dev[i].width; bwin->app->resources[index].devlocn[i].height = dev[i].height; bwin->app->resources[index].devlocn[i].from = dev[i].from; bwin->app->resources[index].devlocn[i].to = dev[i].to; if (dev[i].device == -1) continue; bwin->app->resources[index].devlocn[i].callback = dev[i].callback; bwin->app->resources[index].devlocn[i].flags = dev[i].flags; bwin->app->resources[index].devlocn[i].image = brightonReadImage(bwin, dev[i].image); if (dev[i].image2 != 0) { bwin->app->resources[index].devlocn[i].image2 = brightonReadImage(bwin, dev[i].image2); } bwin->app->resources[index].devlocn[i].dev = (struct brightonDevice *) brightonCreateDevice(bwin, dev[i].device, index, i, dev[i].image); } return(0); } int brightonCreateInterface(brightonWindow *bwin, brightonApp *app) { int i; brightonResource *res; if (app == 0) return(0); /*printf("brightonCreateInterface(%x, %x)\n", bwin, app); */ bwin->template = app; bwin->app = (brightonIApp *) brightonmalloc(sizeof(brightonIApp)); bwin->app->nresources = app->nresources; bwin->app->flags = app->flags; bwin->app->init = app->init; /* if (bwin->app->init) */ /* bwin->app->init(bwin); */ bwin->app->resources = (brightonIResource *) brightonmalloc(bwin->app->nresources * sizeof(brightonIResource)); /* * Go through each panel on the app panels list, generate them, then do the * same for each device on each panel. */ for (i = 0; i < app->nresources; i++) { res = &app->resources[i]; /*printf("%s (%i,%i)/(%i,%i)\n %s, %s\n", res->name, */ /* res->x, res->y, res->width, res->height, */ /* res->image, res->surface); */ bwin->app->resources[i].x = res->x; bwin->app->resources[i].y = res->y; bwin->app->resources[i].width = res->width; bwin->app->resources[i].height = res->height; bwin->app->resources[i].flags = res->flags | BRIGHTON_ACTIVE; bwin->app->resources[i].image = brightonReadImage(bwin, res->image); bwin->app->resources[i].surface = brightonReadImage(bwin, res->surface); /* * We need to calculate our size, and then create a backgorund canvas * for panel rendering. This will only happen when the first configure * notify arrives. */ bwin->app->resources[i].init = res->init; bwin->app->resources[i].configure = configurePanel; bwin->app->resources[i].callback = res->callback; bwin->app->resources[i].ndevices = res->ndevices; brightonCreateDevices(bwin, res, i); } return(0); } static int brightonDestroyDevices(brightonWindow *bwin, brightonIResource *res) { int i; brightonILocations *dev = res->devlocn; brightonDevice *device = (brightonDevice *) dev->dev; for (i = 0; i < res->ndevices; i++) { device = (brightonDevice *) dev[i].dev; if ((device == 0) || (device->device == -1)) continue; brightonFreeBitmap(bwin, device->image); brightonFreeBitmap(bwin, device->image2); brightonFreeBitmap(bwin, bwin->app->resources[device->panel].devlocn[device->index].image); brightonFreeBitmap(bwin, bwin->app->resources[device->panel].devlocn[device->index].image2); /* brightoneDestroyDevice(bwin, dev->device); */ } brightonfree(res->devlocn); return(0); } int brightonDestroyInterface(brightonWindow *bwin) { int i; printf("brightonDestroyInterface(%p): %i\n", bwin, bwin->app->nresources); for (i = 0; i < bwin->app->nresources; i++) { /* * Since we are going to wipe out this interface, prevent any further * rendering. */ bwin->app->resources[i].flags |= BRIGHTON_WITHDRAWN; brightonDestroyDevices(bwin, &bwin->app->resources[i]); brightonFreeBitmap(bwin, bwin->app->resources[i].image); brightonFreeBitmap(bwin, bwin->app->resources[i].surface); } brightonfree(bwin->app->resources); brightonfree(bwin->app); return(0); } bristol-0.60.11/libbrighton/brightonRibbonKbd.c0000644000175000017500000001141211746476474016341 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include "math.h" #include "brightoninternals.h" static float winwidth, winheight; int destroyRibbon(brightonDevice *dev) { printf("destroyRibbon()\n"); if (dev->image) brightonFreeBitmap(dev->bwin, dev->image); dev->image = NULL; return(0); } static int displayRibben(brightonDevice *dev) { brightonIResource *panel; if (dev->bwin->app->resources[dev->panel].flags & BRIGHTON_WITHDRAWN) return(0); panel = &dev->bwin->app->resources[dev->panel]; dev->lastvalue = dev->value; dev->lastposition = dev->position; return(0); } static void considercallback(brightonDevice *dev) { brightonIResource *panel = &dev->bwin->app->resources[dev->panel]; if (dev->lastvalue != dev->value) { if (panel->devlocn[dev->index].callback) { panel->devlocn[dev->index].callback(dev->bwin, dev->panel, dev->index, dev->value); } else { if (panel->callback) panel->callback(dev->bwin, dev->panel, dev->index, dev->value); } } dev->lastvalue = dev->value; dev->lastposition = dev->position; } static float rbckeymap[40] = { 0.0f, 0.0f, 2.0f, 2.0f, 4.0f, 4.0f, 5.0f, 5.0f, 7.0f, 7.0f, 9.0f, 9.0f, 11.0f, 11.0f, 12.0f, 12.0f, 14.0f, 14.0f, 16.0f, 16.0f, 0.0f, 1.0f, 1.0f, 3.0f, 3.0f, 4.0f, 5.0f, 6.0f, 6.0f, 8.0f, 8.0f, 10.0f, 10.0f, 11.0f, 12.0f, 13.0f, 13.0f, 15.0f, 15.0f, 16.0f, }; static float getRibbonKey(int x, int y, int w, int h) { int v; if ((x <= 0) || (x >= w) || (y <= 0) || (y >= h)) return(-1.0f); if (((v = x * 20 / w) < 0) || (v >= 20)) return(-1.0f); if ((y << 1) < h) { /* Black key */ return(rbckeymap[v + 20]); } else { /* White key */ return(rbckeymap[v]); } return(-1.0f); } static int configure(brightonDevice *dev, brightonEvent *event) { //printf("configureRibbon(%i)\n", event->command); if (event->command == -1) return(-1); if (event->command == BRIGHTON_RESIZE) { dev->originx = event->x; dev->originy = event->y; dev->x = event->x; dev->y = event->y; dev->width = event->w; dev->height = event->h; //printf("Ribben resize %i %i, %i %i, %i %i: %f\n", //event->x, event->y, dev->x, dev->y, dev->width, dev->height, dev->value); dev->lastvalue = -1; displayRibben(dev); return(0); } if (event->command == BRIGHTON_BUTTONPRESS) { if (dev->width == 0) return(0); dev->value = getRibbonKey(event->x, event->y, dev->width, dev->height); //printf("Ribben press %i %i, %i %i, %i %i: %f\n", //event->x, event->y, dev->x, dev->y, dev->width, dev->height, dev->value); considercallback(dev); return(0); } if (event->command == BRIGHTON_BUTTONRELEASE) { //printf("Ribben release %i %i, %i %i, %i %i: %f\n", //event->x, event->y, dev->x, dev->y, dev->width, dev->height, dev->value); dev->value = -1; considercallback(dev); return(0); } if (event->command == BRIGHTON_MOTION) { //printf("Ribben motion %i %i, %i %i, %i %i: %f\n", //event->x, event->y, dev->x, dev->y, dev->width, dev->height, dev->value); dev->value = getRibbonKey(event->x, event->y, dev->width, dev->height); considercallback(dev); return(0); } return(0); } int * createRibbon(brightonWindow *bwin, brightonDevice *dev, int index, char *bitmap) { //printf("createRibbon(%s): %i\n", bitmap, index); winwidth = bwin->display->width / 2; winheight = bwin->display->height / 2; dev->destroy = destroyRibbon; dev->configure = configure; dev->index = index; dev->bwin = bwin; if (bitmap == 0) { if (dev->image) brightonFreeBitmap(bwin, dev->image); /* * Open the default bitmap */ if (bwin->app->resources[dev->panel].devlocn[dev->index].image != 0) dev->image = bwin->app->resources[dev->panel].devlocn[dev->index].image; if (dev->image == 0) dev->image = brightonReadImage(bwin, "bitmaps/images/pointer.xpm"); } else { if (dev->image) brightonFreeBitmap(bwin, dev->image); dev->image = brightonReadImage(bwin, bitmap); if (dev->image == 0) dev->image = brightonReadImage(bwin, "bitmaps/images/pointer.xpm"); } dev->lastvalue = -1; dev->lastposition = 0; return(0); } bristol-0.60.11/libbrighton/brightonEventHandlers.c0000644000175000017500000005400011746476474017247 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include #include #include "brightoninternals.h" #include "brightonX11.h" static float opacity = 1.0; /* * Much of this could do with a rework to make it more generic, at the moment * a lot of the key handlers are very bespoke. */ extern void brightonKeyInput(brightonWindow *, int, int); extern void brightonControlKeyInput(brightonWindow *, int, int); extern void brightonShiftKeyInput(brightonWindow *, int, int, int); extern void brightonControlShiftKeyInput(brightonWindow *, int, int, int); extern void printColorCacheStats(brightonWindow *); /* * TOOK THIS OUT BY POPULAR DEMAND */ //extern int brightonMenu(); int brightonKeyPress(brightonWindow *bwin, brightonEvent *event) { brightonIResource *panel; if (bwin->flags & BRIGHTON_DEBUG) printf("brightonKeyPress(%i)\n", event->key); if ((event->key == 'p') && (event->flags & BRIGHTON_MOD_CONTROL)) { brightonXpmWrite(bwin, "/tmp/brighton.xpm"); printColorCacheStats(bwin); } /* * All of the following up to the dispatch is for the top layer opacity, it * could go into a separate file? * * T should just be a toggle between totally opaque and the current * setting. There are a few other keys that are natively interpreted for * rather trivial reasons before being passed through to the GUI. These * implicit mappings should be dropped. */ if ((event->key == 't') && (event->flags & BRIGHTON_MOD_CONTROL)) { float hold; hold = bwin->opacity; bwin->opacity = opacity; opacity = hold; brightonFinalRender(bwin, 0, 0, bwin->width, bwin->height); } else if ((event->key == 'o') && (event->flags & BRIGHTON_MOD_CONTROL)) { /* * 'O' should be to make more opaque, 'o' more transparent. This is not * as * trivial as it seems since the shift key is always a separate * event. */ if (event->flags & BRIGHTON_MOD_SHIFT) { if (bwin->opacity == 1.0f) bwin->opacity = 0.2f; else if ((bwin->opacity += 0.1f) > 1.0f) bwin->opacity = 1.0f; brightonFinalRender(bwin, 0, 0, bwin->width, bwin->height); } else { if (bwin->opacity <= 0.21f) bwin->opacity = 1.0f; else if ((bwin->opacity -= 0.2f) < 0.2f) bwin->opacity = 0.2f; brightonFinalRender(bwin, 0, 0, bwin->width, bwin->height); } } /* * We now want to look to see if the request needs to be dispatched to any * devices. This means 'if the mouse is within any device then pass the key * event to that device. */ if ((bwin->flags & BRIGHTON_DEV_ACTIVE) && (bwin->activepanel != 0)) { bwin->activepanel->configure(bwin, bwin->activepanel, event); } else if ((panel = brightonPanelLocator(bwin, event->x, event->y)) > (brightonIResource *) NULL) { if (panel->configure) panel->configure(bwin, panel, event); } /* * Finally, as this is a key press event I want to pass it through to the * midi library. This is a rather ugly hack to have a more useful keyboard * mapping. We should only really do this from the keyboard panel, but that * if for later study. */ if ((event->flags & BRIGHTON_MOD_CONTROL) && (event->flags & BRIGHTON_MOD_SHIFT)) brightonControlShiftKeyInput(bwin, event->key, 1, event->flags); else if (event->flags & BRIGHTON_MOD_CONTROL) brightonControlKeyInput(bwin, event->key, 1); else if (event->flags & BRIGHTON_MOD_SHIFT) brightonShiftKeyInput(bwin, event->key, 1, event->flags); else brightonKeyInput(bwin, event->key, 1); return(0); } int brightonKeyRelease(brightonWindow *bwin, brightonEvent *event) { brightonIResource *panel; if (bwin->flags & BRIGHTON_DEBUG) printf("brightonKeyRelease(%i)\n", event->key); if ((bwin->flags & BRIGHTON_DEV_ACTIVE) && (bwin->activepanel != 0)) bwin->activepanel->configure(bwin, bwin->activepanel, event); else if ((panel = brightonPanelLocator(bwin, event->x, event->y)) > (brightonIResource *) NULL) { if (panel->configure) panel->configure(bwin, panel, event); } if (~event->flags & BRIGHTON_MOD_CONTROL) brightonKeyInput(bwin, event->key, 0); return(0); } int brightonButtonPress(brightonWindow *bwin, brightonEvent *event) { if (bwin->flags & BRIGHTON_DEBUG) printf("brightonButtonPress(%i)\n", event->key); /* * TOOK THIS OUT BY POPULAR DEMAND if (event->key == BRIGHTON_BUTTON3) { brightonMenu(bwin, event->x, event->y, 100, 200); return(0); } */ /* * We need to determine which device is under the selection, and force * statefull delivery of events to that device for further motion. */ bwin->activepanel = 0; if ((bwin->activepanel = brightonPanelLocator(bwin, event->x, event->y)) > (brightonIResource *) NULL) { bwin->flags |= BRIGHTON_DEV_ACTIVE; event->command = BRIGHTON_BUTTONPRESS; if (bwin->activepanel->configure) bwin->activepanel->configure(bwin, bwin->activepanel, event); } else bwin->flags &= ~BRIGHTON_DEV_ACTIVE; return(0); } int brightonButtonRelease(brightonWindow *bwin, brightonEvent *event) { if (bwin->flags & BRIGHTON_DEBUG) { if ((bwin) && (bwin->activepanel)) printf("brightonButtonRelease(%p, %p, %p)\n", bwin, bwin->activepanel, bwin->activepanel->configure); } event->command = BRIGHTON_BUTTONRELEASE; /* * TOOK THIS OUT BY POPULAR DEMAND if (event->key == BRIGHTON_BUTTON3) { brightonMenu(bwin, event->x, event->y, 100, 200); return(0); } */ /*if (bwin->activepanel && bwin->activepanel->configure) */ if ((bwin->flags & BRIGHTON_DEV_ACTIVE) && (bwin->activepanel != 0)) bwin->activepanel->configure(bwin, bwin->activepanel, event); bwin->flags &= ~BRIGHTON_DEV_ACTIVE; bwin->activepanel = 0; return(0); } int brightonMotionNotify(brightonWindow *bwin, brightonEvent *event) { if ((bwin->flags & BRIGHTON_DEV_ACTIVE) && (bwin->activepanel != 0)) { if (bwin->activepanel->configure) bwin->activepanel->configure(bwin, bwin->activepanel, event); } return(0); } static void brightonFillRatios(brightonWindow *win) { float wfact, hfact; wfact = ((float) win->display->width) * 0.95 / ((float) win->template->width); hfact = ((float) win->display->height) * 0.95 / ((float) win->template->height); if (hfact > wfact) { win->maxw = win->display->width * 0.95; win->minw = win->template->width; win->minh = win->template->height; win->maxh = win->template->height * wfact; } else { win->maxh = win->display->height * 0.95; win->minw = win->template->width; win->minh = win->template->height; win->maxw = win->template->width * hfact; } } int brightonEnterNotify(brightonWindow *bwin, brightonEvent *event) { if (bwin->flags & BRIGHTON_DEBUG) printf("brightonEnterNotify()\n"); #if (BRIGHTON_HAS_ZOOM == 1) if (bwin->flags & BRIGHTON_AUTOZOOM) { if (bwin->flags & BRIGHTON_DEBUG) printf("AutoZoom\n"); // Make sure we are initted if ((bwin->minh == 0) || (bwin->maxh == 0)) brightonFillRatios(bwin); bwin->display->flags |= BRIGHTON_ANTIALIAS_5; brightonRequestResize(bwin, bwin->template->width, bwin->template->height); if (bwin->flags & BRIGHTON_SET_RAISE) BRaiseWindow(bwin->display, bwin); } else #endif if (~bwin->flags & BRIGHTON_NO_ASPECT) { float aspect = ((float) bwin->width) / bwin->height; if ((aspect / bwin->aspect < 0.98) || ((aspect / bwin->aspect) > 1.02)) { /* Ratio has changed */ if (bwin->flags & _BRIGHTON_SET_HEIGHT) { if ((bwin->height * bwin->aspect) < ((brightonDisplay *) bwin->display)->width) bwin->width = bwin->height * bwin->aspect; else { bwin->width = ((brightonDisplay *) bwin->display)->width - 10; bwin->height = bwin->width / bwin->aspect; } } else { if ((bwin->width / bwin->aspect) < ((brightonDisplay *) bwin->display)->height) bwin->height = bwin->width / bwin->aspect; else { bwin->height = ((brightonDisplay *) bwin->display)->height - 10; bwin->width = bwin->height * bwin->aspect; } } if (bwin->flags & BRIGHTON_DEBUG) printf("changed aspect ratio: %f %i %i\n", aspect, bwin->width, bwin->height); BResizeWindow(bwin->display, bwin, bwin->width, bwin->height); brightonWorldChanged(bwin, bwin->width, bwin->height); } } bwin->flags &= ~_BRIGHTON_SET_HEIGHT; if (bwin->flags & BRIGHTON_EXITING) { BAutoRepeat(bwin->display, 1); return(0); } BAutoRepeat(bwin->display, 0); return(0); } int brightonLeaveNotify(brightonWindow *bwin, brightonEvent *event) { if (bwin->flags & BRIGHTON_DEBUG) printf("brightonLeaveNotify()\n"); #if (BRIGHTON_HAS_ZOOM == 1) if (bwin->flags & BRIGHTON_AUTOZOOM) { if (bwin->flags & BRIGHTON_DEBUG) printf("AutoZoom\n"); // Make sure we are initted if ((bwin->minh == 0) || (bwin->maxh == 0)) brightonFillRatios(bwin); // Flip the window size brightonRequestResize(bwin, bwin->minw, bwin->minh); if (bwin->flags & BRIGHTON_SET_LOWER) BLowerWindow(bwin->display, bwin); } else #endif if (~bwin->flags & BRIGHTON_NO_ASPECT) { float aspect = ((float) bwin->width) / bwin->height; if ((aspect / bwin->aspect < 0.98) || ((aspect / bwin->aspect) > 1.02)) { /* Ratio has changed */ if (bwin->flags & _BRIGHTON_SET_HEIGHT) { if ((bwin->height * bwin->aspect) < ((brightonDisplay *) bwin->display)->width) bwin->width = bwin->height * bwin->aspect; else { bwin->width = ((brightonDisplay *) bwin->display)->width - 10; bwin->height = bwin->width / bwin->aspect; } } else { if ((bwin->width / bwin->aspect) < ((brightonDisplay *) bwin->display)->height) bwin->height = bwin->width / bwin->aspect; else { bwin->height = ((brightonDisplay *) bwin->display)->height - 10; bwin->width = bwin->height * bwin->aspect; } } if (bwin->flags & BRIGHTON_DEBUG) printf("changed aspect ratio: %f %i %i\n", aspect, bwin->width, bwin->height); BResizeWindow(bwin->display, bwin, bwin->width, bwin->height); brightonWorldChanged(bwin, bwin->width, bwin->height); } } bwin->flags &= ~_BRIGHTON_SET_HEIGHT; BAutoRepeat(bwin->display, 1); return(0); } int brightonFocusIn(brightonWindow *bwin, brightonEvent *event) { if (bwin->flags & BRIGHTON_DEBUG) printf("brightonFocusIn()\n"); brightonEnterNotify(bwin, event); return(0); } int brightonFocusOut(brightonWindow *bwin, brightonEvent *event) { if (bwin->flags & BRIGHTON_DEBUG) printf("brightonFocusOut()\n"); brightonLeaveNotify(bwin, event); return(0); } int brightonKeymapNotify(brightonWindow *bwin, brightonEvent *event) { if (bwin->flags & BRIGHTON_DEBUG) printf("brightonKeymapNotify()\n"); return(0); } int brightonExpose(brightonWindow *bwin, brightonEvent *event) { if (bwin->flags & BRIGHTON_DEBUG) printf("brightonExpose(%i %i %i %i)\n", event->x, event->y, event->w, event->h); BCopyArea(bwin->display, event->x, event->y, event->w, event->h, event->x, event->y); return(0); } int brightonGraphicsExpose(brightonWindow *bwin, brightonEvent *event) { if (bwin->flags & BRIGHTON_DEBUG) printf("brightonGraphicsExpose()\n"); return(0); } int brightonNoExpose(brightonWindow *bwin, brightonEvent *event) { if (bwin->flags & BRIGHTON_DEBUG) printf("brightonNoExpose()\n"); return(0); } int brightonVisibilityNotify(brightonWindow *bwin, brightonEvent *event) { if (bwin->flags & BRIGHTON_DEBUG) printf("brightonVisibilityNotify()\n"); return(0); } int brightonCreateNotify(brightonWindow *bwin, brightonEvent *event) { if (bwin->flags & BRIGHTON_DEBUG) printf("brightonCreateNotify()\n"); return(0); } int brightonDestroyNotify(brightonWindow *bwin, brightonEvent *event) { /* * Counter intuitive, we do nothing here. The process gets a SIGPIPE and * the GUI intercepts this to request the engine to terminate the algo * represented by this GUI. Engine will terminate when all algos have * finished. */ if (bwin->flags & BRIGHTON_DEBUG) printf("brightonDestroyNotify()\n"); return(0); } int brightonUnmapNotify(brightonWindow *bwin, brightonEvent *event) { if (bwin->flags & BRIGHTON_DEBUG) printf("brightonUnmapNotify()\n"); return(0); } int brightonMapNotify(brightonWindow *bwin, brightonEvent *event) { if (bwin->flags & BRIGHTON_DEBUG) printf("brightonMapNotify()\n"); return(0); } int brightonMapRequest(brightonWindow *bwin, brightonEvent *event) { if (bwin->flags & BRIGHTON_DEBUG) printf("brightonMapRequest()\n"); return(0); } int brightonReparentNotify(brightonWindow *bwin, brightonEvent *event) { if (bwin->flags & BRIGHTON_DEBUG) printf("brightonReparentNotify()\n"); return(0); } int brightonConfigureNotify(brightonWindow *bwin, brightonEvent *event) { if (bwin->flags & BRIGHTON_DEBUG) printf("brightonConfigureNotify(%i, %i, %i, %i)\n", event->x, event->y, event->w, event->h); if (bwin->flags & BRIGHTON_SET_SIZE) { bwin->flags &= ~BRIGHTON_SET_SIZE; return(0); } if ((bwin->width != event->w) || (bwin->height != event->h)) brightonWorldChanged(bwin, event->w, event->h); /* This is wrong. */ // if ((bwin->width != event->w) || (bwin->height != event->h)) // BResizeWindow(bwin->display, bwin, bwin->width, bwin->height); return(0); } int brightonConfigureRequest(brightonWindow *bwin, brightonEvent *event) { if (bwin->flags & BRIGHTON_DEBUG) printf("brightonConfigureRequest()\n"); return(0); } int brightonGravityNotify(brightonWindow *bwin, brightonEvent *event) { if (bwin->flags & BRIGHTON_DEBUG) printf("brightonGravityNotify()\n"); return(0); } int brightonRequestResize(brightonWindow *bwin, int w, int h) { if (bwin->flags & BRIGHTON_DEBUG) printf("brightonResizeRequest(%i, %i)\n", w, h); if ((bwin->width != w) || (bwin->height != h)) { if ((bwin->width < w) && (bwin->flags & BRIGHTON_SET_RAISE)) BRaiseWindow(bwin->display, bwin); /* * Our size has changed. We need to re-render the background, and then * repaint it. */ BResizeWindow(bwin->display, bwin, w, h); brightonWorldChanged(bwin, w, h); } return(0); } int brightonResizeRequest(brightonWindow *bwin, brightonEvent *event) { if (bwin->flags & BRIGHTON_DEBUG) printf("brightonResizeRequest(%i, %i)\n", event->w, event->h); if ((bwin->width != event->w) || (bwin->height != event->h)) { /* * Our size has changed. We need to re-render the background, and then * repaint it. */ brightonWorldChanged(bwin, event->w, event->h); /* if ((bwin->width != event->w) || (bwin->height != event->h)) BResizeWindow(bwin->display, bwin->win, bwin->width, bwin->height); */ } return(0); } int brightonCirculateNotify(brightonWindow *bwin, brightonEvent *event) { if (bwin->flags & BRIGHTON_DEBUG) printf("brightonCirculateNotify()\n"); return(0); } int brightonCirculateRequest(brightonWindow *bwin, brightonEvent *event) { if (bwin->flags & BRIGHTON_DEBUG) printf("brightonCirculateRequest()\n"); return(0); } int brightonPropertyNotify(brightonWindow *bwin, brightonEvent *event) { if (bwin->flags & BRIGHTON_DEBUG) printf("brightonPropertyNotify()\n"); return(0); } int brightonSelectionClear(brightonWindow *bwin, brightonEvent *event) { if (bwin->flags & BRIGHTON_DEBUG) printf("brightonSelectionClear()\n"); return(0); } int brightonSelectionRequest(brightonWindow *bwin, brightonEvent *event) { if (bwin->flags & BRIGHTON_DEBUG) printf("brightonSelectionRequest()\n"); return(0); } int brightonSelectionNotify(brightonWindow *bwin, brightonEvent *event) { if (bwin->flags & BRIGHTON_DEBUG) printf("brightonSelectionNotify()\n"); return(0); } int brightonColormapNotify(brightonWindow *bwin, brightonEvent *event) { if (bwin->flags & BRIGHTON_DEBUG) printf("brightonColormapNotify()\n"); return(0); } int brightonClientMessage(brightonWindow *bwin, brightonEvent *event) { if (bwin->flags & BRIGHTON_DEBUG) printf("brightonClientMessage()\n"); return(0); } int brightonMappingNotify(brightonWindow *bwin, brightonEvent *event) { if (bwin->flags & BRIGHTON_DEBUG) printf("brightonMappingNotify()\n"); return(0); } int brightonNullHandler(brightonWindow *bwin, brightonEvent *event) { if (bwin->flags & BRIGHTON_DEBUG) printf("brightonNullHandler()\n"); return(0); } typedef int (*eventRoutine)(brightonWindow *, brightonEvent *); /* * Check out the bEvent from the library, it can mask some events that are * considered "not important", but actually may be. */ eventRoutine defaultHandlers[BLASTEvent] = { brightonNullHandler, brightonNullHandler, brightonKeyPress, brightonKeyRelease, brightonButtonPress, brightonButtonRelease, brightonMotionNotify, brightonEnterNotify, brightonLeaveNotify, brightonFocusIn, brightonFocusOut, brightonKeymapNotify, brightonExpose, brightonGraphicsExpose, brightonNoExpose, brightonVisibilityNotify, brightonCreateNotify, brightonDestroyNotify, brightonUnmapNotify, brightonMapNotify, brightonMapRequest, brightonReparentNotify, brightonConfigureNotify, brightonConfigureRequest, brightonGravityNotify, brightonResizeRequest, brightonCirculateNotify, brightonCirculateRequest, brightonPropertyNotify, brightonSelectionClear, brightonSelectionRequest, brightonSelectionNotify, brightonColormapNotify, brightonClientMessage, brightonMappingNotify }; void brightonInitDefHandlers(brightonWindow *bwin) { int i; for (i = 0; i < BLASTEvent; i++) bwin->callbacks[i] = defaultHandlers[i]; } void brightonOldEventLoop(brightonDisplay **dlist) { brightonDisplay *display; brightonEvent event; brightonWindow *bwin = (*dlist)->bwin; while (1) { /* * BNextEvent will block due to it using XNextEvent. This makes the * use of other functions rather difficult. Will rework this to use * XCheckMaskEvent which will not block. * * while (1) { * foreach (win) { * BCheckMaskEvent(bwin, &event); * } * } * * We need this since the MIDI routines also need to be checked, so we * will select on the ALSA SEQ port looking for controller changes so * that they can modify the GUI display. */ BNextEvent(bwin->display, &event); if (event.command == BRIGHTON_NONE) continue; /* * This may need to be changed to a semaphore, but I am hoping all GUI * activity can occupy a single thread only. */ bwin->flags |= BRIGHTON_BUSY; /* * Look for the right window. */ display = *dlist; while (display != 0) { if (event.wid == ((brightonWindow *) display->bwin)->win) break; if ((event.type == BRIGHTON_DESTROY) && (((brightonWindow *) display->bwin)->parentwin == event.wid)) break; display = display->next; } if ((display == 0 || (event.type < 0) || (event.type >= BLASTEvent))) continue; ((brightonWindow *) display->bwin)->callbacks[event.type] (display->bwin, &event); bwin->flags &= ~BRIGHTON_BUSY; } } int brightonEventLoop(brightonDisplay **dlist) { brightonDisplay *display; brightonEvent event; brightonWindow *bwin = (*dlist)->bwin; /* while (1) { */ /* * BNextEvent will block due to it using XNextEvent. This makes the * use of other functions rather difficult. Will rework this to use * XCheckMaskEvent which will not block. * * while (1) { * foreach (win) { * BCheckMaskEvent(bwin, &event); * } * } * * We need this since the MIDI routines also need to be checked, so we * will select on the ALSA SEQ port looking for controller changes so * that they can modify the GUI display. */ while (BNextEvent(bwin->display, &event) > 0) { if (event.command == BRIGHTON_NONE) continue; /* * This may need to be changed to a semaphore, but I am hoping all * GUI activity can occupy a single thread only. */ bwin->flags |= BRIGHTON_BUSY; /* * Look for the right window. */ display = *dlist; while (display != 0) { if (event.wid == ((brightonWindow *) display->bwin)->win) break; if ((event.type == BRIGHTON_DESTROY) && (((brightonWindow *) display->bwin)->parentwin == event.wid)) break; display = display->next; } if ((display == 0 || (event.type < 0) || (event.type >= BLASTEvent))) continue; ((brightonWindow *) display->bwin)->callbacks[event.type] (display->bwin, &event); bwin->flags &= ~BRIGHTON_BUSY; /* * Configure events are typically big resizes which are long events. * If we handle all of them (they come in buckets) at once it is * possible the engine will detect GUI failure from active sense */ if (event.command == BRIGHTON_CONFIGURE) return(1); } /* * This will now become a select on the ALSA SEQ socket looking for * MIDI events. Not certain how they will be linked into the GUI at * the moment. For now this is just a sleep until the ALSA SEQ interface * registration code has been finalised. * * What we will be looking for are events on a MIDI channel, we will * look for that MIDI channel in our window lists. We want to respond * to key events and reflect that in the GUI optionally, but not send * the key events since the engine will handle all those. We also want * to look for controller values and have some configurable method to * link those to our controls. Now this linkage will be done via the * GUI, preferably, with the . * Since the GUI handles this then we can dispatch events to another * module that does the linkage. Need to be able to save and retrieve * configurations - will go to this module, and all * MIDI controller events as well, and it will make the linkage and * dispatch the events. * We should try and have a vkeydb type X event keymap. */ /* usleep(10000); */ /* } */ return(0); } bristol-0.60.11/libbrighton/brightonColorMgt.c0000644000175000017500000005033611746476474016243 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include #include #include "brightoninternals.h" #include "brightonX11.h" #define COLOR_START 8 #define SHIFT_BITS 12 /* This is silly, should be cleared out */ #define SCAN_R r #define SCAN_G g #define SCAN_B b typedef struct CCEntry { short last, next; short p_index; unsigned short g, b; } cc_entry; typedef struct CCRow { unsigned short count; unsigned short start; cc_entry *entry; } c_row; struct { int redshift; /* defines cache tablesize */ unsigned short mask; /* defines color matching mask, f(redshift) */ struct { int hits; int miss_no_row; int miss_no_color; int miss_no_entry; int miss_no_green; int miss_no_blue; int miss_eol; int inserts; int missedinserts; int deletes; int deleted; int errors; int rowinserts; int rerows; float depth; float lsd; } stats; c_row *row; } c_table; static void initColorCache(brightonWindow *bwin, int shift) { int rcount = pow(2, shift), i; c_table.redshift = 16 - shift; c_table.mask = 0xffff << c_table.redshift; c_table.row = brightonmalloc(sizeof(c_row) * rcount); /* * Initialise each row with COLOR_START colors. These may have to be * rehashed later. There are arguments to make this 'none', in fact they * are good enough to implement it now, ie, later. */ for (i = 0; i < rcount; i++) c_table.row[i].count = 0; } extern int xcolorcount; #define ASD c_table.stats.depth = c_table.stats.depth * 0.99999f + d * 0.00001f; c_table.stats.lsd = d void printColorCacheStats(brightonWindow *bwin) { int rcount = pow(2, 16 - c_table.redshift), i, j, occ, cum = 0; printf("\nBrighton Color Cache Stats:\n---------------------------\n\n"); printf("quality: %4i\n", 16 - c_table.redshift); printf("redshift: %4i\n", c_table.redshift); printf("colormask: %4x\n", c_table.mask); printf("bucketsize: %4i\n", COLOR_START); printf("redbuckets: %4i\n", rcount); printf("\n"); printf(" hits: %8i\n", c_table.stats.hits); printf("\n"); printf(" miss row: %8i ", c_table.stats.miss_no_row); printf(" missed: %8i\n", c_table.stats.missedinserts); printf(" miss line: %8i ", c_table.stats.miss_no_entry); printf(" deletes: %8i\n", c_table.stats.deletes); printf(" miss EOL: %8i ", c_table.stats.miss_eol); printf(" deleted: %8i\n", c_table.stats.deleted); printf(" miss green: %8i ", c_table.stats.miss_no_green); printf(" errors: %8i\n", c_table.stats.errors); printf(" miss blue: %8i ", c_table.stats.miss_no_blue); printf(" new rows: %8i\n", c_table.stats.rowinserts); printf(" miss color: %8i ", c_table.stats.miss_no_color); printf(" new buckets: %8i\n", c_table.stats.rerows); printf(" misses total:%8i ", c_table.stats.miss_eol + c_table.stats.miss_no_row + c_table.stats.miss_no_color + c_table.stats.miss_no_entry + c_table.stats.miss_no_green + c_table.stats.miss_no_blue); printf(" inserts: %8i\n", c_table.stats.inserts); printf("\n"); printf(" ASD: %8.1f ", c_table.stats.depth); printf(" LSD: %8.1f\n", c_table.stats.lsd); printf("\n"); printf("Red bucket stats:\n"); printf("----------------------------------"); printf("----------------------------------\n"); for (i = 0; i < (rcount>>1); i++) { occ = 0; if (c_table.row[i].count > 0) { for (j = c_table.row[i].start; j >= 0; j = c_table.row[i].entry[j].next) occ++; } printf("%3i: sz %5i, st %3i, occ %5i | ", i, c_table.row[i].count, c_table.row[i].start, occ); cum += occ; occ = 0; if (c_table.row[i+(rcount>>1)].count > 0) { for (j = c_table.row[i+(rcount>>1)].start; j >= 0; j = c_table.row[i+(rcount>>1)].entry[j].next) occ++; } printf("%3i: sz %5i, st %3i, occ %5i\n", i+(rcount>>1), c_table.row[i+(rcount>>1)].count, c_table.row[i+(rcount>>1)].start, occ); cum += occ; } printf("----------------------------------"); printf("----------------------------------\n"); /* * Scan the table of colors to see how much of the palette has not been * allocated by the library. */ occ = 0; for (i = 0; i < bwin->cmap_size; i++) if ((bwin->display->palette[i].uses > 0) && ((bwin->display->palette[i].gc == 0) && (bwin->display->palette[i].pixel < 0))) occ++; /* * Color stats: the numbers typically appear to not add up, the cache has * most, more than in the dumped XPM files and in the middle sits the * number allocated by the window system interface library (B11). The * reason is that the cache contains all the colors requested from all the * bitmap files - not all colors may be rendered since the bitmaps are * scaled/rotated, etc, and some pixels are missed out of the drawn image * however are still in the cache if they are needed. * * The interface library has more than in the dumped image since the image * changes due to shading and transparencies, so colors that may have been * rendered in one image may not be in the next depending on location of * the controllers and panels once drawn then withdrawn often have a * lot of unseen controls. It will probably never have the same value as * the cache since GC are scarce and are only requested in the interface * library when they are actually required to be painted. * * So, the following figures should more or less add up. There is always a * difference of '1' due to the use of 'Blue' as transparency, hence never * rendered. */ printf("Total cache entries: %i, Window System %i, no GC (unused): %i\n", cum, xcolorcount, occ); printf("\n"); } /* * When a row fills up then we have to rebuild it in a new longer cache line. */ static int cacheReRow(unsigned short row) { cc_entry *n_entry; int i, new = 0; n_entry = brightonmalloc(sizeof(cc_entry) * (c_table.row[row].count += COLOR_START)); /* * Initialise the new table */ for (i = 0; i < c_table.row[row].count; i++) n_entry[i].last = n_entry[i].next = n_entry[i].p_index = -1; /* * Insert the first entry */ i = c_table.row[row].start; n_entry[new].g = c_table.row[row].entry[i].g; n_entry[new].b = c_table.row[row].entry[i].b; n_entry[new].p_index = c_table.row[row].entry[i].p_index; /* * Move to the next entry and start the convergence. */ i = c_table.row[row].entry[i].next; for (; i >= 0; i = c_table.row[row].entry[i].next) { new++; /* * Take this entry and converge it to the new list */ n_entry[new].g = c_table.row[row].entry[i].g; n_entry[new].b = c_table.row[row].entry[i].b; n_entry[new].p_index = c_table.row[row].entry[i].p_index; n_entry[new].last = new - 1; n_entry[new].next = -1; n_entry[new - 1].next = new; } brightonfree(c_table.row[row].entry); c_table.row[row].entry = n_entry; c_table.row[row].start = 0; c_table.stats.rerows++; return(0); } /* * There are a couple of things we have to watch out for. Firstly we have to * correctly reorder each red row when a color is inserted. Then if we have * reached the end of the table we need to insert a larger size for this red * hue and convert the existing one over. Hm. */ int cacheInsertColor(unsigned short r, unsigned short g, unsigned short b, unsigned short p_index) { c_row *row; cc_entry *entry; int i, j, free; /* * Get our red row. If it is new stuff in the values. */ row = &c_table.row[SCAN_R >> c_table.redshift]; /* * So we have a free entry. Now we need to scan to find the target point * to insert the new color * * Make these values 'searchable': */ SCAN_G &= c_table.mask; SCAN_B &= c_table.mask; if ((entry = row->entry) <= 0) { //printf("insert NEW: 0 (%i)\n", r>>c_table.redshift); /* * Create the row if it has not been done, by implication this already * means we should generate a new color, done in the calling party. */ row->count = COLOR_START; row->start = 0; c_table.row[SCAN_R >> c_table.redshift].entry = brightonmalloc(sizeof(cc_entry) * COLOR_START); for (i = 0; i < COLOR_START; i++) row->entry[i].last = row->entry[i].next = row->entry[i].p_index = -1; row = &c_table.row[SCAN_R >> c_table.redshift]; row->entry[0].last = row->entry[0].next = -1; row->entry[0].p_index = p_index; row->entry[0].g = SCAN_G; row->entry[0].b = SCAN_B; c_table.stats.rowinserts++; c_table.stats.inserts++; return(0); } /* * We need a free entry in this row to proceed */ for (free = 0; free < row->count; free++) if (row->entry[free].p_index < 0) break; /* * If we passed the end of row then it is full. We need to rebuild the row * but will work that later as it comes up. For now, return blue. */ if (free == row->count) { c_table.stats.missedinserts++; cacheReRow(r>>c_table.redshift); entry = row->entry; } entry[free].last = -1; entry[free].next = -1; entry[free].g = SCAN_G; entry[free].b = SCAN_B; entry[free].p_index = p_index; /* * We first want to scan for green, that will be more efficient than * scanning that both green and blue match as this can terminate earlier. * * We have to start with the first entry since it may need extra processing. */ if ((entry[row->start].g > g) || ((entry[row->start].g == g) && (entry[row->start].b > b))) { /* * If start is already greater then insert our new entry. */ entry[free].next = row->start; entry[free].last = -1; entry[row->start].last = free; row->start = free; //printf("insert SOL: %i (%i)\n", free, r>>c_table.redshift); c_table.stats.inserts++; return(free); } j = row->start; while (entry[j].SCAN_G < SCAN_G) { /* * If we have hit the end of the line and our new green is still * bigger append the new entry and return. */ if (entry[j].next < 0) { entry[j].next = free; entry[free].last = j; //printf("insert EOS: %i (%i)\n", free, r>>c_table.redshift); c_table.stats.inserts++; return(free); } j = entry[j].next; } /* * At this point we have scanned to where the cached green is equal * to the targetted value. Now scan for a matching blue until end of * list or green no longer matches. */ for (; j >= 0; j = entry[j].next) { /* * Check green still matches. If it doesn't then insert the new entry * behind this one? */ if ((entry[j].SCAN_G != SCAN_G) || (entry[j].SCAN_B > SCAN_B)) { entry[free].next = j; entry[free].last = entry[j].last; entry[entry[j].last].next = free; entry[j].last = free; //printf("insert INL: %i (%i) %i: %x %x/%x %x\n", free, r>>c_table.redshift, //SCAN_R>>c_table.redshift, SCAN_G, entry[j].SCAN_G, SCAN_B, entry[j].SCAN_B); c_table.stats.inserts++; return(free); } /* * If the next entry is the end of the list then append this new one */ if (entry[j].next < 0) { entry[free].last = j; entry[j].next = free; //printf("insert EOL: %i (%i)\n", free, r>>c_table.redshift); c_table.stats.inserts++; return(free); } } /* * So we are at the end of the list? Hm. Return "blue". printf("colour cache insert: we should not have got here\n"); */ c_table.stats.errors++; return(0); } static void cacheFreeColor(unsigned short r, unsigned short g, unsigned short b, int pindex) { c_table.stats.deletes++; /* * Search through the row depicted by R for the selected pindex. * * Hm, leave this for now - we are not actually big on deleting GC due to * the way the cache works. If deletes gets out of sync with deleted then * we can implement this. * for (i = c_table.row[r >> c_table.redshift]; i >= 0; j = entry[i].next) { if ( } */ } static int cacheFindColor(unsigned short r, unsigned short g, unsigned short b, int cm) { c_row *row; cc_entry *entry; int j = 0; int d = 0; unsigned short mask = c_table.mask; // 0xffff << (16 - cm); if ((r == 0) && (g == 0) && (b == 0xff00)) return(0); /* * First select the row using a hash of the red value */ if ((row = &c_table.row[SCAN_R >> c_table.redshift]) <= 0) { c_table.stats.miss_no_row++; return(-1); } /* * Make these values 'searchable' */ SCAN_G &= mask; SCAN_B &= mask; /* * We have the red matched, scan through the current line for a green * match. */ if ((entry = row->entry) <= 0) { c_table.stats.miss_no_entry++; return(-1); } /* * We first want to scan for green, that will be more efficient than * scanning that both green and blue match as this can terminate earlier. */ for (j = row->start; j >= 0; j = entry[j].next) { if ((d++) > 10000) return(-1); if (entry[j].SCAN_G == SCAN_G) break; if (entry[j].SCAN_G > SCAN_G) { c_table.stats.miss_no_green++; ASD; return(-1); } /* * If we hit the end of the scan and still have no match on green * then return. */ if (entry[j].next < 0) { c_table.stats.miss_eol++; ASD; return(-1); } } /* * At this point we have scanned to where the cached green is greater/equal * to the targetted value. Now scan for a matching blue until end of * list or green no longer matches. */ for (; j >= 0; j = entry[j].next) { if ((d++) > 10000) return(-1); /* Check green still matches */ if (entry[j].SCAN_G != SCAN_G) { c_table.stats.miss_no_color++; ASD; return(-1); } if (entry[j].SCAN_B > SCAN_B) { c_table.stats.miss_no_blue++; ASD; return(-1); } /* * If this is a blue match, return the palette */ if (entry[j].SCAN_B == SCAN_B) { c_table.stats.hits++; ASD; //printf("found %i\n", entry[j].p_index); return(entry[j].p_index); } } c_table.stats.miss_no_color++; ASD; /* * If we get here then we have scanned until end of list. We could insert * the new color however we will leave that to the calling party as we * don't have a palette index. */ return(-1); } /* * See if we already have this color somewhere. This can be a slow operation * so we will make a couple of changes. Firstly, we will use a color cache to * accelerate the searches, and in the event of not finding the color then it * should be built in here. * * Cache will consist of a table hashed by red, with each table entry being * sorted then by green. As such we can jump very fast to the red matches and * search the greens for a blue match. * * We should add another call to insert a hashed entry. */ int brightonFindColor(brightonPalette *palette, int ncolors, unsigned short r, unsigned short g, unsigned short b, int match) { register int i; register unsigned short rmin, rmax, gmin, gmax, bmin, bmax; float lesser = match , greater = 1 / match; return(cacheFindColor(r, g, b, match)); /* printf("find %i, %i, %i %f %i\n", r, g, b, match, ncolors); */ rmin = (lesser * ((float) r)); if ((greater * ((float) r)) > 65535) rmax = 65535; else rmax = (greater * ((float) r)); gmin = (lesser * ((float) g)); if ((greater * ((float) g)) > 65535) gmax = 65535; else gmax = (greater * ((float) g)); bmin = (lesser * ((float) b)); if ((greater * ((float) b)) > 65535) bmax = 65535; else bmax = (greater * ((float) b)); if (lesser > greater) lesser = greater = 1.0; for (i = 0; i < ncolors; i++) { if (palette[i].flags & BRIGHTON_INACTIVE_COLOR) continue; if ((palette[i].red >= rmin) && (palette[i].red <= rmax) && (palette[i].green >= gmin) && (palette[i].green <= gmax) && (palette[i].blue >= bmin) && (palette[i].blue <= bmax)) return(i); } return(-1); } int brightonFindFreeColor(brightonPalette *palette, int ncolors) { int i; for (i = 0; i < ncolors; i++) if (palette[i].flags & BRIGHTON_INACTIVE_COLOR) return(i); return(-1); } int brightonFreeGC(brightonWindow *bwin, int index) { if (index < 0) return(0); if (index >= bwin->cmap_size) return(0); if (--bwin->display->palette[index].uses == 0) { BFreeColor(bwin->display, &bwin->display->palette[index]); cacheFreeColor( bwin->display->palette[index].red, bwin->display->palette[index].green, bwin->display->palette[index].blue, index); } return(0); } /* * The primary use of GCs is for color selection, and then also primarily in the * forgreound. We are going to request colors as R/G/B tuples, as yet not with * any structure management although this may happen. We will consider the use * of hash table lookup with best fit, limiting the total number of colours * that brighton can reserve, and keep stats on lookup performance for different * hashing functions. * * To minimise color requirements it is preferable for multiple synths to be * children, ie, share the same contexts. */ int brightonGetGC(brightonWindow *bwin, unsigned short r, unsigned short g, unsigned short b) { register int pindex; /*printf("brightonGetGC(%x, %x, %x)\n", r, g, b); */ /* * See if we can find this color */ if ((pindex = cacheFindColor(r, g, b, bwin->quality)) >= 0) { bwin->display->palette[pindex].uses++; return(pindex); } /* if ((pindex = brightonFindColor(bwin->display->palette, bwin->cmap_size, r, g, b, bwin->quality)) >= 0) { bwin->display->palette[pindex].uses++; return(pindex); } */ /* * If we have no free colors, then palette[0] is the default */ if ((pindex = brightonFindFreeColor(bwin->display->palette, bwin->cmap_size)) < 0) return(0); bwin->display->palette[pindex].red = r; bwin->display->palette[pindex].green = g; bwin->display->palette[pindex].blue = b; bwin->display->palette[pindex].uses++; bwin->display->palette[pindex].flags &= ~BRIGHTON_INACTIVE_COLOR; bwin->display->palette[pindex].uses++; cacheInsertColor(r, g, b, pindex); return(pindex); } /* * With named colors we need to allocate them in advance, we cannot leave this * up to the BRendering process. We should only really be using this for one * color as the match is exact, however the XPM bitmap format accepts names * as well as RGB even though pretty much all of the shipped bitmaps avoid * using names ("Blue" is just re-interpreted from 'none' in the bitmap) and * has to be exact to ensure transparency. */ int haveblue = -1; int brightonGetGCByName(brightonWindow *bwin, char *name) { int pindex; if ((strcmp(name, "Blue") == 0) && (haveblue >= 0)) { /* * We only want to map blue once even though it may well be requested * from multiple bitmaps. */ bwin->display->palette[haveblue].uses++; return(haveblue); } /* * If we have no free colors, then palette[0] is the default. This is * typically "Blue" which may have been a bad choice..... */ if ((pindex = brightonFindFreeColor(bwin->display->palette, bwin->cmap_size)) < 0) return(0); bwin->display->palette[pindex].uses++; BAllocColorByName(bwin->display, &bwin->display->palette[pindex], name); bwin->display->palette[pindex].flags &= ~BRIGHTON_INACTIVE_COLOR; bwin->display->palette[pindex].uses++; if (strcmp(name, "Blue") == 0) haveblue = pindex; return(pindex); } /* * Make sure we have a suitable visual, then try and get a shitload of colors. * We should consider looking for any existing visuals of an acceptable type? */ brightonPalette * brightonInitColormap(brightonWindow *bwin, int ncolors) { /*printf("brightonInitColormap(%i)\n", ncolors); */ initColorCache(bwin, bwin->quality); /* Init cache with digit shift */ if (bwin->display->palette == NULL) { int i; bwin->display->palette = (brightonPalette *) brightonmalloc(ncolors * sizeof(brightonPalette)); for (i = 0; i < ncolors; i++) { bwin->display->palette[i].flags |= BRIGHTON_INACTIVE_COLOR; bwin->display->palette[i].pixel = -1; } } return(BInitColorMap(bwin->display)); } void brightonSprintColor(brightonWindow *bwin, char *cstring, int pixel) { sprintf(cstring, "#%02x%02x%02x", bwin->display->palette[pixel].red >> 8, bwin->display->palette[pixel].green >> 8, bwin->display->palette[pixel].blue >> 8); } bristol-0.60.11/libbrighton/brightonLedBlock.c0000644000175000017500000002331011746476474016164 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* * This will emulate a 7 red LED digit block. */ #include #include "brightoninternals.h" extern int brightonPanelLocation(); int destroyLedblock(brightonDevice *dev) { printf("destroyLedblock()\n"); if (dev->image0) brightonFreeBitmap(dev->bwin, dev->image0); if (dev->image1) brightonFreeBitmap(dev->bwin, dev->image1); if (dev->image2) brightonFreeBitmap(dev->bwin, dev->image2); if (dev->image3) brightonFreeBitmap(dev->bwin, dev->image3); if (dev->image4) brightonFreeBitmap(dev->bwin, dev->image4); if (dev->image5) brightonFreeBitmap(dev->bwin, dev->image5); if (dev->image6) brightonFreeBitmap(dev->bwin, dev->image6); if (dev->image7) brightonFreeBitmap(dev->bwin, dev->image7); if (dev->image8) brightonFreeBitmap(dev->bwin, dev->image8); if (dev->image9) brightonFreeBitmap(dev->bwin, dev->image9); if (dev->imagec) brightonFreeBitmap(dev->bwin, dev->imagec); if (dev->imagee) brightonFreeBitmap(dev->bwin, dev->imagee); dev->image = NULL; dev->image2 = NULL; return(0); } static void displayledblock(brightonDevice *dev) { int flags = dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags; brightonBitmap *choice; if (dev->bwin->app->resources[dev->panel].flags & BRIGHTON_WITHDRAWN) return; if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_WITHDRAWN) return; switch ((int) dev->value) { default: choice = dev->imagec; break; case 0: choice = dev->image0; break; case 1: choice = dev->image1; break; case 2: choice = dev->image2; break; case 3: choice = dev->image3; break; case 4: choice = dev->image4; break; case 5: choice = dev->image5; break; case 6: choice = dev->image6; break; case 7: choice = dev->image7; break; case 8: choice = dev->image8; break; case 9: choice = dev->image9; break; case 10: choice = dev->imagee; break; } brightonStretch(dev->bwin, choice, /*dev->bwin->app->resources[dev->panel].canvas, */ dev->bwin->dlayer, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width, dev->height, flags); brightonFinalRender(dev->bwin, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width, dev->height); dev->lastvalue = dev->value; dev->lastposition = dev->position; } static int considercallback(brightonDevice *dev) { brightonIResource *panel = &dev->bwin->app->resources[dev->panel]; if ((dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_WITHDRAWN) || (dev->bwin->flags & BRIGHTON_NO_DRAW)) return(0); if ((dev->lastvalue != dev->value) || (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_CHECKBUTTON)) { if (panel->devlocn[dev->index].callback) { panel->devlocn[dev->index].callback(dev->bwin, dev->panel, dev->index, dev->value); } else { if (panel->callback) panel->callback(dev->bwin, dev->panel, dev->index, dev->value); } } return(0); } static int configure(brightonDevice *dev, brightonEvent *event) { /* printf("configureLedblock(%i, %f)\n", dev->index, dev->value); */ if (dev->bwin->app->resources[dev->panel].flags & BRIGHTON_WITHDRAWN) return(0); if (event->command == -1) return(-1); if (event->command == BRIGHTON_RESIZE) { dev->x = event->x; dev->y = event->y; dev->width = event->w; dev->height = event->h; /* * We should consider altering the locations structure, so that * event dispatching is correct. */ if ((dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_CHECKBUTTON) == 0) considercallback(dev); brightonPanelLocation(dev->bwin, dev->panel, dev->index, dev->x, dev->y, dev->width, dev->height); dev->lastvalue = -1; displayledblock(dev); return(0); } if (event->command == BRIGHTON_LEAVE) { if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_CHECKBUTTON) { dev->value = 0; displayledblock(dev); } return(0); } if (event->command == BRIGHTON_ENTER) { if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_CHECKBUTTON) { dev->value = 1; displayledblock(dev); } return(0); } if (event->command == BRIGHTON_BUTTONRELEASE) { if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_CHECKBUTTON) { dev->value = 0; displayledblock(dev); considercallback(dev); } return(0); } if (event->command == BRIGHTON_BUTTONPRESS) { brightonIResource *panel = &dev->bwin->app->resources[dev->panel]; if (event->key == BRIGHTON_BUTTON2) { brightonRegisterController(dev); return(0); } if (dev->value == 0) dev->value = panel->devlocn[dev->index].to; else dev->value = panel->devlocn[dev->index].from; if ((dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_CHECKBUTTON) == 0) considercallback(dev); displayledblock(dev); return(0); } if (event->command == BRIGHTON_KEYPRESS) { brightonIResource *panel = &dev->bwin->app->resources[dev->panel]; if (event->key == 0x20) { if (dev->value == 0) dev->value = panel->devlocn[dev->index].to; else dev->value = panel->devlocn[dev->index].from; considercallback(dev); displayledblock(dev); return(0); } /* * If this was not a space bar which we use to activate and de-activate * any arbitrary ledblock then it could be that we pressed some key that * can otherwise be interpretted. * This is awkward since here we are in a single ledblock and I would * like to use keypress to emulate a piano keyboard from the computer. * These events would have to be delivered to the parent, not to the * device, and the parent would then decide to which device the event * should be delivered. */ } if (event->command == BRIGHTON_KEYRELEASE) { /* * This is just to clear the event and repaint the key, we should not * be bothered with the callback. */ if (event->key == 0x20) { if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_CHECKBUTTON) { dev->value = 0; displayledblock(dev); /* considercallback(dev); */ } } return(0); } if (event->command == BRIGHTON_PARAMCHANGE) { dev->value = event->value; dev->lastvalue = -1; if ((dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_CHECKBUTTON) == 0) considercallback(dev); displayledblock(dev); return(0); } return(0); } int * createLedblock(brightonWindow *bwin, brightonDevice *dev, int index, char *bitmap) { /* printf("createLedblock()\n"); */ dev->destroy = destroyLedblock; dev->configure = configure; dev->bwin = bwin; if (dev->image0) brightonFreeBitmap(bwin, dev->image0); if (dev->image1) brightonFreeBitmap(bwin, dev->image1); if (dev->image2) brightonFreeBitmap(bwin, dev->image2); if (dev->image3) brightonFreeBitmap(bwin, dev->image3); if (dev->image4) brightonFreeBitmap(bwin, dev->image4); if (dev->image5) brightonFreeBitmap(bwin, dev->image5); if (dev->image6) brightonFreeBitmap(bwin, dev->image6); if (dev->image7) brightonFreeBitmap(bwin, dev->image7); if (dev->image8) brightonFreeBitmap(bwin, dev->image8); if (dev->image9) brightonFreeBitmap(bwin, dev->image9); if ((dev->image0 = brightonReadImage(bwin, "bitmaps/digits/redled0.xpm")) == 0) printf("could not load redled image\n"); if ((dev->image1 = brightonReadImage(bwin, "bitmaps/digits/redled1.xpm")) == 0) printf("could not load redled image\n"); if ((dev->image2 = brightonReadImage(bwin, "bitmaps/digits/redled2.xpm")) == 0) printf("could not load redled image\n"); if ((dev->image3 = brightonReadImage(bwin, "bitmaps/digits/redled3.xpm")) == 0) printf("could not load redled image\n"); if ((dev->image4 = brightonReadImage(bwin, "bitmaps/digits/redled4.xpm")) == 0) printf("could not load redled image\n"); if ((dev->image5 = brightonReadImage(bwin, "bitmaps/digits/redled5.xpm")) == 0) printf("could not load redled image\n"); if ((dev->image6 = brightonReadImage(bwin, "bitmaps/digits/redled6.xpm")) == 0) printf("could not load redled image\n"); if ((dev->image7 = brightonReadImage(bwin, "bitmaps/digits/redled7.xpm")) == 0) printf("could not load redled image\n"); if ((dev->image8 = brightonReadImage(bwin, "bitmaps/digits/redled8.xpm")) == 0) printf("could not load redled image\n"); if ((dev->image9 = brightonReadImage(bwin, "bitmaps/digits/redled9.xpm")) == 0) printf("could not load redled image\n"); if ((dev->imagec = brightonReadImage(bwin, "bitmaps/digits/redledoff.xpm")) == 0) printf("could not load redled image\n"); if ((dev->imagee = brightonReadImage(bwin, "bitmaps/digits/redledE.xpm")) == 0) printf("could not load redled image\n"); /* * These will force an update when we first display ourselves. */ dev->value = 0; dev->lastvalue = -1; dev->lastposition = -1; return(0); } bristol-0.60.11/libbrighton/brightonDisplay.c0000644000175000017500000001612211746476474016115 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* * This is intended to be a cheap looking LCD display panel. */ #include "brightoninternals.h" #include "brightonkeymappings.h" /* * Use of this variable means every display must have the same coloration */ int destroyDisplay(brightonDevice *dev) { printf("destroyDisplay()\n"); if (dev->image) brightonFreeBitmap(dev->bwin, dev->image); dev->image = NULL; return(0); } static void renderDot(brightonDevice *dev, int xoff, int yoff, int onoff, int dsize) { int xcount = dsize, ycount = dsize, color; if (onoff == 1) { color = dev->lastvalue; } else { color = dev->value2; } while (ycount--) { while (xcount--) { if (yoff + xoff + xcount >= dev->width * dev->height) return; dev->image->pixels[yoff + xoff + xcount] = color; } xcount = dsize; yoff += dev->width; } } static int renderChar(brightonDevice *dev, char ch, int xoffset, int dsize, int dspace) { int yoff = dev->width, boff, xoff = xoffset; unsigned char bitmask = 0x80, btarget; if ((ch = key[(int) ch].map) == -1) ch = 0; if ((((key[(int) ch].width + 1) * dsize + dspace) + xoff) >= dev->width) return(key[(int) ch].width + dsize); btarget = bitmask >> key[(int) ch].width; /* * We now attempt to render the character - we have the space we need. * * If any given bit is set in the character mapping then we paint in a * dot of size dsize. */ for (boff = 0; boff < KEY_HEIGHT; boff++) { while ((bitmask & btarget) == 0) { if (key[(int) ch].bitmap[boff] & bitmask) { renderDot(dev, xoff, yoff, BIT_ON, dsize); } else { renderDot(dev, xoff, yoff, BIT_OFF, dsize); } xoff += dsize + dspace; bitmask >>= 1; } renderDot(dev, xoff, yoff, BIT_OFF, dsize); yoff += (dev->width * (dsize + dspace)); xoff = xoffset; bitmask = 0x80; } return((key[(int) ch].width + 1) * (dspace + dsize)); } static void renderText(brightonDevice *dev, char *text) { int dotsize = 1, dotspace = 1, xoffset = 1; char ch; if ((text == (char *) 0) || (text == (char *) -1)) return; if (dev->height < 7) { dotspace = 0; } else if (dev->height < 12) { dotspace = 0; } else if (dev->height >= 17) { dotsize = (dev->height - 6) / 5; } while ((ch = *text++) != '\0') { if ((xoffset += renderChar(dev, ch, xoffset, dotsize, dotspace)) >= dev->width) return; } /* * Clear out any remaining text by rendering spaces. */ while ((xoffset += renderChar(dev, ' ', xoffset, dotsize, dotspace)) < dev->width) { ; } } static int displaydisplay(brightonDevice *dev) { if (dev->bwin->app->resources[dev->panel].flags & BRIGHTON_WITHDRAWN) return(-1); if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_WITHDRAWN) return(-1); renderText(dev, &dev->text[0]); /* renderText(dev, "test"); */ /* * We should render any text we desire into the bmap, and then have it * painted */ brightonRender(dev->bwin, dev->image, /*dev->bwin->app->resources[dev->panel].canvas, */ /*dev->x, dev->y, */ dev->bwin->dlayer, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width, dev->height, 0); /* * We can consider the alpha layer here. */ if (dev->image2 != 0) { brightonAlphaLayer(dev->bwin, dev->image2, dev->bwin->dlayer, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width, dev->height, dev->position); } brightonFinalRender(dev->bwin, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width, dev->height); return(0); } brightonBitmap *first; static int configure(brightonDevice *dev, brightonEvent *event) { /* printf("configureDisplay(%i)\n", event->command); */ if (event->command == -1) return(-1); if (event->command == BRIGHTON_RESIZE) { int i; dev->originx = event->x; dev->originy = event->y; dev->x = event->x; dev->y = event->y; dev->width = event->w; dev->height = event->h; brightonfree(dev->image->pixels); dev->image->width = dev->width; dev->image->height = dev->height; dev->image->pixels = (int *) brightonmalloc(dev->width * dev->height * sizeof(int)); for (i = 0; i < dev->width * dev->height; i++) dev->image->pixels[i] = dev->value2; /* * We should consider altering the locations structure, so that * event dispatching is correct. brightonLocation(dev->bwin, dev->index, dev->x, dev->y, dev->width, dev->height); */ displaydisplay(dev); return(0); } if (event->command == BRIGHTON_KEYRELEASE) { } if (event->command == BRIGHTON_KEYPRESS) { brightonIResource *panel = &dev->bwin->app->resources[dev->panel]; panel->callback(dev->bwin, dev->panel, dev->index, event->key); } if (event->command == BRIGHTON_MOTION) { } if (event->command == BRIGHTON_PARAMCHANGE) { char *string; if (event->type != BRIGHTON_MEM) return(-1); if ((string = (char *) event->m) == 0) return(-1); if (strlen(string) > 64) string[64] = '\0'; sprintf(&dev->text[0], "%s", string); displaydisplay(dev); return(0); } return(0); } int * createDisplay(brightonWindow *bwin, brightonDevice *dev, int index, char *bitmap) { /* printf("createDisplay()\n"); */ dev->destroy = destroyDisplay; dev->configure = configure; dev->bwin = bwin; if (dev->image) brightonFreeBitmap(bwin, dev->image); if (bwin->app->resources[dev->panel].devlocn[dev->index].image != 0) dev->image = bwin->app->resources[dev->panel].devlocn[dev->index].image; else dev->image = brightonReadImage(bwin, "bitmaps/digits/display.xpm"); if (dev->image == 0) { printf("Cannot resolve the bitmap library location\n"); _exit(0); } dev->value2 = dev->image->pixels[0]; /* * We should take a peek at the second image resource. A display uses no * bitmaps, the second may be used as an alpha layer. */ if (bwin->app->resources[dev->panel].devlocn[dev->index].image2 != 0) dev->image2 = bwin->app->resources[dev->panel].devlocn[dev->index].image2; initkeys(); /* * These will force an update when we first display ourselves. */ dev->value = 0; dev->lastvalue = -1; dev->lastposition = -1; /* * Need to bury this one in the device itself, not globally. It breaks when * we have multiple windows. */ if (dev->lastvalue == -1) dev->lastvalue = brightonGetGC(dev->bwin, 0, 0, 0); return(0); } bristol-0.60.11/libbrighton/brightonSlowTimer.c0000644000175000017500000000711211746476474016434 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* * Slow timer events. * * Devices can register for slow timers, cancel requests, and a call has to be * made to clock the slow timer. Per default this is from brighton.c on the * active sense timeout, default every 1000ms. */ #include "brightoninternals.h" static struct { brightonWindow *win; int panel; int index; } brightonSTL[1024]; static void brightonScanTimerList() { int i; brightonEvent event; //printf("Brighton ST Clock scan\n"); for (i = BRIGHTON_ST_FIRST; i < 1024; i++) { if (brightonSTL[i].win != 0) { //printf("matched on %i/%i\n", brightonSTL[i].panel, brightonSTL[i].index); event.command = BRIGHTON_SLOW_TIMER; event.value = 0; brightonParamChange(brightonSTL[i].win, brightonSTL[i].panel, brightonSTL[i].index, &event); } } } static int brightonSTRegister(brightonWindow *bwin, brightonDevice *dev) { int i, free = 0; /* * We should scan our list to see if this is a duplicate then insert it * at the first free location */ for (i = BRIGHTON_ST_FIRST; i < 1024; i++) { if ((brightonSTL[i].win == NULL) && (free == 0)) free = i; if ((brightonSTL[i].win == bwin) && (brightonSTL[i].panel == dev->panel) && (brightonSTL[i].index == dev->index)) return(i); } if (free == 0) return(-1); brightonSTL[free].win = bwin; brightonSTL[free].panel = dev->panel; brightonSTL[free].index = dev->index; //printf("Register slow timer %i: %x/%i/%i\n", free, (size_t) bwin, brightonSTL[free].panel, brightonSTL[free].index); return(-1); } static int brightonSTDegister(brightonWindow *bwin, brightonDevice *dev, int id) { int i; if ((brightonSTL[id].win == bwin) && (brightonSTL[id].panel == dev->panel) && (brightonSTL[id].index == dev->index)) { //printf("Deregister slow timer %i: %i/%i\n", id, brightonSTL[id].panel, brightonSTL[id].index); brightonSTL[id].win = NULL; return(id); } /* * If we get here then the deregister failed on the index. Scan the list * to see if it is still a known timer */ for (i = BRIGHTON_ST_FIRST; i < 1024; i++) { if ((brightonSTL[i].win == bwin) && (brightonSTL[i].panel == dev->panel) && (brightonSTL[i].index == dev->index)) { //printf("Deregister slow timer %i: %i/%i\n", i, brightonSTL[i].panel, brightonSTL[i].index); brightonSTL[i].win = NULL; return(i); } } //printf("Failed to deregister slow timer %i/%i\n", brightonSTL[id].panel, brightonSTL[id].index); return(-1); } int brightonSlowTimer(brightonWindow *bwin, brightonDevice *dev, int command) { //printf("brightonSlowTimer(%i)\n", command); if (command < 0) return(command); switch (command) { case BRIGHTON_ST_CLOCK: brightonScanTimerList(); break; case BRIGHTON_ST_REQ: return(brightonSTRegister(bwin, dev)); case BRIGHTON_ST_CANCEL: default: return(brightonSTDegister(bwin, dev, command)); } return(0); } bristol-0.60.11/libbrighton/brightonRotary.c0000644000175000017500000004042111746476474015767 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* * This will be a rotary potmeter. Takes a bitmap and rotates it according to * input from the mouse/keyboard. We need a few different parameters, and a * hefty include file. Where possible will try and keep X11 requests in a * separate set of files. */ #include #include "brightoninternals.h" /*#include "brightonX11.h" */ extern void brightonPanelLocation(brightonWindow *, int, int, int, int, int, int); int destroyRotary(brightonDevice *dev) { printf("destroyRotary()\n"); if (dev->image) brightonFreeBitmap(dev->bwin, dev->image); dev->image = NULL; return(0); } static int displayrotary(brightonDevice *dev) { if (dev->bwin->app->resources[dev->panel].flags & BRIGHTON_WITHDRAWN) return(0); if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_WITHDRAWN) return(0); /* * Build up a smooth position for the pot. We may need to adjust this based * on the to/from values. */ if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_STEPPED) { dev->position = dev->value < 0.5? 1 * M_PI * (1 - 2 * dev->value) / 3: M_PI * (7 - dev->value * 2) / 3; } else dev->position = dev->value < 0.5? 7 * M_PI * (1 - 2 * dev->value) / 8: M_PI * (23 - dev->value * 14) / 8; /* * Only draw fixed number of steps. */ if ((int) (dev->value * 360 / M_PI) != (int) (dev->lastvalue * 360 / M_PI)) { brightonIResource *panel; if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_REDRAW) { brightonDevUndraw(dev->bwin, dev->bwin->dlayer, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width, dev->height); } panel = &dev->bwin->app->resources[dev->panel]; /* * Rotate my image onto the parents canvas. For rotaries that have blue * bitmaps its needs to be made sure that the background is clear * before this rotation is done. This means we have to copy the image * background into place first. */ brightonRender(dev->bwin, dev->bwin->dlayer, dev->bwin->dlayer, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width, dev->height, 0); brightonRotate(dev->bwin, dev->image, dev->bwin->dlayer, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width, dev->height, dev->position); /* * We can consider the alpha layer here. */ if (dev->image2 != 0) { brightonAlphaLayer(dev->bwin, dev->image2, dev->bwin->dlayer, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width, dev->height, dev->position); } /* * And request the panel to put this onto the respective image. */ brightonFinalRender(dev->bwin, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width, dev->height); } dev->lastvalue = dev->value; dev->lastposition = dev->position; return(0); } /* * This will go into brighton render */ static void renderHighlights(brightonWindow *bwin, brightonDevice *dev) { float d, ho2, streak; float ox, oy, dx, dy; if (dev->shadow.coords == 0) dev->shadow.coords = brightonmalloc(7 * sizeof(brightonCoord)); dev->shadow.ccount = 7; dev->shadow.flags = BRIGHTON_STATIC; ho2 = dev->width / 2; ox = dev->x + ho2; oy = dev->y + ho2; /* * We are going to render the shadow directly onto the background bitmap. * We have X and Y for the source of the shadow, plus its height and * intensity. For now we will take a default relief, and highlight the * background accordingly. This should be a 3D transform..... * * This can all be done with fractional distances, since we are going to * be dealing with a number of similar triangles. */ dx = ox - bwin->lightX; dy = oy - bwin->lightY; d = sqrt((double) (dx * dx + dy * dy)); dev->shadow.coords[0].x = ox + dy * ho2 / d; dev->shadow.coords[0].y = oy - dx * ho2 / d; dev->shadow.coords[1].x = ox - dy * ho2 / d; dev->shadow.coords[1].y = oy + dx * ho2 / d; streak = (dev->width * 1.6 * d / bwin->lightH) / (1 - dev->width * 1.6 / bwin->lightH); dev->shadow.coords[2].x = dev->shadow.coords[1].x + streak * dx / d + dy * ho2 * 0.4 / d; dev->shadow.coords[2].y = dev->shadow.coords[1].y + streak * dy / d - dx * ho2 * 0.4 / d; dev->shadow.coords[6].x = dev->shadow.coords[0].x + streak * dx / d - dy * ho2 * 0.4 / d; dev->shadow.coords[6].y = dev->shadow.coords[0].y + streak * dy / d + dx * ho2 * 0.4 / d; streak = (dev->width * 2.07 * d / bwin->lightH) / (1 - dev->width * 2.07 / bwin->lightH); dev->shadow.coords[3].x = ox + (streak * dx / d) - dy * ho2 * 0.5 / d; dev->shadow.coords[3].y = oy + (streak * dy / d) + dx * ho2 * 0.5 / d; dev->shadow.coords[5].x = ox + (streak * dx / d) + dy * ho2 * 0.5 / d; dev->shadow.coords[5].y = oy + (streak * dy / d) - dx * ho2 * 0.5 / d; streak = (dev->width * 2.2 * d / bwin->lightH) / (1 - dev->width * 2.2 / bwin->lightH); dev->shadow.coords[4].x = ox + (streak * dx / d); dev->shadow.coords[4].y = oy + (streak * dy / d); /* printf("renderHighlights(%i) %i,%i-%i,%i-%i,%i-%i,%i-%i,%i-%i,%i-%i,%i\n", dev->index, dev->shadow.coords[0].x,dev->shadow.coords[0].y, dev->shadow.coords[1].x,dev->shadow.coords[1].y, dev->shadow.coords[2].x,dev->shadow.coords[2].y, dev->shadow.coords[3].x,dev->shadow.coords[3].y, dev->shadow.coords[4].x,dev->shadow.coords[4].y, dev->shadow.coords[5].x,dev->shadow.coords[5].y, dev->shadow.coords[6].x,dev->shadow.coords[6].y); */ dev->shadow.ccount = 7; /* * rather than fill the polygon, we need to generate this shape, and lower * the shading of pixels that are within this area. */ } static void considercallback(brightonDevice *dev) { brightonIResource *panel = &dev->bwin->app->resources[dev->panel]; if (dev->bwin->flags & BRIGHTON_NO_DRAW) return; if (dev->value < 0) dev->value = 0; /* * We now need to consider rounding this to the resolution of this * device. If the max value is not 1.0 then we need to put fixed steps * into our new device value. */ if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].to != 1.0) { dev->value = (dev->value * dev->bwin->app->resources[dev->panel].devlocn[dev->index].to); if ((dev->value - ((int) dev->value)) > 0.5) dev->value = ((float) ((int) dev->value) + 1) / dev->bwin->app->resources[dev->panel].devlocn[dev->index].to; else dev->value = ((float) ((int) dev->value)) / dev->bwin->app->resources[dev->panel].devlocn[dev->index].to; } /* * I am not sure this is desired functionality. Yes, it reduces the total * number of events sent, but there are issues with multifunction panels * and memory loading. if (dev->lastvalue != dev->value) */ { if (panel->devlocn[dev->index].callback) { panel->devlocn[dev->index].callback(dev->bwin, dev->panel, dev->index, dev->value * panel->devlocn[dev->index].to); } else if (panel->callback) { panel->callback(dev->bwin, dev->panel, dev->index, dev->value * panel->devlocn[dev->index].to); } } } static int cx, cy; static float sval; static int configure(brightonDevice *dev, brightonEvent *event) { /*printf("configureRotary(%i)\n", event->command); */ if (event->command == -1) return(-1); if (event->command == BRIGHTON_BUTTONPRESS) { /* * This is hard coded, it calls back to the GUI. This is incorrect as * the callback dispatcher should be requested by the GUI. * * Perhaps the MIDI code should actually be in the same library? Why * does the GUI need to know about this? */ if (event->key == BRIGHTON_BUTTON2) brightonRegisterController(dev); return(0); } if (event->command == BRIGHTON_BUTTONRELEASE) { cx = cy = sval = -1; dev->flags &= ~BRIGHTON_CONTROLKEY; return(0); } if (event->command == BRIGHTON_RESIZE) { dev->originx = event->x; dev->originy = event->y; if (event->w < event->h) { /* * If width is less than height, then we need to configure * some offsets. Also, we only want even number of pixel areas. */ dev->x = event->x; dev->y = event->y; dev->width = event->w & ~0x01; dev->height = event->w & ~0x01; } else if (event->w > event->h) { dev->x = event->x; dev->y = event->y; dev->width = event->h & ~0x01; dev->height = event->h & ~0x01; } else { dev->x = event->x; dev->y = event->y; dev->width = event->w & ~0x01; dev->height = event->h & ~0x01; } /* * We should now rework our parent understanding of our window, since * it will have altered. */ brightonPanelLocation(dev->bwin, dev->panel, dev->index, dev->x, dev->y, dev->width, dev->height); considercallback(dev); if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_WITHDRAWN) return(0); /* * We need to build in some shadow, to prevent the rotary from looking * like it is hanging in mid air. */ brightonRenderShadow(dev, 0); dev->lastvalue = -1; displayrotary(dev); return(0); } if (event->command == BRIGHTON_KEYRELEASE) { switch(event->key) { default: break; case 37: case 109: case 65508: case 65507: dev->flags &= ~BRIGHTON_CONTROLKEY; cx = cy = sval = -1; break; case 50: case 62: case 65505: dev->flags &= ~BRIGHTON_SHIFTKEY; break; } } if (event->command == BRIGHTON_KEYPRESS) { switch(event->key) { default: break; case 37: case 109: case 65508: case 65507: cx = event->x; cy = event->y; sval = dev->value; dev->flags |= BRIGHTON_CONTROLKEY; break; case 50: case 62: case 65505: dev->flags |= BRIGHTON_SHIFTKEY; break; case 0x6b: case 0xff52: /* * UP arrow - we need to put some bristol keysyms in here. For * portability we should not include the X11 headers but map * our own translations. */ if (dev->flags & BRIGHTON_SHIFTKEY) { if ((dev->value += ((float) 256) / 16384) > 1.0) dev->value = 1.0; } else { if ((dev->value += ((float) 1) / 16384) > 1.0) dev->value = 1.0; } break; case 0x6a: case 0xff54: /* * Down arrow * We should have this consider stepped rotary motion where a * single up or down would give a whole step rather than a * micromovement */ if (dev->flags & BRIGHTON_SHIFTKEY) { if ((dev->value -= ((float) 256) / 16384) < 0) dev->value = 0; } else { if ((dev->value -= ((float) 1) / 16384) < 0) dev->value = 0; } break; case 0xff51: /* Left arrow */ if (dev->flags & BRIGHTON_SHIFTKEY) { if ((dev->value -= ((float) 2048) / 16384) < 0) dev->value = 0; } else { if ((dev->value -= ((float) 32) / 16384) < 0) dev->value = 0; } break; case 0xff53: /* Right arrow */ if (dev->flags & BRIGHTON_SHIFTKEY) { if ((dev->value += ((float) 2048) / 16384) > 1.0) dev->value = 1.0; } else { if ((dev->value += ((float) 32) / 16384) > 1.0) dev->value = 1.0; } break; } considercallback(dev); displayrotary(dev); } /* * Adding a fine adjustment control, and adding a notch into the motion * control under option */ if (event->command == BRIGHTON_MOTION) { if (dev->flags & BRIGHTON_CONTROLKEY) { float deltax; /* * We should have this consider stepped rotary motion where a single * up or down would give a whole step rather than a micromovement */ if (cx == -1) { sval = dev->value; cx = event->x; cy = event->y; } deltax = ((float) (event->x - cx)) / 16383.0f; dev->value = sval + deltax; /*printf("Controlled motion from (%i, %i) to (%i, %i): %f\n", */ /*cx, cy, event->x, event->y, deltax); */ } else if (dev->bwin->flags & BRIGHTON_ROTARY_UD) { if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_NOTCH) { dev->value = 1.0f - ((float) (event->y)) * 1.1f / (dev->bwin->height); /* If in range 0.45/0.55 - interpret 0.5 */ if (dev->value > 0.55) dev->value -= 0.05; else if (dev->value < 0.45) dev->value += 0.05; else dev->value = 0.5; if (dev->value < 0.0f) dev->value = 0.0f; else if (dev->value > 1.0f) dev->value = 1.0f; } else { if ((dev->value = 1.0f - ((float) event->y) / (dev->bwin->height)) < 0) dev->value = 0.0f; else if (dev->value > 1.0f) dev->value = 1.0f; } //printf("%f %i %i, %i %i\n", dev->value, //event->x, event->y, event->ox, event->oy); } else { double angle, diffx, diffy; diffx = event->x - (dev->width / 2 + dev->x); diffy = event->y - (dev->height / 2 + dev->y); angle = atan(diffy / diffx); /* * Adjust this so that we get counterclock rotating angles from * mid top. */ if (((diffx < 0) && (diffy < 0)) || ((diffx < 0) && (diffy >= 0))) angle = M_PI / 2 - angle; else angle = 3 * M_PI / 2 - angle; /* * To correct to clock rotating angles, with stop points. */ if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_STEPPED) { /* * Stepped controllers have limited motion, not from 145 to * -145 but from 60 to -60 * * The '7' is 2M_PI + M_PI/3 */ if (angle < M_PI) dev->value = (M_PI / 3 - angle) / 2; else dev->value = (7 * M_PI / 3 - angle) / 2; } else { /* * If the angle is negative then we are PM on clockface and * we have motion up to 7/8 of M_PI. * * If the angle is positive then we are AM on clockface and * we have motion from 7/8. * * The '23' is 2M_PI + 7M_PI/8 */ if (angle < M_PI) dev->value = (7 * M_PI / 8 - angle) * 4 / (M_PI * 7); else dev->value = (23 * M_PI / 8 - angle) * 4 / (M_PI * 7); } if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_NOTCH) { if (dev->value > 0.55) dev->value -= 0.05; else if (dev->value < 0.45) dev->value += 0.05; else dev->value = 0.5; } } if (dev->value < 0) dev->value = 0; else if (dev->value > 1.0) dev->value = 1.0; considercallback(dev); displayrotary(dev); return(0); } if (event->command == BRIGHTON_PARAMCHANGE) { dev->value = event->value / dev->bwin->app->resources[dev->panel].devlocn[dev->index].to; considercallback(dev); displayrotary(dev); return(0); } return(0); } int * createRotary(brightonWindow *bwin, brightonDevice *dev, int index, char *bitmap) { /*printf("createRotary(%s)\n", bitmap); */ dev->destroy = destroyRotary; dev->configure = configure; dev->bwin = bwin; dev->index = index; if (bitmap == 0) { if (dev->image) brightonFreeBitmap(bwin, dev->image); /* * Open the default bitmap */ if (bwin->app->resources[dev->panel].devlocn[dev->index].image != 0) dev->image = bwin->app->resources[dev->panel].devlocn[dev->index].image; else dev->image = brightonReadImage(bwin, "bitmaps/knobs/knob.xpm"); } else { if (dev->image) brightonFreeBitmap(bwin, dev->image); dev->image = brightonReadImage(bwin, bitmap); } /* * We should take a peek at the second image resource. A rotary only uses * a single bitmap, the second may be used as an alpha layer. */ if (bwin->app->resources[dev->panel].devlocn[dev->index].image2 != 0) dev->image2 = bwin->app->resources[dev->panel].devlocn[dev->index].image2; /* * These will force an update when we first display ourselves. */ dev->value = 0; dev->lastvalue = -1; dev->lastposition = -1; return(0); } bristol-0.60.11/libbrighton/brightonLayer.c0000644000175000017500000002363511746476474015573 00000000000000/* FIX VERTICAL LINKS */ /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ /* * The toplayer is used as an overlay, initially targetted for the patch cable * implementation started with the ARP2600. It may be generalised such that * multiple toplayers can be defined with some kind of stacking order. * * Toplayers should be a panel option? No, keep it at the global level since * we may want patching between panels. */ #include #include #include #include "brightoninternals.h" extern int brightonInitBitmap(brightonBitmap *, int); int brightonSRotate(brightonWindow *bwin, brightonBitmap *src, brightonBitmap *dst, int a, int b, int c, int d) { float x1, y1, x2, y2; float xstep, ystep, srcx; float length, height, shearx; int offset, cdown, p; /* * This will not be a simple rotation. The bitmap needs to be stretched * first, and then we are going to find the lowest * x/y (of a/b or c/d) * and rotate the bitmap up or down from there. The co-ordinates are not * the central point for rotation, we will have to fix that too. */ if (c < a) { /* * Let c/d become the starting point */ x1 = c; y1 = d; x2 = a; y2 = b; } else { x1 = a; y1 = b; x2 = c; y2 = d; } /* * Find out what length we should have */ length = x2 - x1; height = y2 - y1; if (length < 0) length = -length; /* * Go stepping through the virtual src bitmap, taking the pixal value from * the true source and placing it on the dest, rotated. * * Going to change this to transform rather than rotate, we first stretch * the bitmap to the desired length and then shear it to the desired target * elevation. */ if (((height >= 9) && (length >= height)) || ((height < 0) && (length > -height))) { shearx = ((float) src->width - 10) / (length - 10); for (ystep = 0; ystep < src->height; ystep++) { cdown = 5; for (xstep = 0; xstep < length; xstep++) { if (xstep >= length - 5) { srcx = src->width - (cdown--); offset = (int) (ystep * src->width + srcx); } else if (xstep < 5) { srcx = xstep; offset = (int) (ystep * src->width + srcx); } else { srcx = 5 + (xstep - 5) * shearx; offset = (int) (ystep * src->width + srcx); } if (isblue(offset, bwin->display->palette, src->pixels)) continue; if ((p = ((int) ((y1 + ystep + ((int) ((height * xstep)/length))) * dst->width + x1 + xstep))) > dst->width * dst->height) continue; dst->pixels[p] = src->pixels[offset]; } } } else { int oy; int h = 1; cdown = 6; if (height < 0) { /* * We should take the lowest y, ie, probably swap the coord */ h = y2; y2 = y1; y1 = h; h = x2; x2 = x1; x1 = h; h = -1; height = -height; } shearx = ((float) src->height - 10) / (height - 10); /* * We need to stretch and slip rather than shear */ for (ystep = 0; ystep < height; ystep++) { if (ystep >= height - 5) --cdown; for (xstep = 0; xstep < src->width; xstep++) { if (ystep >= height - 5) { offset = (src->height - cdown) * src->width + xstep; oy = length - 1; } else if (ystep < 5) { offset = (int) ystep * src->width + xstep; oy = 0; } else { offset = (5 + (int) ((ystep - 5) * shearx)) * src->width + xstep; oy = length * (ystep - 5) / (height - 10); } oy *= h; if (isblue(offset, bwin->display->palette, src->pixels)) continue; if ((p = ((int) ((y1 + ystep) * dst->width + x1 + xstep + oy))) >= dst->width * dst->height) continue; dst->pixels[p] = src->pixels[offset]; } } } return(0); } /* * This will place a bitmap into the transparency layer at fixed co-ordinates, * for now probably full window stretching. */ int brightonPut(brightonWindow *bwin, char *image, int x, int y, int w, int h) { int i; /* * Find free layer item */ for (i = 0; i < BRIGHTON_ITEM_COUNT; i++) if (bwin->items[i].id == 0) break; if (i == BRIGHTON_ITEM_COUNT) { printf("No spare layer items\n"); /* * Consider returning zero? */ return(0); } bwin->items[i].id = 1; bwin->items[i].x = x; bwin->items[i].y = y; bwin->items[i].w = w; bwin->items[i].h = h; bwin->items[i].scale = bwin->width; if (bwin->items[i].image != NULL) brightonFreeBitmap(bwin, bwin->items[i].image); /* * If an image is specified then we should try to read it, otherwise we * we should just put a default red patch cable in. The use of ReadImage * ensures we can share bitmaps if they already exist. */ if ((image == NULL) || ((bwin->items[i].image = brightonReadImage(bwin, image)) == (brightonBitmap *) NULL)) { /* * If image is NULL then we could open a default bitmap however that * would make less sense than just not painting anything. */ printf("Failed to open any transparency bitmap\n"); bwin->items[i].id = 0; return(0); } brightonStretch(bwin, bwin->items[i].image, bwin->tlayer, x, y, w, h, 0); brightonFinalRender(bwin, x, y, w, h); bwin->items[i].flags = BRIGHTON_LAYER_PUT; if ((w == bwin->width) && (h == bwin->height)) bwin->items[i].flags |= BRIGHTON_LAYER_ALL; return(i); } /* * For now this will just place the specified bitmap on the top layer */ int brightonPlace(brightonWindow *bwin, char *image, int x, int y, int w, int h) { int i, a = x, b = y, c = w, d = h; /* * Find free layer item */ for (i = 0; i < BRIGHTON_ITEM_COUNT; i++) if (bwin->items[i].id == 0) break; if (i == BRIGHTON_ITEM_COUNT) { printf("No spare layer items\n"); /* * Consider returning zero? */ return(0); } bwin->items[i].id = 1; bwin->items[i].x = x; bwin->items[i].y = y; bwin->items[i].w = w; bwin->items[i].h = h; bwin->items[i].scale = bwin->width; if (bwin->items[i].image != NULL) brightonFreeBitmap(bwin, bwin->items[i].image); /* * If an image is specified then we should try to read it, otherwise we * we should just put a default red patch cable in. */ if ((image == NULL) || ((bwin->items[i].image = brightonReadImage(bwin, image)) == (brightonBitmap *) NULL)) { /* * If image is NULL then we could open a default bitmap however that * would make less sense than just not painting anything. */ printf("Failed to open any transparency bitmap\n"); bwin->items[i].id = 0; return(0); } /* * We cannot use a stretch algorithm as it does not look very good. We * should find the lowest coordinates and do a stretch/rotate operation * from the source onto the dest. This is not really a function that * should be in here, but we will put it here for now. */ if (y == h) { /* * Just stretch it to fit the given area. We may need to check for a * similar case with vertical? */ brightonRender(bwin, bwin->items[i].image, bwin->tlayer, x, y, w, bwin->items[i].image->height, 0); } else brightonSRotate(bwin, bwin->items[i].image, bwin->tlayer, x, y, w, h); if (c < a) { a = c; c = x; } c += 10; if (d < b) { d = b; b = h; } d += bwin->items[i].image->height; brightonFinalRender(bwin, a, b, c - a + 6, d - b); bwin->items[i].flags = BRIGHTON_LAYER_PLACE; return(i); } /* * Removal is not really possible, we have to clean up the item in our * list and then repaint the whole lot. */ int brightonRemove(brightonWindow *bwin, int id) { int a, b, c, d, i; if ((id < 0) || (id >= BRIGHTON_ITEM_COUNT)) { for (i = 0; i < BRIGHTON_ITEM_COUNT; i++) bwin->items[i].id = 0; brightonInitBitmap(bwin->tlayer, -1); brightonFinalRender(bwin, 0, 0, bwin->width, bwin->height); return(0); } if (bwin->items[id].id <= 0) return(0); bwin->items[id].id = 0; a = bwin->items[id].x; b = bwin->items[id].y; c = bwin->items[id].w; d = bwin->items[id].h; brightonInitBitmap(bwin->tlayer, -1); for (i = 0; i < BRIGHTON_ITEM_COUNT; i++) { if (bwin->items[i].id > 0) brightonSRotate(bwin, bwin->items[i].image, bwin->tlayer, bwin->items[i].x, bwin->items[i].y, bwin->items[i].w, bwin->items[i].h); } if (c < a) { a = c; c = bwin->items[id].x; } c += 10; if (d < b) { d = b; b = bwin->items[id].h; } d += bwin->items[id].image->height; /* brightonFinalRender(bwin, 0, 0, bwin->width, bwin->height); */ brightonFinalRender(bwin, a, b, c - a + 6, d - b); return(0); } static char tImage[1024]; /* * This is called for world changes */ int brightonRePlace(brightonWindow *bwin) { int id, flags; float x = 0, y = 0, w = 0, h = 0, scale = 1.0; for (id = 0; id < BRIGHTON_ITEM_COUNT; id++) { if (bwin->items[id].id > 0) { flags = bwin->items[id].flags; if (flags & BRIGHTON_LAYER_ALL) { x = y = 0; w = bwin->width; h = bwin->height; } else { scale = ((float) bwin->width) / ((float) bwin->items[id].scale); w = ((float) bwin->items[id].w) * scale; h = ((float) bwin->items[id].h) * scale; x = ((float) bwin->items[id].x) * scale; y = ((float) bwin->items[id].y) * scale; } sprintf(tImage, "%s", bwin->items[id].image->name); /* Remove this, it will result in the rest being repainted */ if (flags & BRIGHTON_LAYER_PLACE) { brightonRemove(bwin, id); brightonPlace(bwin, tImage, x, y, w, h); } else { bwin->items[id].id = 0; brightonPut(bwin, tImage, x, y, w, h); } } } return(0); } bristol-0.60.11/libbrighton/brightonLed.c0000644000175000017500000001362511746476474015221 00000000000000 /* * Diverse Bristol audio routines. * Copyright (c) by Nick Copeland 1996,2012 * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include "brightoninternals.h" #include "brightonledstates.h" int destroyLed(brightonDevice *dev) { printf("destroyLed()\n"); if (dev->image0) brightonFreeBitmap(dev->bwin, dev->image0); if (dev->image1) brightonFreeBitmap(dev->bwin, dev->image1); if (dev->image2) brightonFreeBitmap(dev->bwin, dev->image2); if (dev->image3) brightonFreeBitmap(dev->bwin, dev->image3); if (dev->image4) brightonFreeBitmap(dev->bwin, dev->image4); dev->image = NULL; return(0); } static void displayled(brightonDevice *dev) { int flags = dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags; brightonBitmap *choice = NULL; if (dev->bwin->app->resources[dev->panel].flags & BRIGHTON_WITHDRAWN) return; if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags & BRIGHTON_WITHDRAWN) return; if (((int) dev->value) & BRIGHTON_LED_FLASH_FAST) choice = dev->image4; else if (((int) dev->value) & BRIGHTON_LED_FLASH) { if (((int) dev->value) & BRIGHTON_LED_FLASHING) { choice = dev->image0; dev->value = ((int) dev->value) & ~BRIGHTON_LED_FLASHING; } else dev->value = ((int) dev->value) | BRIGHTON_LED_FLASHING; } if (choice == NULL) { switch (((int) dev->value) & BRIGHTON_LED_MASK) { default: choice = dev->image0; break; case 1: choice = dev->image1; break; case 2: choice = dev->image2; break; case 3: choice = dev->image3; break; case 4: choice = dev->image4; break; } } brightonStretch(dev->bwin, choice, dev->bwin->dlayer, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width, dev->height, flags); brightonFinalRender(dev->bwin, dev->x + dev->bwin->app->resources[dev->panel].sx, dev->y + dev->bwin->app->resources[dev->panel].sy, dev->width, dev->height); dev->lastvalue = dev->value; dev->lastposition = dev->position; } static void considercallback(brightonDevice *dev) { brightonIResource *panel = &dev->bwin->app->resources[dev->panel]; int callvalue = 0; if (((int) dev->value) & BRIGHTON_LED_FLASH_FAST) callvalue = 1; if (panel->callback) panel->callback(dev->bwin, dev->panel, dev->index, callvalue); } static int configure(brightonDevice *dev, brightonEvent *event) { if (event->command == -1) return(-1); //printf("configureLed(%i, %f)\n", event->command, event->value); if (event->command == BRIGHTON_SLOW_TIMER) { /* * Change state of display. If we are still configured to flash then * request another callback */ displayled(dev); return(0); } if (event->command == BRIGHTON_FAST_TIMER) { // printf("Fast timer expired\n"); /* * We are going on or off, we probably have to know that here from our * flag status. In either case we need to set some value and notify a * callback value since these are used for note on and note off events. */ if (event->value == 0) dev->value = ((int) dev->value) & ~BRIGHTON_LED_FLASH_FAST; else dev->value = ((int) dev->value) | BRIGHTON_LED_FLASH_FAST; considercallback(dev); displayled(dev); return(0); } if (event->command == BRIGHTON_RESIZE) { dev->originx = event->x; dev->originy = event->y; dev->x = event->x; dev->y = event->y; dev->width = event->w; dev->height = event->h; dev->lastvalue = -1; displayled(dev); return(0); } if (event->command == BRIGHTON_PARAMCHANGE) { int iv = (int) event->value; /* * If we have a flashing option set then request a callback. Do not * change the color bits, only the 'flash' bit. */ if (((int) event->value) & BRIGHTON_LED_FLASH) { brightonSlowTimer(dev->bwin, dev, BRIGHTON_ST_REQ); if ((iv & BRIGHTON_LED_MASK) == 0) dev->value = ((int) dev->value) | BRIGHTON_LED_FLASH; else dev->value = event->value; } else { brightonSlowTimer(dev->bwin, dev, BRIGHTON_ST_CANCEL); dev->value = event->value; } displayled(dev); return(0); } return(0); } int * createLed(brightonWindow *bwin, brightonDevice *dev, int index, char *bitmap) { /* printf("createLed(%s)\n", bitmap); */ dev->destroy = destroyLed; dev->configure = configure; dev->index = index; dev->bwin = bwin; if (dev->image0) brightonFreeBitmap(bwin, dev->image0); if (dev->image1) brightonFreeBitmap(bwin, dev->image1); if (dev->image2) brightonFreeBitmap(bwin, dev->image2); if (dev->image3) brightonFreeBitmap(bwin, dev->image3); if (dev->image4) brightonFreeBitmap(bwin, dev->image4); if ((dev->image0 = brightonReadImage(bwin, "bitmaps/images/offled.xpm")) == 0) printf("could not load offled image\n"); if ((dev->image1 = brightonReadImage(bwin, "bitmaps/images/redled.xpm")) == 0) printf("could not load redled image\n"); if ((dev->image2 = brightonReadImage(bwin, "bitmaps/images/greenled.xpm")) == 0) printf("could not load greenled image\n"); if ((dev->image3 = brightonReadImage(bwin, "bitmaps/images/yellowled.xpm")) == 0) printf("could not load yellowled image\n"); if ((dev->image4 = brightonReadImage(bwin, "bitmaps/images/blueled.xpm")) == 0) printf("could not load blueled image\n"); dev->value = 0.500001; dev->lastvalue = -1; dev->lastposition = 0; return(0); } bristol-0.60.11/bitmaps/0000755000175000017500000000000011233572002011770 500000000000000bristol-0.60.11/bitmaps/icon_bitmap.xbm0000755000175000017500000000161211233572001014706 00000000000000#define icon_bitmap_width 32 #define icon_bitmap_height 32 static unsigned char icon_bitmap_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0x1c, 0x70, 0x00, 0x00, 0x03, 0x80, 0x01, 0x80, 0x00, 0x00, 0x02, 0x40, 0xe0, 0x0f, 0x04, 0x60, 0x18, 0x30, 0x0c, 0x90, 0x04, 0x40, 0x1e, 0x08, 0x03, 0x80, 0x3f, 0x08, 0xc3, 0x87, 0x3f, 0x84, 0x34, 0xd8, 0x7f, 0x44, 0x08, 0xe0, 0x7f, 0x44, 0x04, 0xf0, 0x7f, 0x22, 0x04, 0xf8, 0xff, 0x22, 0x02, 0xfc, 0xff, 0x22, 0x02, 0xfe, 0xff, 0x22, 0x02, 0xff, 0xff, 0x22, 0x02, 0x80, 0x88, 0x22, 0x02, 0x80, 0x88, 0x22, 0x02, 0x40, 0x88, 0x44, 0x04, 0x40, 0x44, 0x44, 0x04, 0x20, 0x44, 0x84, 0x38, 0x78, 0x42, 0x08, 0xc3, 0x97, 0x21, 0x08, 0x03, 0x80, 0x21, 0x90, 0x04, 0xc0, 0x12, 0x60, 0x18, 0x70, 0x0c, 0x40, 0xe0, 0x2f, 0x04, 0x80, 0x00, 0x00, 0x02, 0x00, 0x03, 0x80, 0x01, 0x00, 0x1c, 0x70, 0x00, 0x00, 0xe0, 0x0f, 0x00 }; bristol-0.60.11/bitmaps/images/0000755000175000017500000000000011233572001013234 500000000000000bristol-0.60.11/bitmaps/images/algo21.xpm.gz0000755000175000017500000000041011233572001015404 00000000000000eHalgo21.xpmRU*.I,LVHH,RRHI72(ȍUUR2P!C%.%dT[V677W5t20q``$Q=zF m8 AGt=d!!5Ȉ N9pڣ@ [QB8-~aQ Sцr 8r3 n6=4 TT`6RÍW![Q^ACZk._$0 bristol-0.60.11/bitmaps/images/algo7.xpm.gz0000755000175000017500000000046211233572001015337 00000000000000eHalgo7.xpm 0)zk$VTGADJԊzw]&[7Ńthd?I,Sx;?X 0 e`6̧;&aM;pfId#bHj2bfP(0Tt0) C GdfQ6L Ne@~p?QQؗ;>dd &;by3$)yFz9ӈ-Qi# m8u ]ϓMS!ۏLS3Ef*2ϑ bristol-0.60.11/bitmaps/images/algo3.xpm.gz0000755000175000017500000000046011233572001015331 00000000000000eHalgo3.xpmM @+1$ѥ{1/CrwfݕT ̼̾Mf1xMr MpYNpwnmP ar<GOEI'$/$! /%d\`A_-x&fiԻ +OB2v ɸgPDP  ^v.δ"ȻIK4uz?tђIT0ؗ KV F^#xuy_ %H&W,h`,egϫ{WKV|>:>]-~IdZKoq'm"Rd_*>'Z)x7{0 s1\=1S *h(x鵠 xkr|Ri/5~N4~*>GLQbJF&r'rWjWqpqDf0 [8'pDQ+qsl"F#l! ƒAe ك(Qz3ФclB~f>:,)PDA`SVCL28xɰg5%hër`V*F֨VjYfie,jrz jy"["kd9nY5 a#l v#(TB5 ,%\P>6!Rd+8GzQ4SEFIg`7kҲ3'?:):sdSb9S$Sidu\@R\KDd ҇$J׊:p֕8>pg,JfM*r[.Z$%L 6 S))HI0uݕPF0X>*ʏq@hIᯡ/qe{H+ǤiaS(ϻ.G-'!bA^}ч|(CvvFjZAA< ~wy Ľ,@p $ph%κv'% T $@Pu a,#lj;h=㎇#K/EwG"`CEqU *YG|^ %\z+@F9Fx>H`%-gE,yyo֗ DzG~O~I/Y?gJc7uIXH% 5%‰\y8tUԚa L\]wMUjb 8DZWMЮ$e|D ?=G => R $ƚ.E3g$Y-k6q 0ڣ4'`|ThW+ EŇiZ4\#:=؟S+LѐgB(Z vCQ[K(eBLJN@=(Ҭ ])&MÓՏ׸& Zuc"9@SJ1Lף 66J3 3U"cwo[M81  e|Jx9 J0e8|Y/ՏҜWSŪM̄²sx^]?񦷓,VO]3?p* 2r]S8,XH.,TMfGgx#%MaG4[UX3ۃPR*`+Ibx'%~$U|1Av=pvDK7jt ]f.H]GQan>&(FPUq`LX:JXs*[zq%WEl!bf#^ Yq.QQV-3虞h]GJb%S89]9w?nf^ck0{Ӳpb/iPD4]M+J섵[tu̴9&L{H7b崤0 $C6(odCa-掋X)^ }$l}<FHyp-rKnjzG_ MFήMnj`^ q>bje+͡d1"e6fx|;/=VX=ȵRKBOZ+nB(!xЮ4䪋y|U|Ҹ#H$L,@rfnzF>7|ʆF!*xݞI5*b) -ex́qXt~=Q ( bJ ]u'vidA?a H( rh:\|n%tcR@=龜~it!7NK K2J HirV4fi]9\kpzMF@/Q}t} 6C=\cJ.ڱpHՎMJnn+Dbi9g[=&ڣkI??Fq 3?Ю4 }Xꘘ.=TLjTIӳ8|ht=q ܺ" &jcz~ ~Qt-"uPKAϑ: ?ϑO94e7ޤNŮM`uҐ5c}V9'$Q< ̊idyDYfNkۓl$"P7 >UKЏ=X$|@D#t: ]^_i6%O,X~ xӟys*9eI` Sχ!"9KG O|SFyj(=#"k\| @ۻc@dS[MϳsR]O뙹|H|K:2I_m?N0B>\kHBP}4%UO%?@p7MyT۵y]As⏾XOi9SDuN9"'up$TBVX|qUR&4~T:h#՞SM>UyUGbZ׾ᭉ"r$0SM(>*^ÁT5FjuUsJF(S|([J;3 SYmAGkqOcт &f**ɑq`I8|Je$dzVO]ΪzÆ,RtT ^:B>~a+R tg*3͜fZ,Eڮ [2cEXzLPes4ɏ"w湕;~9@W,QouUf3LI 0IRX3h7uao TO [Ϧt$c_䟈*1sN3ʴnb>DG הA I6"R)|3痤`՛mτSJ/6Jvm؀=RLtFxZ>*WxsThCVa9Ȼ?,0_N?a=rN^T'_RƂhH1 03T3UIaPmjF)* 6$ER@h:kDzIUr}2?KGUU7MI)j2 0d5MTzuX7 heS崎g 9yuRȬJA[cX@q|pc_-Ǹ)gƜZiZG9UH!zA-SuJQaI{Bk{چs\ : j*s6'X](nIRDT S#XQR㋱_=6 \CʫIKګxޮ׋f }5;^H#};%}?HK҂G,)7O=pX_ڤG,?RvNS?GUԴ$*Ysӛu@퉔rEE}g3DzW7y&S"'(58m*mRg/H6u4_3ώI27ئ֘Ƶ sNEC]MMCڕN@b,}2Ν2m;Զ _Y0s1?wЦ]Kf3̃L:Lf"F,uBEYWu.)ㄳcYcgjb'$R~C(zgj)0 vѿhj%ɻ6QSkKyMqkuDW/OgY j]X<~t1V3NݺxH72=zeR󴚇Jd<6`IђRSmk[ ŰTt֭4|\s4S)=  Hc (҂RBD@ѕ{TZf̬Ȧy:4e[< Mq#wP*9#d^gH!aɛjD厬S}BY'.rq#'):,h8Y(iMݛj)#ZOTSiu(SɧI52(SUz|GVJUb"4/jtz"=ƦM)T7QiQs\ bW;k"1 7>_K'w^%R#TY;EdJY>h;8ux#MSu6HSHB >:G|s.=di)'Yt7nϜmߨj[⮛p}d|n'vZ;Vh!reFUZWМ49g&P0ɾ8mXm*5 D rQr+5+OuԀk=%RyP&_?qħ͠_RCMmX lt @QA#=b9B48rUs%b(+\~T 7j_?4[y\s.Q ~.lTOjmTvt0<$8uZ(VDc |\R_I/R(</ P^ɋn݁ in ƈ)Y&A&aBQPi1hҙ:TsabL"TIЙf_deSC1MR Jd|i.tvcAu_g% }'Wl'vq}wQW6lQ'/37,Zο1Aq#dý`/f ;.|^+-BfȲ7,3 tdA @)4lao`Z~_1fB֒\ous T֒W\nWM)!K{;Y|[S _Y,n1|49(r=畯_*2&V`Q\[ˀh.fqr4(@Bn:z}A!Ys7z;+AIѬܻ{AN2 o{;yg4҂q|LsCTj4+iu@PSXRUYM'<>ʡ ɏKvg=|]X^?D"{ߏu$%t)MJã|T)""O?E-^>2pB]%;#%S?y<Bn/akgP+~rAH;厲"w@|pgG)F?.f]n`R"]qOCTj(-7@Ƚf-D?#v),+찊'ف$j G]#Bč=ի驌^eJV//AtA/B=LA$W*% yg^0-:aOOπ$+Ky~ƧN y\p{JUf{&󇇗տ *_6e^ޗ#{zR #LVJ^iNP61 EwVvkvE#OP*Dʖr)ys%x~Uhn+rĈ+jIA>,Ƈh&ޮY˱]{ltW{+ѪL1Ž:*cK /_,N1n Sg[ʃWb}&<ݽHܽ7ABٻ }6*cw9w@6ThY\w$B)ֻbx ey;¶[jR\Z Sh'{Hb {aϪ7r"4e7 nIc眔nߩsZT~z=*2vҝe3d]Qd۴jGF>Vj/vY1N=y"i4Oxmm'W6 rRk? 7mz߻>G k+Yo!^++#4Xv)?CoF-tgn|τEx8mJǏFXDn JiU>}7UX3 ֝~/6]Mj4;dIU4bUHQ=xUZWhos)To[jϩWrAK uNx~hSmg -k[qO;%mngi;f_W= 㝶ǃisG瓪$.\XIIքpmT[gvJJr6J'kj\ޞm[U+֘vzILtS梘>,Vl6/$6ACu^x5̆~D`Af=>,ne2^^7:ف)k ԰#auV ѿ=ڋiEa%Eio֥T?/[v0\lZS}gt񹾇rBѣh}^EOj}#OJŒx0KZ1؈gk„/Dqw=]uf?Hz]94=33ߒmsu([m[BWS{7ڍƊ8lE ^XJ꺟]e/h&6rc}qsn}MCkzcWXۊlH֣;4Uג3q{+O:j󪗟8CFvMZtRy]+P 8uicD1+ |zzyHJ|YqnW'a|Ѭg$٨oz] *0?6kZZt]rbSL4CK~;IGw_5]/Sb"t#'zU~!盌w\Cc02~5W]~-p5'0m(/80/^J\Zbc"m9$+G@|xzStN;fl Oy' fFJUO LLğ1 __(F$(y8MH|绛90w:˦<ڄ:N14bT&<My(ϽNLy?ԡS-'NP"lvh1AucjN0sSlM ZB:cHKf!L^ x'D LxNY}isG8yKxPxpO(3n9Va@ߺ{w~? Zx0_܂31u"NWvwf:S0#M@u/Vduzir7{rc(t3~ M+{||^>B;?;eԙ9ns:US9>jt'"LtsMWL:)ʦ6>,ܴ݅U9Hτ4<[?~j/s&`" ~*l%BwO IV$lQݰЯJmc.3rpSn󵾞+hf|ar>pv2#)veqonGUPJ?, L{ةKkp},=]-77j^"IR̭y}b{^%ǝ"mLf̵{p}SI8=b\>dP%D;_XNaKp'9I{Maҵm_>Pn_wF:--plaF^Jla5t=}M9~u~56]p +n"~s;]*؆E妻޺SK?A_H-(X]_6&8nq_u#}?ݿ!_%o&לu k18&}9,GRR6L!@a(leHhԨJVzq*Ɗۥө W|O= }&̅yuܻ0UVYsWvI~n b䔊D`ƒnsqi^,9]`݄b!Qr][4XA m'v n]MjIam.[aQA _$n[+3&oqw V $n۶G7~|HY2u?J ߨsNX$8X~]z@)=f$qv$ѝ)TA4WK3s:X{AJL- Ls}wCFu()[?.pm,@Í,J+~EDm98UAC5aO >#ݳ)v`d&wc D>q^m5΂ d;Jm0ckG4s]"DXT{i}]3[>QX`;\y$]\u nf<܉&֋2/#w֥.]a )vL &R9`VekYܪk-]bRsKM>]VX>?;),Yz&8T͛hbf\*"9uM&3:+Rޘn2{5n ( Omg[=VngnѢ˽ڌ(uR[~Hp=̭:Jn)ѕ_munm;\g<~*"A"{58=UmMQ9gE Ɣ`qaI m25sU꯿_nկuVoe.%+vn\k&R嶲n _?rSr9Mg}oT̓z,kLjCRTM)V<:ޝڜ\\ d\MsxZ/[S]+_uxݶʶHo#Q2 64\Kfj![%T.* NU(n+ֽeFn|j yrT7b\R庢Mc嚙j>w!u%BEs8c _׆'tOOYH[5:Rc*Ku'LD }E(5G8t5,LyVrgUōO%iW??RZߠYYr҄FWh? YR Ƒ$j& lu tӟ}Suq#B oTI0e C2Fr5 `VkBȭ0bV8)(r=rh?!2] {XT 6TC!rY-y,ͪIVDB '1X3)LԳ0iDo Qѵrk@6.&c.o!bTUߊT@(xI%F0j҄9QBã(1 WIlh&ern já%eB4xD.(D3꠪WRD`h(Cؔ !bK3x`,?%M&ާ)iP'jYZQU$J>*> QKDu9鬂=1ɇ<镪N'rQ˻.7+Ɓ MMe9MUɺ׎ 5,ȸ Y$IR L`lN&eyxp>[B I 5ZFV伩kF94iaL?L;j!tNTOX%2+v~"g3^QעMҠh! mI&[P}Iۢr;M5>[ClBs)qC#N F-FJ6z q0̚:4ӹ  h`?2 j$.N'Q)/y4HVQ0r'Q⊆J\,ݬ>{Ae CDiH UTFk}D`4j _ yDwQ^:-nBfD)H)?G=WrP;oMzTk4hVMH Iy )1ZptR k(\QAM)88JMU^g2̊XIei# B1y@X "ߑ&њ\ TO$kRԏӈD'SZU%CW/أ$Fg.!MJpL)Gq@D~5`C&ͦBD4;Qg@%B"A'@D37P Z>c 2>5#%Y8Q+ *3 r&ZP꿯|1# ?;Afv?M`HՃjvO-Ϧ=2Q0 ԌHffH@[$|P'gP|oǟ`Xx"6bU:s[}j&LKiU)32)ED1w"6tzzfJzFKu~h<$(P"KhVڦx۶Bg- ay lô(گ)Ɗr$p~pM9]:0Z3O&l6G!UJ[@t%BIj"XC+5$D> [k^ĬPy|_EOOpͱ~̝Rh Qh|(j,OY <5I;h`(E2hW͘/ƷEN% T< | lM;BrlUR7 `q`1kF棚m#Ns\<" F4Zz@Mjd U֯"L8uN ìE8vJuZCIyZI̡V ܉okߖrjzgho5- |41j4|,] zK {$%fhʓՓɉ4tQSr$ 99;@IIqr D\GWiFXH#Y0'VPyE8=%-* JEj5˳ͧK-}iKC*1ə$WK"g/_g'Q|i_0 Ă ( S5!  &d!REؒܫ`p' Jk'5nB@$|䌢@_@NL?XL,饘rzƄ !/S=/|Mhd ._Na%Ic4`|`X $Tvt9 GKPQԽ g%`2: g..`8+XVEqKXa eJYۥ|2dHsDSuvCQ QD>vWQo>e JR-R$%4Nوa !*bristol-0.60.11/bitmaps/images/vu.xpm.gz0000755000175000017500000000224711233572001014763 00000000000000eHvu.xpm_o6ƯO K T9m&rDWզbҴ&Ug_96`Ҹ:~Hs||ݷd4뗯NF?6<')5yNAH3Hl琮 ]x )tl 4>˴4kHQˇAZ?WY>{)b&G1eZG-[ŽCs>t(~RHO ~@@)CS.vFd(BV^ouG.3k\n?FH_H֕ދc<^X?x|?C\:Q;mi0ڜI'ݰ sĻNIۛ^d.DQpqFətqS lw:qpmB<֯`?;NF14~NSx?tÆnj` Vv`fN0 "Y1(h@S6&~ uJĻme 6ll1+Gg51u6V”G bJo#"% H/{y2*mT ^y*iI})55S!s'\q! bristol-0.60.11/bitmaps/images/algo0.xpm.gz0000755000175000017500000000037711233572001015335 00000000000000eHalgo0.xpmRU*.I,LVHH,RRHI7(ȍUUR2P"cC%.%dT[V6t20qA\0$z!.L6CQ4;Y8U6zPܦmzpY/ j@#`?dCMWt3隸Lh\tMH=zX܆ ףARqg0i?H0g멵_ bristol-0.60.11/bitmaps/images/bristol.xpm.gz0000755000175000017500000001574411233572001016015 00000000000000eHbristol.xpm][s~ )"9&Q7N1Ivk%d[9y*wsF;}N @8yݛ77{ϻWW{˽~<Mg{ɏ?Ǜ;sqT=NqR<Džثggc~ZyFsB@{`8c;Rm3 FӭuQhЌ_@Ϫ'lM P[Fƪ;L*93qua[w좠D.362Z`meqCGv u!ZpzqG!(ےw+Ym`?RXF v>-N3\]Uvŗ7;<Z؟\[oē:OvgWt?},Dp6П 졠mP5(|<<%7"Q=>O)ή}H֘?>n7Fs$գMD&lէZv@WS4ql!MiR{T:A:Ǟ5B_kyp9&೧$_J鬇)pM>UU #)F>P8qALL<"fQfxdCK/?3P@`ZAund3y2qWa ˾Xy'Ր_ X9\O&E;nqN1ֿoNMTi3㊈-@Z+rPXcnA2GE 8MZ 򽌝> _`t|vK*b n9 )$N9 Ù]6ͭgvPJ:G=]>_ z4Li;3$&,_adopDmĠAs1snhџ|~87hi9>\ܕ<%BbxU"%6G8B_dNs(:,tAו]ƦV!t#:Ħdj0C h`}LT:X@cqʈ k $ ւBo ϳ>aÞg?,L 1^Ox G$Ubj"C$rȸT16EjV AJp;V]sx'xXH B]: IN(cc7.ʁkNOgйA*{)29XlD3EKIUiHCr"j2#%6:e(,)џ 우`(8gMYBm|񹊄!r%TTC}X%o޺8?}ZWC@'|RrD3x-[i)V@?iXw;9[%`7G_P?LhBB?$j bZ 9yuHp4pGEPg9$h0C2S-ZON8kh19 Їe1,@i ŋT3d$qd٘ zxRZ:[,$OЏv?K 8={2xE"G0#ӛ[6kS,̊7DJ0sb֧D(^송nm>(%)2GvP c.pQPiQ[A;@-SJ,Fp`8k5 SBE&3(QAKbob1d/ OM>|)fϷL1fvdngk\D=_*QOrD\< ,~{&"Ujrvz@8ek\F:*QS|20x*)M.i\mh#8`Y<)&Κ@簳C(`+T&j MP0`kJD D(@&Hff[D9\@>|c_ZUg8'J*s<Qr2ICRk9hnw#_LQG$]{GPr.$N`#rBQ\2A^iK(d*K IDF4ɰ; ?G+ED~\4Nu^Aٌ^o 񟈌] '1Kg z(:x}j@mtzmDlfAmRfr@ ?gx0 ~t] %jB4 ))p\P$F1=N8%[F[S u©}&/( hO/ DȺ VhwVm;haؗDUhfgD3L4%〚 &,٨7%7wpMn]4MK4JoNoFSM=,E16ȯrYѡ%T Ȟ3#c>O%~w(Υn/3Y=-WзG<|[f+9 r7;-\@!xea٨o]Nj!,A=\+4& LF+JN!&i{ȭnC2{BKln L}o +{"D@Bkȧb]ǤQWV׈'kmt{-ڣ34:E GUB \I\JqPW Z]tw(צ2͓xbPM=EqL=z7nU>*&ڐ\0#Zȟ 9f g, MRѦ{F~ FMd8JǠ~7 OF S,~\v bristol-0.60.11/bitmaps/images/alphadisplay5.xpm.gz0000755000175000017500000000030111233572001017056 00000000000000eHalphadisplay5.xpmA 0е9ŐQ("TKADB-P5.G3?I46%t"7eh*P֡7vB:PD/|npTRi4JSjkىR{ҡ2P )Q~{DoE1OPbristol-0.60.11/bitmaps/images/alphadisplay2.xpm.gz0000755000175000017500000000034711233572001017065 00000000000000eHalphadisplay2.xpmRU*.I,LVHH,RRH)HL,.I4(ȍUUR25P02PP0TRRLVKlesWqA\ qn *. ⪀ ⪂N ⪁ dv`xrpЃ@P*WW TU P _p%pEH8I(."jbbristol-0.60.11/bitmaps/images/op2.xpm.gz0000755000175000017500000000037311233572001015027 00000000000000eHop2.xpmRU*.I,LVHH,RR/0(ȍUUR23Q02T0V0TRRLVKle psqA\g0Ro6 "X̀ #i0 CVl,TC`l ʴєa5Cfz]/F 3$1g]3n $Al430 n38B1,aHE. Ԙ PŌZk.Mbristol-0.60.11/bitmaps/images/algo20.xpm.gz0000755000175000017500000000042511233572001015411 00000000000000eHalgo20.xpm @S vsB(H"ފADDQsE]]Y%ÿάj9$ x:?D}zD cu8ll9ftdw)Wii$2|<80(cPʠA9# 5ܷő%GAhkLi 7r&僢-EϤlݘhLdk+[w߷ͻ\7Ϙׄ_u0 bristol-0.60.11/bitmaps/images/cableVred.xpm.gz0000755000175000017500000000132411233572001016213 00000000000000eHcableVred.xpm[Pǟ@Qpn1,VibXI>4A=3Z{`i_'̙x_^׻w?mwZU#%ƅFG`:ho|wWD> H % 32d5E JNcr-dD`jrEB ە|rG,gH4SlIp@ѳXxJl0+=-6^G~!l[bT+QS`~ h, X"GӥΜ $K13(bq8~,({V>^ "0}׵3m?x2Q=Z4Syj͓r֕wF]x3~]YY*|W [v1)O wO3S^a3Nebܳ*S8r]xU%8xÅ?VarMgGG 3y@yB-Nk< w'B°.+TT; w?›/yxg}cstV_ξǞNl- 7G:±:u[h̯guj̕9eee{eʞ{hrR14zr݋dc<ؗޕLS$:S2P' bristol-0.60.11/bitmaps/images/algo1.xpm.gz0000755000175000017500000000040611233572001015327 00000000000000eHalgo1.xpmRU*.I,LVHH,RRHI7(ȍUUR2P"cC%.%dT[V6t20qA\0$PG`cգzX#GMz#T=zD E4hzhaGm$r=tMhaML1!CH L pMMĄ54J"'br9yp( B`TPO5Oв7 bristol-0.60.11/bitmaps/images/algo15.xpm.gz0000755000175000017500000000041611233572001015415 00000000000000eHalgo15.xpmRU*.I,LVHH,RRHI74(ȍUUR2P!C%.%dT[V677W5t20q``$aG$&]6zȱnzH 72 R>|3]F!tlkb{փl9l&r06ɳn֑IWX]#qiwX3Ir"Q$Q34ldȰa#F 62ldȰa#F 62ldȰa#F 62ldȰa#F Z&ovV)bristol-0.60.11/bitmaps/images/algo2.xpm.gz0000755000175000017500000000044111233572001015327 00000000000000eHalgo2.xpmM @+iIt^t "B$*DmIPЋ+x =r%'UM[0/0lbɚLH3$Q`:aLR |P󑞍RXd{Пh)fg?"LƼFUAl0 bristol-0.60.11/bitmaps/images/algo6.xpm.gz0000755000175000017500000000042411233572001015334 00000000000000eHalgo6.xpmRU*.I,LVHH,RRHI7(ȍUUR2P"cC%.%dT[V6t20qA\0$`ף գ#]zȱg0уM㇌tՉC|7=#m0Mo8)ӣG @׃ ,COXr bgR RQazat!d!GMmڨnCe"A&16t TU#!p8M9]C4=驵yL bristol-0.60.11/bitmaps/images/greenled.xpm.gz0000755000175000017500000002574011233572001016121 00000000000000~oIgreenled.xpmyWE~ FfXUL41FY@%Nխ[Kuu 1$7w&:3_ry93ٿ;=ǟ::o?I<~2y>toNĠ+M$WK=_c1~bO_q_~?O z>'??y}͊|a~z8^q_??y9/x^g`eOq_~?VY;j<ƻjrxA}5^Z!y,WX9zSOt+X] ;]9TUu}p^?~&_oWsc~oyw8Vo -z_ű8^. %+_MCk:?|U~6.ۦ?znf} Vym'oߒ@G7pڬ~wb<;;K܅ڜ|r5]./;uFGN JXgsW[)g$}[Fܦ4_n}&֯hh}#֯ʏ?[-ھCFw_#Fǭ_%G'_'OF+3L7m2Z$}@f:=5NߐفdtHhJ=5s,dΐYHOI۟/@DkWgFRT +nHM/-?~a͹ݖٕpONĂ|9'zz/CL¯-0@f^}GG!fLimp[@##DKL8Ԛb^ !$}zf3~*đ3%BHi . }Hhf]5;pl>֟>r1s3ʹ&Hڌ=˟Uڡ=ҬOC |ޞd`NقCe Ͽ@%+/G)h}HH <L^k @cuk=PCih?:?!ƈJlfN p_̪᥂r*Z, aZ~K~d$L!)U𲖕 dT\kqn ;:kVKB}kF PjdpiWa"8 w"̗4,hK hDdLD`@3 aU\?\k  ,4AQ=%@6KIl"LX> d9`.@m.Y<`da,oˡ o@+$Kp"4 i5@¿k<MF"=!òЇt}hw$|7Qお+@`tKÊF$NfUCm'`^r Zq(PiXQj!OusO[c iwP%-9h{vch@;!r <<9'&&.HH)VLg0:f%n@Ğ85}U@U5VڞxY՚jW& DCoIO&** 8ڀ kUGcH^K*Wdp aCBZQ0#z}dŊ,ud qBt$7;I Z1#t_)`y}P#3m%dgK,7 8YC#x:F#{TP+K'Dy4$|9QhRvGcaEVHPe#$$T3ƴ-wpߵ)fyl؈z+IH.@  joB,L4U+j H:;O%-O,\|ee~>DB .x  < *HYm-e!I~r#yV!#) X:2@:k f" m#\G`]BYl}$stDZxXm-D],#$i9H{n|cq޸N ^8RF/i1n &dR$T:2\.t̀>}&.dB`$*s=)^H!Xg3 8. /f@c p uz&>d3xa6 ^c$#hs֕/<s~}C}c1%biҾ-4i Ь缸/L2'PVpwP5(f8])"xu5@:0<|4؞?U8kܘNk bIӉ1< YAȊC~}2t[_~DH3#, Y\/2\56!!/R =Yx%d?r& qZvbR$\EH>D 1԰`Q>iU}عF.]Gx m$ޭ~Lb!2IQ)fS fB8Tk=%cI׹=& jE)ŬtIFj_4Y;\$DOBO@F& YOjIG#,*yFypoaU*|ނY ?}RJ13g0\fg.okE/-Ă9r <s/!!]M2kd9zmx3ك<}@s,P )@CB!YK8+%=̛6C# Sz\QfuD@,֢ʱ@¹EBO!Q{:dkbH0y88p 3%GE*B(bFS&!>Ē"r| `P, s&Ll h qZaIEhROf r(y8 ǡm(f^S5(vLZkĝV(W^ѫf1(2m9\ˑ`2$pxwUIX4X q< ^f6uKBr_8$P#wyaB$: [ ?= S]e_ VMWSkO/bkVHC¢)uBc$!G&l0#arH S$1TTS{u_t2yz]'rۻ=dm`~zw$xjK1&$P/[( KCDV:EA އE)'"a\UIEOjztB~f)oL 0 $u6gOm;PGxdhR$j=a^C'1$dYt$P{Hck-1ΨIg`Q*<;}JihY+v7%יRێ hqB@$ƭT9Q=Km0N{vjPckq䄣Rhw,X{Ͷ $% ۭ脽.B$$Paӣf3Q!O(pϢa[Uc8VȖ]">$YW@UKy f_/MpdmNWQ"h(X ~O&T٢ _P&20t`[R[TmYTO+`RcV0KUYMg`Jho/pYaeHX"Tt$WFҙqYI0U|{+ w ~>ZǒFbG3 oG Ayp%//p>Z%[4z(NB}H{v5"D3qPda_5J/Ɠ8?6 N2uWR,GGr` }5K$w;Tb)N|eú&_BtBg$.f>>6mv-f>,l+]~2|,Z7ʡx{;W (OIr/},d5_>9PX7Hp={7o!& `ڈ /nj fkw$?>eWF鼄*$@jt$Ig˻{nqwǒxtÔ^+o(@W:郓* u ;"Ax $UYNB?G_ /6BV!+~ݻHϖ>$L~)nrd@Z` Cg@=ǽ7 `nRWWHB#L8:!.} 2ݍ/O+d3`w4N3kMc$08K0چ$!"}|tå%:%삛8IO+1 /]k-].&2wffV-UpOg&+aGj`K4SgJV 1}`/!mKBV[kٓHj&,OΓq֏:jФ0pۀ{I賎rSa|g0UH]cO@'R13ޕFX=kTvg3~7OAs`_[i' A*Q|zlx>W@\?zᕰLO^lC3$P4YZWO I6"8W3E)t_L:!+FEʺXu! ?dӳ2J<``p,oZ wam%4B Ś9VD*Q ٺ!Kqе8>%W.7.EhZE? Ghvh̩\Gb!y,JBm`s*8GГԹsItB;BD,ks]O-/ҹRR#]g= :.Hc>)d\ezmB mH 88K^.FQ$FuΙu7M"ݬ,Lfp W.c>? cfuy镒V&(gyLAIA^-.['ev5B"^2" hY܃w9 \?d{![Ug[йf>"`ᢎ%!F+62Ǘvx:OB9 DsݷXE·Zcɓ(_ƑlO;tsGD$UrDG)m)b"<4b%;UJ30Ԡ֡5#z&;g^hZ(hCשHt+`JE / mͻyisǽ[VVg΂$Ge, qZaUʞ8͉cJu0@ ADT95nylEk}B!ZaN|z!N,Հe艼y 0 檖JXA#HW|$ei{s,.a}쿦l׽ؾb^F#ZW(o4Ybש3_G K@j!80zOdܾή^شhұ3e#!M@}iKhě6B+X Q6i` K1@A#FS٤3ۍ`.BоUYثd.Z|0)H`VlP*]22,lXb3;yt#'7rv{4qP Y oN#a'DUIwĨ Xp.sp┊8z|Q1Fgݫ~}hM 6 ]P]j,C:O1$7Ψs eO9@+npCapeKB`R`U̮!r 2p;Vۅlb5`g8SԚI3z eϮf>sor̬Ϝ3U@F)nX"x:ًrP򫣄Un@/_ȢaEs|\[qLNHXUYc8SLg~(4eH Βg%bٱ[BfSSc9ŴBQPXoS[LS pg<ﺛöOnjY9^h`7qN eIxC~߹jl,ddqqkZmw\(GI׵.3đo!T©PXz;ED?j#c_oJ)I~*,6,)FT K2^0 ppD/Q-gHJ$ CBV@p _HyDPKߐsVNz]6Ӯwq$`T!LE!r,5SRW8%!QWck 7Y>~aXIgv[y*mj'u4 }G95ɓ{`$!<.nxoiTƊ}2tNv!V#T# *Dp,%=T% VmӀɊ3j $T Ԙ]I)n>ª!^*TqSC))HBHV{Z?)H=AU}UȨXwy)8S(PY@mP, *vftv(߱Rp;Ppn糨3i+q.TUՏHѢN庴O1HRj5pMUESk:HHHt2+ahౢ .u D i9HM'l&4rGz-ąHHnݪ,2R*cz+ Yk8U^iS;ق/R# UX/:̥&(dFѰ ZxJ?(iJ,+Mp#zdt(-B$AHOSvb"!ԙiuiU V_^TSPwր$CBf R3)pŅ$ "Lte1NNߟ !}EFnj+wi8VX@]IB:fT [{ol$dީ-AbsX :Wp؃ pP/ 畽GWD ʇFq [ѝ|ܵB_x Uقy @>O%6GWiKA(Zk @ 8ձi gث9F w'!- @C_~THٌ=(_^vB[3;ZU]]nB4A3$fxô6@*0g7,R ,4j )x-0vs`(O8'_iYaIZeWk})Si}M$͒|0!Yèʏ AI{s. yhih!!~7 ;a!AH3Ҏ}Q!mIa#AȟA|gKbX!1 !JHs^ھan=wBg>32*$Ŝp (pT|ɡ 2z$<b JJ۳nJW: -0.u@7HI<I/ _/ T^gv8|Tbristol-0.60.11/bitmaps/images/alphadisplay3.xpm.gz0000755000175000017500000000033611233572001017064 00000000000000eHalphadisplay3.xpm1 @/9Uz`mEc VEOKK~zv5 Սn\I.\*38>@14I)R֐Y4hso; ( a@0@FKr)]C@RƆ!G>2_oLPu%=w\w"FUz}Io"bristol-0.60.11/bitmaps/images/blueled.xpm.gz0000755000175000017500000002444611233572001015752 00000000000000Iblueled.xpmyWF~)xc8IۤmiYܒ !|WսȋȆޓ6dYnsgv=1]}'v=8;{οeElvo>p/z.\zom|x~t}.Y7 ў}Dk[߮oȓh| >}u!o]~v[q|ؾ??c)GwYw-yg}[[ME_wIo}$ߛpm-|ކ_lKyCK ??Wqxo 7?-q뒿ȟ7x%|-l?s|? 8ߖ ߕxG.M=.\!:\!/7xsGs_m8}>P;x^|.~^\/_sf)o/mD[͖误-p~%':nm/n/ @]xc^E󝥎x8+":mv~Q\׌_,K ڻ,#[mK{ՉX>|~xw~ͦh=Ʀ?e]?G~ߏpΦhx?-q-Ѿp%7BItֶhpp~[WMdc{$7:~ؐǝH/gϻ(yنۢ@G!q_<~#?/G?>?BߒG /e[K_R,-z|$ ~;}z;2[$b=^6C'\plpk:;{tb'c[KnE˴:l9BL|N>xV|9}d2M$e}&x޷[m\ޱ=6(C w {l[rUf`_;n$)+ ;{a^[&e$̝| {+R6>4^8'ML$\ ( '[,$eg"$ˑs( ǕOH`3}_΂v$+(/YKI:۸0%#>͠m. [l=Al]^i1d3hY&;eQ~`tɣfK=J+A=!~b?5:O3B}{{N<) tM/W{KN< )&7!UF١l; $0ynٖjƌ{~Łs\Yȗ&)#&# yp{j8XRi$dvn,G~t-{(FQ"g;9 B88ds#d"R_}gN~>$ BDW)%6Bʮ)m+ _?(jϟHؤ)ƿff!]a);DT&*egמʣ j TGM?<ʜwJ+^8Ųbp`!ayX.: G5nW; wV-H3Hz#I'>(Z'\+Qw' a츪? ȶG_ߦ8 "q\?0HP-"~ =[>$xw6t >?O?6"Ld4QtdX1YWA`^ _mzvpdq$g${Z@>RefBKC'PgPrG&ЌP_ l.xQ|,EvL5T ű7r<>O R#`@w@M'Ӊi=tdn EOza<sjKF(o&!$=0OF0md10T`DPVx2Cgߗk5 ${#+q8RtıIo%MMx+o=y$ I{ ;ƌ Vb 6PG ;7{ B;JgfWZcŚbH`a4 YOG UQB_W q oVAJ|k=R DGo+fa9@M b_&'`DG cP1F4 `8Gv,4`|'VBfugD '=B0.z`7VtA 4sa49l:"qЙL%!{H Kz$w,_XZ8GsAz?D3S."_; Zx=| r AH4Yh6&R](CIg|EmDwˁSZJG]U#* XEehsA }KlB8h+~k%e$@ꎦTt0 M6BLњ,H Iȣ6˻ь fFqV΂}.U Ѥ;DEI˸Eޓ땧9{0'j'hYys|>bG9diuDmì c!Ak$2 ,d%!{_s e{#x* ja G? ?4z)}e߬2Y $еA+@ʹc_=-c%d fPRx* xU'ܐp+~4HxyC˲Jl "f}Pq$ǫIXZq^U+HzQ0(g;f0Y0탍YZW$rX?g58!jG 4ਔeoЕXipO3K܀>`g8$*$Et]B/qU@! g*+JG8xO X,$|3NT# /`zE _L\cK4$\[O9,Hx))hr@I(Sgβ$3Ը*_ xq=C Nu.(QjXV͖$! v_T9fpZ&>\W;;ԇ$<Δik@6xP}Z^0s: n K}UsJ8W4Ƞ~kfM-)!a.#C̉$4St}ZxRVڤՊ+?Đ$όcT$E3| ȣQ~^+& +> TBYV94TQ+V (\ Iψ97$$p=F[ʅOz F$; Npۢ3=D"+N3$׾aE' !}ݚJBKzn-f} =#CN^T4:LSp3 f$v!)VUB1$s 65՘u'짾+V;?ilP_M*gpM it=KRMp䩈MP=1 Iu} AX8S [nInG؈\G8uX:$_5$>4(!&[-X" ttBKY3aMs%Ӭy*B#$ /"\jWK $XAB'uK+9E@c(X0 n=~8P%aNv JEDBW]tO3[oG{v\?*|I%HHi$Gj:Q~$ !aYn) 8d7~+%ܲA8iPu8"#ӤGaJyIZHIO€>W$d!W,_+ʭQdHxiY$+"˔YM>j|Hxm!mn ~IHP)kFOH9vTZɺόJbIGtT}0iY$Q鴕*qu Œ`' 8(; AJku(=`'A FA2KNHki+Zu$tZHiIq$,S;]+|E/7H(Npcd{ڙ/HRcQ$ՌnkzrKp6P$ 6렓YqI1fIΆVMyFq)HP$UFPIp_Ӫ`vQz*bH3͌}Yn=Tb{zi$*bN|uҎAfEf&e{vw{gA}%sEbYĢzO ge^t6{hD6Ϡh_h.hu3'r[Wz5 tФUUܯijB6M`[e]1 7V}f!իV n{~5Erp@G( ;/aJz7a$'P(PԚqvH"&m1uyd.A%\W}6~XOBV "J=_V9SIXK)`$ V*rE%8 W+#pt53d`]pMݠR4~L&~I`=)UMʺyu;eC_\ς~Il!gB9s(LA@nlBz_SC9wHVHA' Y'W)8S؁G"&V6nA0A!4N#NI.hn>\Lc-$VH玑e@fچ*J­rH=pE`!);H;1]WEs?ЪF{͗GlEeu7| ;*KsZR!BG =@#7RCHN^j$va@EZXq>ס$<VHouK\}?87#L4ڼeP5¼ñJj$f!3abfUA+G (8{8}?ك=⇂8HcGj^NAb%cm$Rkpm 9*#* V+K@(@[@#Ԫ#PipFD QZ7kACg|9+@j$iq^̪j?yC#$*׈^$@L; }t7q$zbI=+s<8{tI,цdV2hAum,\G؍c~52 Afie#= I9Ѯjd.r 0Jf2UhS@}9:) AP+5;ܜ~>s[~YqE]!%b+^}fuJ5KFNg,j=5 LhuBbO"A++\XY8q J.t#N|JПiIଙoWk65@9PJFʤ0Ew6ufJM`5;|$TBg ,*L0^fU6WG8~MbFg:J`.FS e13 -e=hg|9$[,h !9G8$L¬j+Aݣ(0DC+ n x<:-# tO!B%迼HȦB@`[e:Yг/WO3`0> YYZ[:MI,IsRr8)hBʮYmQ>1BY2LFBV ]r$GPPcM,R:fpG¸; YYQDT.XDdtPG=wpi>ǘ]8 l!ֈ^:G L} -fYJwL09 -=`;)_E %bFU=2VL&'!oA柁&2z-ˁz@iԣu?va2ҐPh!tlҵ/+@e+PP"5t&;Xt$d R/`~!)פXH-kc]%$VaGJ.#P&4$ak+4t cתnhwZMzH+.%!0d]>x9zID~DC#LgqrЊ|DiK,I`h6:!/H4WKG~G*u2tO@c>P|C3ftŒy.IG+8'&2t Kv@lZ>h.=g'%絭cL;b(3= 4 Clဣ } ]=~.(+HȋzZA't?RZsF/@m@i6ѵMAV 1 h'."͐6B'9Tgu1bڠd'!?9<Ⱦ;8rWEt5]pPSH) !?U3xPÓl#5PGumPsf@Aa v2 IB."g "!O-vs T?=vVlQ?M~AD E(<8ȏ7ǥ oPc uv]R|*];l1f#S8@ʛ ǚܒ\Y@T4\H&dB h+@;$^,J_~$pwB%njN|'됿/5@A$p kB߂YmZ~}@8xXB@+ YdXA$ۂ cUBƭZJ|i}A+*W:U>29"B>~KgA 'V4hMi& !XLA-98<[ܐPZC"PCMŧD.4 XgC? HpBh+Z 5!ՐL4&%*@TA ܑ$l(i}v@9pŁK\D@l1؋HK̏)p=O%= @ġoOyGh'$d eЇ_XI(r>RZ pMA1$%bM :/P4ŐP4 X3~ }T eaz)+IQS$ W,L.M$\0/œpxRt ኆQG|pB$\`}ᗄ+$ps4^KB({¯nPBB(RJHw\N B) GA(e$!t($Hc)&!}w($%yne:H?ӉVW){v2}$H˳Āi%wO? Ngr0( Pt@Z5P2]TQosbristol-0.60.11/bitmaps/images/pro10.xpm.gz0000755000175000017500000000151411233572001015266 00000000000000eHpro10.xpmVMo1=_}4_%,$ͭ#BJHμ;I(=p`Jvy~=u7W;|{~|S|\uw;~*U?'Ϋ _'Iz}#G|_Y6rc l}us9C5P_-yȬzYAuN˗PxA Pl 5B]LXn͙X<ţ'~pusn1d/ch$P֨S̒qwП&g6m*j: Nbk5c!XcHً%+czKu #8 RBGOɑO)%1Oy@è7IăXR!AmXh@6!ʘ` avj"k65nN('259@"]m2l-cJVpZSXDh[;A|,NĆ%BuX*DsA Lbo-)@1$ʫ@=r`I=4 ?!}RVXMª6/xHt*9" t* r{rՁjVY.'{2KƐjPR]YَC=5ͥS+2H#@xDP#{|,>CP4NՆ7T{?hHٻ2rg? bristol-0.60.11/bitmaps/images/led.xpm.gz0000755000175000017500000000024111233572001015065 00000000000000Iled.xpmRU*.I,LVHH,RRIM(ȍUUR24R"C%.%dT[V677Wus .iCd:8@A\!ӏl a$ 5 .bristol-0.60.11/bitmaps/images/op1.xpm.gz0000755000175000017500000000033411233572001015023 00000000000000eHop1.xpmRU*.I,LVHH,RR/0(ȍUUR23Q02T0V0TRRLVKle psqA\g0Ro6 "jFabc5~T6`3Y c TUz8"3p%@UN30f`f" ,GJA17br,"Xbristol-0.60.11/bitmaps/images/algo23.xpm.gz0000755000175000017500000000034311233572001015413 00000000000000eHalgo23.xpmRU*.I,LVHH,RRHI72(ȍUUR2P!C%.%dT[V677W5t20q``$Q=zF3zI`=Fvbm$Z @4TT6LӋT{ ه6AʵnBvmq@p##~vFZk.NP0 bristol-0.60.11/bitmaps/images/algo14.xpm.gz0000755000175000017500000000044211233572001015413 00000000000000eHalgo14.xpmݓO @D$HoE "D(AsٲSxa7 l0Fmq ʬn,hD0+~n禛*xy#uݬYS`!uHA}  I׌ۧi^U;3(cܓR[-OQs3O(؋3 |DF)&%gI} AE¨krU}+Un1كz1 0 bristol-0.60.11/bitmaps/images/algo17.xpm.gz0000755000175000017500000000043211233572001015415 00000000000000eHalgo17.xpmRU*.I,LVHH,RRHI74(ȍUUR2P!C%.%dT[V677W5t20q``$Q=zF m@!hz#hcmz Q\znFF@aӣ ӃMdˉ`cl4 K.6, m$uPlVb9ics' w3FF+퐯x@7=\2tI0 bristol-0.60.11/bitmaps/images/yellowled.xpm.gz0000755000175000017500000001552511233572001016334 00000000000000DIyellowled.xpmiD?/a! n̷؏A[F/fl[yTI>Ʈ,, ngfef]߿ϻnVw/GI2$E˯w?ݽ蓇fxl޵O蓻|6h~CFBQZCSO̼ͫ6oZ|a^mB'jl~ Of|g~[W}e_s@cmhcjͿ~o=7[O[-; ?_/~eЀ/{|o~)DtMq{|0]_4_B?@Y]jW=QN9 5Ch>-j֡xhuكfݠfAh!|E!4ۭ 7OC)|⧚@꾤fWWSh~55]To^&|*ь__5&wA'~%71V0?c;|ٚ 솚=jΖq?sMv 7wG'n!skl֮.]gg _﹮A '_\ᮂ#-?c(@KY.OGQ" J%QRG %Bd$7g ٻ{p+*/ A !÷Sx|0Tj UHy C?j0TR|R~PΞ+bg+a*㪻h%YK@JPuDR;&0T-; c.9o1|_u+~;G 3o+/O~# QX^ L-h@ڙAj1|=(v? CQm /V(~ubJbQoZJ!!G(Zc8P@`4G Ff}·N8c*o(O*0OL1[ <&zGCwmb`L`6AS# #"o4|3* {$Il J)F5>@ oe=tܨRH-u '/Kp)s'p@i%)wW7Y4t4 -_q= h9E{MYf؆c1@ӈXDe%\!(sh4QbQft21d4*bB 8>`sƬgƠ@Ht;MgZ3@Aeybhut bCk R+4a" nJ h-k 8FVLI]t2#@08Ahg4ա %_[6_!V@&WO%PJIu8!!1uF@t 4!3 L_ml)Y!TDU/LYbf  ,&A}#/c$ bL?) !( BqfAC-8}rM2}| b 0 `&^ev:ƴ*r _`ӍVNai:弌@rW)o:Q041TcY+$\TK%t!{ }H$6H!*q (gsFTr0A4s=+P%=[N?m$UAc tnGu6$F :\ fS0b PPFq. z(t-0ecF (8y!6A,`SXi1XMmDK`P8Oita~1"l 'ﰇ+K *$YOdUG%]Wy ڸ~!=Dh\.L0 Ih0a:p*8H°pL(/4ژKg%d5u  (#\681U@w`mPox)Vj-\ϸXĔ{VXNJ=ZR!VKSt Vߎ%L\ Z &,䅨wg(ϐ%%2Y,\8r{ F>P6AEL+W2PI04h4'fʝ`UTL g 0L2K-`~ 0|k#Z7\[WME4=f_a2.~J"K=Z4:Y5VX>eT)YV2eC6Ϥ8_4fP߰Ii ' 6MϊĆu +K#wJ' E(7k-jmr15L*GKC+ G g3 @ +=X: K @9X'UaFҁm^I-9q9CymV fÝFM Ѻ@,<ʹiգk@Qx>d1pXUBqyZ!q BcA\À@ gnu0>0kwwV"Z,'L)V!!gIWGuIIWIA*; KL^-T>.NǖWf#&{ɫf[B93qH5:yJda}$hè'\LnC7a3 GE:7 jP@æ2 Q0`aX4%* 4Bt|C ֒AsLgY(1Hm n sty 0[QpR.P2`rpZc}cNHaZv:`8&ZB#`T N(B^rcHac8e,K4o1#'!a zf`W7-C}P6LB9N4:>+H^ Ê9 SF1<9pRȅO0H&1ŴjLð7A%Xu)0`>gER$J'p{F C#:Qa}BRe (24-c2ɪ9 էLvvPZ'b?Wֳv=XB2zjp:m5K-'p%mNYQ ! ݬEB K=QASz ГlmGg<9n7N7JZ}p unK9.v:"9mZnІm, OOaBkwV71paz4?Ulp}kҽ%v a/ -p]CA A/0 U?pČV3,(&E`iY'Q#e*ljfSaQ`rjXFA/Hɨ'\trPQC$^%kUYh܅yuv->;&PGÍaxVi&q8Z9oV{yY9`ۭ@Kǭw(ےduMr{mل8~k}~[0v֬͢3mC>Lå=6l ֘M%-n(sgV!  OmՇ+ bqȡQ` 'PXo2[Ҙ~rp#u.+:Pˉv9A7d٪{B #sח;:gUtv1'YI a ͱԘɕv$r[ގ+ۤ~N>ż3 U k;B)I? 1 I4z}z/ybǗ0p+lNQ2'a;|Y^Lܧ:sZ0)TSP((sw) SC]x-.r2  )$b%d?,qZ]oAYD_w0hrR@d%5O1qhDݧ ,Ōg$)S.w1Xr{x)x& -%1qHB*T þ5^N$(27{0>A1M.`FtgE*RSNW¡⸼)t9ahlp+JG ۔u^/;2 ͠_ yTbA:\*~s\l tQoxPϚfX XOxIBG 51&! ƒcpu[wL uvj1;6LpIe)IYd%&4l`H(5{Ml1Ծ{H6'Ptp| pT~ QCW)@"f]qv.&1@A4pf9{ BB{Bz "CA" z/WGq$ a*xr(+c05a-XL*EXWZ0D} hP !Wҁ KC@FAFB"9->1IpȤ^~遈z%Pg.:%I!i\0>q08qp\v98ÍpK +E0P@? b!(ԋnD>xPj +DP) Ce 1j߄C}c]64=S9wN_j޾4Ǟl >4G:P-W30`wLl\h.瞥2֢pԞ^!ڸ?9>;V^O.{J?n.Ҟ}I],7YߞֻaOm$ bristol-0.60.11/bitmaps/images/explorer.xpm.gz0000755000175000017500000000440111233572001016163 00000000000000eHexplorer.xpmYَܸ}Yw{j"=oc H2g9^nRL2TurϹ o0?_?>O㧏O_O>yz݇G?Kvgfvߞߞ_>;kհ]ʱNLJw;;kO /ް}8?"[v=ίwgvx|syiߎ66@c)~Ӭnku[\kMsIh 裮W5hS_3*l!6EuÛ0zD?qƽzvf67hImAP?{=Đ V|Pǝ:s^7zNPQ(hQ ڕпB66u$#hl a ؏ XQપGYx7ޚYJ@o4ES7QJ|.0DwAPNEы\\gT5NuhX!ape8m:?FUv(VH!9Wp; !~Utr@h4Sp y %=R%eHl)qh a pAO.F ng52CK 4؈Slri6VEy8,++14_g=(={K神:48) h2Ȩ@EG|A;Ìankoɋ; 5iAds`I`W\Lp'Ep X+{/dpSϳ2)ԄcdhLЁǃlf\aX`P\@#A&`cqQǍmd'Pޛ0GSI@BA!O+gL vr2!$w7 DS (uzF瞷%o8)!K| -, - EظNA/M`|a9p {\)W:_ADSr b7H^ǣzD't&#*BxWK E DiL <)L 8ҜeP?RA fPD 0'f @@B(#r40I<.8' *7.kFʁ f- -;"pRE^LcQt7A@xIWAkkhH#QS<_毈<#we>qWи|^j`@hįC#}SCTCx WjF7+ZbW'>I>4~fLz37D#x{ f䛉[/F\wOh!;}M>~x3-ωƤguhEmʸ"ZcTwrzaCtx|O382 ոg'|EgU3H]rf܌Ø!}1^y[j)e ~3O|eԫJEu竈EehT'G>Ϳ~<LjUeeG؟ey>,sea|((C@V0Mg-Q&ki^EchI83mYϦ{_kІMXeXA[4{Pa>[ho:\c+_˨uψ4/| ^SB <3gȳ+kփq?{j$O.#xg7xJz0csZywv?l^'r4nW1*+߁0_l jt[ג*&/&5pJxZxIgO Q9jJj/࿦N1ڪIM+Wp؃U>0 O+j%ΑPaAc$&o4so~f]|cn|䬽/>zbristol-0.60.11/bitmaps/images/sphere.xpm.gz0000755000175000017500000000121111233572001015605 00000000000000eHsphere.xpm[O@W (+}>nP (`ԇM9,/3t:Ŗ&~!Vm6E>M>O'/E:Xl)?WΙQ;rsU~Vw}L!`A!9 F^#`̥4IGG@9 EKG:c{k;fd-Ε$opEdW ܯ[R"{Еh}t@F@ɥtyq/}HC.!` +s\ lK"`A# p3.usmbXW>rZՙ^|F8tŒٲ:*nUDg+0ˑhXrHYV_ޥv(G~,muk_ѿ~|߿|7?\o~~ŗtѓg< ''?|{l዗_~ΡCi>pSv-r:?~Ρ9L~ F?}a~Å/9\9|>}.xm?mE&~F律C+ֶm}5yYƬߡwx5E7N[;}Ҧnx֮0ՏxStnUM4;f^O <ѧB*5s~bjw]=4sA_i 3iBƻ16xwgI2Vo~]O‰Tu3ČN>9}o N((#@,) 5 u"̄ *^9`ݾIwtڡtGF0  Á!΁7 9{BaB>,=HW: sIO]_0w{2$FmqL)y;h"!zSX'pԢ;IELԒ T!U|TQņs<CeE1QS(_]^b;u؛u]qOA1S088A80.d AQ'vܶ1  L KAdZw`I`۫"썃3ɗ2G%4@q05Y Nqo8Oy"k2 ;N}4d6ռ;8@AR^ n.7>Jb *ZPD0eGN)0& xPONn%b UDK;28?RSGQ\V[_h)0dpAPܾz6k< nؓ R7``q!.kTtL xKIыݨ#{Yo9zD't )JxZvɗ EDuB*L 8ҜF_je^ :r2fsgN(&U-YX_  d K quʃ˚`rP|+d1KV]Y8Cj~ԋs,r" O/a 1{ `-)`לH5<B2D ?uAed8E8hٔ]绥`8) z<k $i*ʝ֦,a*WAP9F8=ѕ(7 =-⩻K~c7,>K XY 3f\)XIAQzRKsCdQdPP=@..3b 5 SV5l!Zk.Ri ^n8pA(HAUh:L)V=4Mg0\aV x;q= ?U"1%ԕB_e'`BMAG^ |ۋTiVD8u_ HT*ݕg2P &P#qIг^ZPE3 ^;3 QBr)- dF}| Q@ F1'Pű֥zQ{q'\bO*RwFNocm&y:Rݙ苃kQf ɕ@oY7346[[m= 6-+T둃ι俿7m:v,' N/( {{*Z:-ӴkI3g[Z-?Ake׀~VS@bristol-0.60.11/bitmaps/images/cableyellow.xpm.gz0000755000175000017500000000141111233572001016623 00000000000000eHcableyellow.xpmU]P} X>D@^.[>6!`imi7iޙAkwm/=O̜sk҇o%aʏo)Y.5s'$vm_]KoJ5>;𬸀ԟ+"pHADC"DQ4d!tuC 5x,B:B қ9|vPot܀ldcz;tV, .y t*JR- %FGy҂z2 s[ZAHDU4! ֜&'YYlFˉ¨9(~E"e9\>QץE (YhO4Ns˲cAqHMQ5]/(7񚪐ezqlI{#բkbY{ n6b'ɹD.F&esL-TZueff6 $űadYr0b-PUB ݊RUa;Ps,} a9B70oO+r@@>KIԪ b{_<˺־.V..ƗhsRhj(CGj$i[ڜvE}hvzSQ C `~.gyP {ki=Ɨ@59wES٨ٻЍ?jRt6|MTǙ^>9B? (,j-x݌׫Z_ bristol-0.60.11/bitmaps/images/algo12.xpm.gz0000755000175000017500000000043011233572001015406 00000000000000eHalgo12.xpmRU*.I,LVHH,RRHI74(ȍUUR2P!C%.%dT[V677W5t20q``$Q=G0x886(zUӣMT{Ip##~ u˱A8bz1 %4z! e *Cj?Ez`,q@ h@znC7J: _6@@1nzjHy0 bristol-0.60.11/bitmaps/images/offled.xpm.gz0000755000175000017500000000025111233572001015561 00000000000000䠪Ioffled.xpmRU*.I,LVHH,RROKIM(ȍUUR24R"C%.%dT[V677W̵  +X6@Dą @P0>bzV!Zk.',0bristol-0.60.11/bitmaps/images/algo19.xpm.gz0000755000175000017500000000043611233572001015423 00000000000000eHalgo19.xpm @ݜH$DHTP!=W[v]WY%ggw4`aj8!}d>eG0}+ ')qgԣUJ׌阎,$K ՌhHfP`52>Lz9O{k0$Y΁nAS` 1Û+|tfFNA:>!e8}ROdF&[gn~o S2zoUF%F=~Ƽ& G0 bristol-0.60.11/bitmaps/images/op4.xpm.gz0000755000175000017500000000036211233572001015027 00000000000000eHop4.xpmRU*.I,LVHH,RR/0(ȍUUR23Q02T0V0TRRLVKle psqA\g0Ro6 "z(Sf6V3PGea dep6A 3\,fB׋fG& l$$нGlx~q-^3>43Pd6qf`I s=^3`aa N3T1֚ @fbristol-0.60.11/bitmaps/images/redled.xpm.gz0000755000175000017500000002143711233572001015572 00000000000000enIredled.xpm՝i"Eր?ƭuJ2Y=l=㌎3.9yþbaAQƒ,Im. 2k~w߼z{?ׯ_|6^}jvf_ ?{W}o{HOEZhR@E3M?hX4s9lr_ʟ}Ϳװ zdD }5񐟈fl&Yaʈ% nE4݂h~.9Kfma3#HMV%zq]4]lfclY?e 6s9]oD3MGv0Cʹhf5` fM4 ̊f oYԡo^,ͪl) Y9JV#l$16jJSjJHU!%w;*k]&Ss_j>Z+k V|bMKT2lX3[ez̚7925kSyz,Xz7R'1A,ilVYRSX YgzN73]z<})O]|Hzow驾Mo٤w#S}/F~^G]yIe.,_L߽|.^EjTp[͸ #"ş>:.!{ bEI\ E\E0||A(paLb~1 q>vƀI|'+CD|n!>qa@ă/oLwíí/n í;'p^`uʵ1ܺ'nݺ+au?r \|qa \í;g p0ܺcr! \WT*v ݺK䳘1\b^oN] dww n% ~$F .aHv "Β!= 0ƦL&[VآJ$ va|s/o!`]-RD0t0yCܑ4KM책b$ddF?pt` R"d(9OF"`j&ߌCt d2t6=) Ád eBq j !46$*u?JQ:P;aX)EԋsPb t 2ivS^{B>cvEU"*qi* Q!4h Jun! $ј E0@"XH]E 030D8I2imy'( :8 5#0'@"yA~a+St:CoCTN;ړg:a! ~!g%%@!@meB=E=fS ʈ_|A1ԄCJ1d^SP3AD`); P" &ޯ> Ip_G?&^m%-#`#C̡>GaBUhAPy1:L#q_1~ݦI.}jBtQgc*&o yBc0{{ $m.2x OH~ D.K84`HꧢKx~Afe%6y^ s mr j:FEa#h ]d}0`J%d:U ,A8x rKPwmL6H-F^f#0aD)[g[UTkg1BO+ XF<օ2#*m o$% iDcb@6+8.FDnl $ 0W 9RdÈCbS*Z6@Hu}trMr 6w6%L^L12\T8Ȉ $EUy<.Q 1P:75ݷ]@ "E Kޠ[jF(ߩiJ!E=%!& w0@:Er[X+0c>R1RXcXۈ~2 |W0Qe! ?b{Bj1Z&CPp, >C$ &BH2yR0 n@."pPL6ňkAR][ s?y&̠Lz AKrS ŇABh8LC*NE 8ǹ fa@#b\N`]G`v 0rYMӠqk 1~Ώ'в#%䐦qZC G1h-5[;RMiz@ >YXfͳ?aФBmmɌc@xB3Kz!!qd6JLʉsdi##Nހ8{8Av+XH'Mk€^@b>W jꎐLFRL >92Xu[26 hPc%f## #x:tU7C:cπ2cȃIc@? d0 cpP0[R`rBp>hD &]'k&նC0taaStGN%U~\<#Tr?iXށf&_0@ 4HӚ12exĹt3J{XzV0:d!S'\+&pN$LW[մ) ތe 3Lrvx&-+&X1\3 œ `O+1@AAKB% 6M^ Qpb9A0,\/ u8=N; vV*l6y0i. !s ȡR̂f/ãB 3J5A(.SyA1wCr6F "KÒ' S7C J,0$ 0i*Tv6H j( ,4,uƨC1 ~U°)8=wɆ 1u-/|Ѝ(DXóSQU60!7&0D \j>mb + bJbS{pzj>cr!&hrj8FLC7Za(LMHkqQQEyYGB_"q_`51<-蛇x6ԐCŏ[DHNǽ`X!F Tq0T i 'A4`X" |/U!Kmt u/ cU4!*KaX : B mqCR鹜'g%R7 9(1p&N);!6q{+ 0Q`X=K 0 4KL%6 36OļQDW _S(MǨ zڇVlAp%RPvhcXdh}"隂U4iŖwDsU9WC f}6*) gʥ4P898WBw0]2ǰ+hK;6дRbX|0Fq8Z`l7ڳUcn'm+#\AIn\ٌ >H+hq#- 6U{D57ТTGAa]@Q~haob_icu0{ҵ 5 EɇbF[`( QHف l*.Li͒81"bFMRiPp} XYҪᲜ/sw!@ڸx|)a4% ( 5\=O{`8ǗW% \&u=0w%7Ws _&I 8P1QzVDlY`wm5Obho`r&sbkG!-נ- %[p>Vk[3-Mb l鸑k<7Oo`x* r59&YW64a/b C] :L E2 ~~dUJ{  ɏŮHE]5 wcA[nWf|>˨,VgN \4OشlMF1WAeC]ni[LRpI?-QjsuHu&ʾEǷ)VLqe?Okѱ \> OP4b~."[ ]ܘk2i&0@>maYqz\+t[%S*hG@7P lGU(`pr~ _wbaGblZ,7c܉, J,}Fa)O\Oܕ(0r{%$T%|>ߔY+^Rzz IyVuJ&(w2Q= f0 3:̷f n|ݯyHjlQxY%.C!ws b(T6ŌɜIe)}|wt4|Gg&6E ߡ 4O+ZPM[_s v(N);*48OrúeB}gT*>6*-ؑ&nR{'>Ǡ NGV.IQ?+IA ,剪ʃ~(usm uq+@rz8퐃CP_mBPTN70nI^ [<9]1 k> # LtDw!E&+A7sne܀O 2 x0[2%+]Hz4q> ?/Z1pZg<:19I9]id`♍?}]>d͏kSXQN8A(ƱG#}GctAp zÌH< >~w~ٲXׅd{ Ӊg\9I\i E01E ?~."8q-^@g~v,;]Y,"O} xr629g4laif$<;8(fȳ*9A,G9pT-a~Z&:=P @w8fJؓ'&r&&HgsAY`@s"G!AR1ʢqr*sg^z~Z_~b;z hE </A/à'yNZ^P!@0'xypRy,& @-\RL Pȓ'th#*,+(@Bj%dd~b@(DG1|Pi⩉C.9}9%werB'* h$-Z7[=yA/_jE]emq_aNt8iq k#>J4:{#:Ck s"k{kVer~aPEskc8p#^ O\czn.R{ۙ-:LqE͇t] _8M c[ =0S7'H1D^ǠJ)׾(1Λ yP0H#a 7aŦ]fs #Hrtm JAb^_LKMAšQrdϐɄ. Ƶ^[+9@5d)vq>ha&#- K.%tln;䌯g9N!>l389Kcc_ o? P?X77a@4"ks 7N1s)ljkS] àq/"QC$rN*O9J38I!5-tW3d4촻\n^0)(0||pM22w B^MT :k'JC""btFcLglȚLOQ ;pV@hܝU&4'!Uqc((1hp-B)Ddϐ2!aPPPc[*ÑrJPr<elCAK6%9x]%iT i7J :t8$pB&Fƌ))haVsa.Ů^^^·q`ZJ',Ld,!BHO2mYnX,A\)UC^c*I$>6R @|bAH #Xfӈ|k)s !H`U~x-u\J#"h4v303"q0]%G ~FyBFbH| g(%Jwbxw9DMd (}9û!jW΁ޑ0p3q&wH!g! ?ޚÏv! w  78?. 7LJ& z81tU?bPC|cǍJ3_V4ѝҗ`d&Cp(p!г^bE=e1yy ??U0Z zHLf@f!ϓ+ctǘ$/O0g bristol-0.60.11/bitmaps/images/mini.xpm.gz0000755000175000017500000000373011233572001015263 00000000000000eHmini.xpmXˎ4]_qӱsGgӊeDBFHb@B;UTN{NwSv 4<=>=..O_;}ǟ~c9ju9^jurVOoxՠr7Z9iurz}#:r\ku ~g7rI@۳Vz-+Z}J`oxeҮmm?EZ[QcHm|so}aTaq5W}u4 Cם,] ô84]IjcǨ6M8[6-0UR 4ݏJ͟a_5SZbb) :q ARX?R_`:vy: Fuߘ+]CQK+NM#'iQz^o[]5Y UyaKul:KݡH3vsp 2C׵hjqkk#or,$yb֣)C$!rp7T`Wp-`dT@Y&%m( ]9!Ш& 0d5gzkŠ!9(3eatd:RT=jSÅb|GMc2J[a*%1pF8c94&F&F"*OAYtT9ބ[BU ddxW},+q/|t6 }w!kə]LYyx08;Sz뀩s\w@ )j5q\ܸݨHp6b`iةuU:\2o2gG&9Y Cy.ȦX!; >pS[rSB[u#]+ zzMkkd`YF$ [cÙp͜ݹ73Pf@ьih=K'3#2>_U0LRE 5Ѣ 6̦)+}mFx"ȝfغ:6WvlSBݒmPoTr[!aQ3B',1JVG`o|mi.bO!J?kߪOZ5>.WYڻcKc7Y}_@xoWK3E}`ןsPJQ且SES߇RjʥǙWR)JF_m;:FEv~=J| | ;.V6?lfbKy͇٬7kV vq~χV{lq~ O;&[ ۞cWk>1F,Nj־"V.#="=/qC#w~َk?:^Z{>4b%n-W-Tl킎?Aſu\X󅆵`/}(ǿR\)C:+?2:~_h4ƿu\k4>6ԟc:njޤݟE8!_ɉ^Fu?zv~4c mX)ZR-"}duWkUg|#[?Um(_sFNSNo&+v\Ⱦ~U;n v~-${Ox!O{?߷j zl?#{jm?Nڟ= qWl=+-QיgcU=;jƿ}]FVye%~_~]q7^Evd~%)Ծ{;}`CuG42]a7QxoSlT_yk ՚ɣlj/J'Wx-xJ=0_ux}tﻵo&Kv}M]?+ =VH5{J-gpݎ!l~o[ŏ6?WsX:x:.Ζ R5g*Q/ KQ_}#`7z-Tr+fMqq~5u\ T`xMڟ5)}՞w#~_hqEw?hJNEoP/8mm uF;7&]n KW6ܦrn5 gsy|> J* n\[pvv]h5^aua{ƕ+qw ?oNpqw{G[2j/,-;ǽ38jmJ.4 }mܷ?6~7.+~:7Wƾڏ[gUЋAݡ=>_$ )^zfxWԻ"ZT]8~zԽ6qn}tFPݼ徸Wb}= Oxl~`,lw {)};<-"5-:n#61wԅ1F~YE+S=gP+>6 "GHh T1Z B#}EjVˠu}W-,>὚V]lw@࿅7pEL5Õ^=Z77tw <']< ?J!<wt:~yɯN0U^܄ׯqyI =;.ca,誩4 a3?,:ã8?wV0x=Iiʵ="(rnx@N{5Z>5>CVekGbt2+s~sӷ<Ҏ]}щ{ h7f gpP)ƁKFE'J_{{uʋs+Y8ݧYx1>GoPGʞ  5o 5 I8a;4%N%]t7_p;zy):te4f(zWjy5 GHWUzgwAJS hRt2; a֏٦'A?3;aCJçc4{7(O!~t2KdQJ]VFOrڑ*~7 a$O U\yD@X kutks{-؞F/M+;( *^gde@v6JJE($WQlH8Cx裐xJ_F?g® 3Cҥ0^ TD2Un |km٪J"N A }]ۂ]c> _2Ь> $]C$ܜ(Թb9~y{:!_1Kyּσւ?$CO}?wM n JYGI<6SoJ[ī_vtp&JiwK48 ݋kV$>Tb\$.¯CNG-=?~α9'O+ S\N#p\ ,4|( y5$''m73_1ߤ$L:z\=}'Y-h@U/>8įn521hޯ$iY<NrRsZrwtrKhz]2}zA«R 㼃\Ⱦv pJr(-jb8zK'בN&!$?Iw }0"O':ij42%ƭ:NwAMjnX'i=clc(KОo16霽ԹxOm>Y>'qJۆ<%h+w(wӠpM79 Ӑ,| 7Q )d&8J?|w'u8ZsBIݰlq? #~=lb`Ƙol'sϣK's)rqԊ'6(w RýO,ETߝxCI+Мyؾ-zÄàSꙏdckۤT$csc)Aw$\Rzloylo۱+nk'5W, .(s e G f!)KOM%vrE4N٢5@GUI[\ 2~:<9\rf֌[[ 6 - zhlOڒ}DM0W)LZȭAVet-ޱmɿQ&CS|Oa_mb.Ks9ޛ 7OI-uyu.~rY6XG> .ʙRغrZ7etRmq2#4K? :8vjB c?' p%EY;𤴄-S]ǜ?-S?#]z|htHPrO0 %w\SVS'ylnAMZ6**?DJsw'AZ޵ (gZҔ>we^N--=c!>3]?Z~QRWƙs_ᵀo@}.l_ !d7ξ,|48_?I߯zUάY~$ yیNv*{5ּkAw╫/eTЏ0t)a2!2Z'(b{s\Ӧ^aχGͣjHG7V}şRY+ci:%8zK!q3fħlJ8RSZѷ>F„F :F*qB?S,_lU|#>><~.~>^X8;;zr#:ty*-$ϙtiTUq%]oY14ij(8*x-FF izr {psi/nT nbd%cvh~2渾R C53-Q|Rcv&//Ƃm7]]J2Qjڒֽ %~M{ 6h~ AJtv%8q5h0zh]w~9ŕƯ JGr{4f̒|*\u2DMy~NYhыDl2d4wp1?E/ \]3^֔ps8|:'qnJ K̇9Q` SۂN?̚"?3hEw?UkYJtwZCZ=Kם;Sw+=οn\ 6ZSZoq \P:˭<\5Zb\I+My0Z_ m۰]CZͭ|RdhisgJgɤ3|GJApv3rU2:FB٪ EV'"?9ZS7pci|ʂ8)̠A\MN[>=ص'E)%}KfN;:*#p= .Rm 8"\IZ#{:y:3kD)5| ZUKe9pDNSiELW\1ŕ@Q)YF㢔FƁ-GG·S1DA. ȃ>2=z>A]i\9Fw;.bI&Õ0 2Nq'ZoS6AJ+Gq[DsS nYx|\c=UYu%oД9m:H|OZ%ԠQJQT~bl'޸ M$m/Hy؈d?}&;?nb,gƟD iS LKh8Zyyzm}QIt5?k~gs B{ ;: W!U$(6[S}u>ms9u-lxrg5J[ϸdE5p'IVy&g{r%<iJ4EaZ;2h7;xGj[:<)7ɉޓ ܫM%C)4v4JDn." ue:΅D5ژ|)w4m;=W{">;kaZ^l4Fwȑ?%nN1j]11w4i푂BY;|O ^+-h+ĕFvTr5~Ģ>;t\)%Amq %y8XAq#>/aBGBvY 1 4T}:zqHI_҈9`hQf&#QkVZ$5n ڪEQ0(Kl󸽗n#ߐ_Q?z;в ݐr},CJ.AWXdHfU7-g,{߿BA=YHzГfԧO;Z3]s*:O)trV:yd¹~uJGe;th bN[rrʉA}~DgD$tumDu0718VaIRdt-eDoGSCQ\[LkvH\''g?9ɟV`ɑ1kFEs!~b1WQm' f%uc1fL\XkSQuް,=Y;vIy9u*:'ߠ';'e#ځ|sKaO1-~Œ1%:)d+eu!{4Ջ DL]+u%Ep=v˦>@+j,jhQcFs並ѵ+ԋO93>/-yϛUE]EN~m  4Ѯ,EzZDMvjʋL 5KfJSD6H"3 ل&؇)>tԓBOVӓZpԧ:,Ɋ<-\z>>ϓKUO*ZrUa9yjDG[E=ZGqeo{KOз[!`:!@»[WH1h3 ->Ovp?vc-EgyƵRliZqmh})/I+-KߐV6.daA԰ѪpeA!#21;~QBM|>тfg|ے=%"66t%Ƶ)7q=eUt̻.?!*sT<1{$OB1֍!$~PƝ;fΝui\lD>Od%zjBpOV*GvE([iDe_-u9C_HmSߝFkE.0ޟZ.k8%Cks;k`7ca{OzԟH ~O:z'>vH~DkkЯ? m ׸=S띢;h>kc?=,zx¯c@qvf3} aTpMա<зyI5ӪfLJҽ0n UUVX,sg}@L59e\ ku^0 }pE_=I^a<}5fœQos-rJ$!dë(m\^}bpP FD_W$gmdj79}-P1gs1*i^>Dz'^|C[C9og~{_kN_| ;1pAt޺J쩳[qD."VԆlKI؎<++tbܮ1(Ôj9[CnKl:RDF3bZmWXڜ77-6lme4c>btCU$$0z!p^W>0(Mǜ+9״$Az[Š%%0|\*#vѺRC$*)v仟zH.=uz@Ϻ>\ gZ?m{)|mJfbA.c磾a/5H'nAVÙ#(&ٟ)|P+0G+;^Lk1Zθupuviqnwee;t bfN(#K!=NH7$Dr %'hZ{R1ҷ t^Q1jU,` Te)CeLYU 7Ex@ey~rs%\ү$Zr6xgES'tiEV d5]P€󊒣UqlIN+Qˢb%6 qLNheɒ| ̉s"yT )cn{pݘZs2LV%9WtEd/oQE\w$5m}ɛNfX}%1*iy:?] >a3էtELo9hDqVKUTӡͿKE33K Ɯ!|g*qx] C'[tF'sz~ak,W9 Nh= $fv1 UٴĭF:yvED\%ƚzzN=`AgNTݰ,=M.8Uȱ;wߥ_DƼ!#7HL/+,щ;9%uB/..cn,ajV^^w =fȮ')TQt(sLvhKwƺHpE'=( M(qJ $Kmj,~?xi(V~꼬ja{D~`!~ZwfGc8؟z9RX:?IQTy?  az8#x0hDzX!4f퓲rHtDù2HKEu\^A{Ɖi _z5x{[ZU~(Qq }o l?ACb+}}R21jI쬴Z$b*Kl[KG8sO4,[1H'Ǣ iui ZYwuR'of~%H́vBӧBxȒ)eY@[ @|wfSvL$K";s;4qpbloݧ)/O@')kȂ|\V<ə2YfkD!rɆ|>Q=D͞lSbCBw<  ' >{:yDAK\?tg[A;R}qB忭f fw<2x#$ɔIY,נb%SRxIe0b/Q7(^!|r˒&ҹKlZHZ1 I9(Uq Lð|mZ#7bգx}K*AU@/PgdsÑWs8w])rW4>m97 E?a3GE''mz2fu]9W;0.2Os33ʠ2$lB,VAE``Nc0ˌbhq# V1ʔGD^)Q+¹wR GlYt0rʼvO/ cOR<7N.ioيVByEu>}R<-5\^wa \eRdRvap_ݜu^_5čIYb/=3*dJs0?|Rט&9NkE_[4Fgђ`~BOˢx,OA;3/-i|*b閄\fߋg?æ`#_ҞYOW9q5TL(zO2Yd'zδˌ h#w,.V:(#c :pCUOz? AU/\u<2x(s+V|盢y+5)c&ǔD\iƞq٧ KQoH ޻1\Wf,bgqG4ϞFi~F*-r ?,%z z?iJ1[M0հfaW&\exLAVq"-%z$׆]PV$yQJ CGRְ>8. wb! z-gt$#c8#`/oT1fs4 d|䚗ǚ/7+Vq(u?C)眖jW*bf^1"I'ZuȝЀFkE]*EO?9zw{K8oMPB(1A ib:RV+#u09jn$跧<:ϣEC!/ͶkBɓEXb(zXٖhvvSƿZzPfbebD]Qdp{O>)2N5}T[n?al*T.4GS'6ey܀1Zk!^zGg&>DQf1vȢܿC7 f1HbF" (uf:3۸j$]u}rzW-t=DA'AЋAm96eLI?i}ErtMGDdw#=k8P'+#7g}B'7[~({tC 3782{<;NZwfjF{ת*O˽>T%x{<^ViYh=(jxOz}]!]`3Ɂ緄@$(2Yx+"A_DD$iܿ(blNkD1!/e# e29U GwZtB*;pd+lWxLR7  訳Y툞b mE:ȓ+j |sB x?W<Ō`X[74q,>\?3:YuI>̻S4b΃xK{ޮ\~?>+!_G<"=삖wò<ĠqU#5ǟB$-Q @L2;ۚ.ڼوhwg2>,s$^{ɥ;Mݝ"w^YQnZT,` !TRZVIj+qBiB?蹲gQ3)NF'7 WX̖i(@0/en. ʁ-<'ʧ?R <9~(I?iMztqz[L8Bb;ϓgf'ʈ>Gltlhw-_wS0ʪpJXXʳB؍(C?{%J#ye x`< OC u|VD p۾_v9(1C͌NNnyWe÷05+"ȧ\Ab wSyېqB9TazNHVA5DςO8 G*kzjݐL_A' aTѝQ Q~Bz~ k~-X  ?lC؍ <\2?%f_7/рr"Y- j9m}B9or}/sm-+")sdr}#刉 1kGI;Zpې~r˵i6gt?I$;O `Tiґ "M-{<(kXdoC(f 8KX^;̓c.aEEfRMj䅌g^dGtµZK''Ѷ:H*l5so)G7 5sԪ'~ QCrPf#]SnjY7<_w>WQei=B~f;󶷈ِ?uJ+o[Z9-/Fp*281N(bMG9Wh+bgλ s^d7O'SUŃ)x)SVE[$NVqh|h &:V]Z+Ħgos$:a>޽1ҎsщeE#N7? ky淟8U-WiMeۖ*--iux-aFCEޠM쎟SG-*Ytu兝:U, m<_A̙| -/պrVoO qsʧYYllgZoy2O=hBUZg6u>u*s2ڵ㵷h2lgNyOV-ً7elsgxOYO+5LrQRGGv0A%\?R%_mZ;P } u*OvOMe(nE6؞0Z:F[  M i',MSIVO07=:9.#.õWU{'=o2X%([.ZQf#6m*m^:ߟѵ&ۓ_`lAk&w9qWu+{K:ޝD:jQs3yT?9b̹.:~%(Cyݎb7_eHꈧ4E'}0Bn*Cƚ_b> ճz, \3alw/BHdd!Lyg'TyeO՛ )x3ׂ׵J#;1G^[FhM /F4v6'q;bd'mAw=-/./nbV+sQr[ىW'I˰||tܟy7Ȏ/W拷-h&&vљٱU=ih`"_*1ʰ,bȉ;d_r(b-jb/)zʿ)UJ0WڐFD`B]B 8>sR5=+,?#E{⣣Uwe۲ĵӁd=źlkŌ2(\_Uu_ؓeV~̷F'C]ab1F1f԰:9JKq dPI]CVRo1;QP-3`QkaݍaQ61\Y{x ;1B< Ti1/iSC7cӑƍ8pue>PӭiW\$wq#6L8yՀrT$e:,Qu5Ԅq3i藯`zI#)z^?rO,߸ZRtfl~su^n^RI[t(9h;(}v>N&|ʌgʁ'b1H'D5wCFfV<%NȳC>~d H,ةpYaNJhJ-1bV "~`ȧw-m`<>Ǽ a2 $)22ó(VH'͛ L+rvɃ)`Vj57jZhEOu =_װh_O=HfHǨMe)C'|юD*&cQpXqA9B* ./9̱H5VrŒ{<)_4`-ZPyV.c@d f!"yCҒq`G%kZ/HZ_a\WiIҶ9Sn@ysЊyK=G.gH^'FZQ}s+)/~<"v. X-UӐVfqXk*եc~ r\MdN#_֐'nF뭐#3¨ߨ#vԫ(+"R(w޹.|Ļ1[z'9us <)B/j= -b G=/ ue"ܹ.$_K^ȸkZ3= zjM!^?9l+#EN2VQ@mD/OjiyA 5t_ubMyJ>ߔ6;(%Vp!Gd7#UsaBZRU6s Hp}D߅fyo3t L=wyG=Un/@/nc 4$̀v$:Y #N]:)juDe?q;~[?l 7;yejɣ7/U9[(8uɆjģk+UgshN70\uџcF?ծj꿧yzENiU],[\^~UO-R+.~7HYIɋpVԪs3Y=rbk4ES\ 侄3詈1 tD ;t\vWɷ*0K\\ȾR Jm/Lu+LG ?WjDfV)@?p}/򳕥u9ODtc1rh)j렂̚C2Ss~^: Wք\vCF)yshO>j~eWwUA/csEYDI%w$Xuiu-ι ]~rmcß:tzl)ci5%LAfCZXn{"ҫd_@EhE1#q%%v1I'zl5|u܈}F/tgIMłpѯnZ&/HȧqΕѳQvg3cLeIلNL3c҆щ+)e{y|{?*F-Y]Z`<}σ?섟XEщ} $3"qnff*V]e\7K^kʁj^ʁ,p+ox|L>a$,MfdM?)`6vyfxV1f"o?BpԬC}-ѺbF=ƉzԞry\T?I$;U*ҍeTp֖xy?죓V`7&-;á7enexK',i?C>xP?̌(ʕ<$AWH":t-F:G[bOPA le|/U:1yʮ/qUpB: 9 q}y]^UD Δ+ЊQ)*^Up.==ae `{Bzq@V. d+D'khՑ(DZӰ9f4]sX?.e4"$fJ-COr ]4GE(Wi(۬Gmҁ.~(̫h#> 7qzAohv7z+G>=1FZ0b({=KZg ~TNbqX=Ȉb[6y\1mU+5O5r599F׎UU?+iBD7yf%i'=D&uE*Sj)왭$%zb<+C >&RlɔO22 ӟ<#33O:>WQ3$lSN]e@XGQ.:y!Z%kFD܄քZƽUVW5{FEVq)~<bCWMCLKLW>hΆ`zg/8kYIU/ht2.dy[qԬ|,ı7U6Rܡiڒz,uǁVYSF-lhQRs5dK*&tGAsE!g |\ ;[73̩ (r7z!ܟmh=!Zꪗ^>(ef |}{Jztb=vLuQ7Ts&^mUyR%ݛ W~mY,=} (NcMք=XR|`V=ejz~W=y(L+ihMyŹj'M sdJy3)l$ʵVS]vE-9E.j1֋1EgN1yQF5וw*iPS;,b>U&vgn`߄C$q?z-]̷_ C~ȨB sV@wzrp)e^+5=f)fW}Vsxn6A(8&eWЎgY\ePYR}-ĖP0MIWwq7dqS¡K`ݫa!ɶ,-h=mueX31ۊicPsD'm+vH[F( j9JшL;κ. QA#&TV\Wzd%td?E鷋tBsXME ޹_*0Bc 5qy3BR/v˦QB؈МkҋM/g[}6 uN-E?S f*=v=Q/OE+m⧹gG[!9Ďx${9mt9lFώuBUrn [RV֥;Y|@ ))A2NydAܖxCA"n1nY!UYXZƀ֋tDWnJ/ пtR> b|82O*ሬ|r>SщS&慠w4#8bE$NJWpccNG{ٶ~HLU旈霏g9aY]2_";uB{~ǤSsJk> /|޿ʦݡ2^GtnB p=S3kcK̗irkpVa&.Ԟ ?ݖár4a׬sONlm@'Z\4I 6ذ;!NX4YM:dщHz4Lj2 mC=&HM 9&1Rt@<,-#^g|fOK7^EZ_'Jx"a_F5/I+"'f5\ c7*( s4;4ɵfa2#eVǧ:{u&d# b;Y"H]Lڤ.AP͢r҇s~(*V]IEfPq wGۮ3[ebA$xfIh/""?ąJ1U,5{β3mV{e g~ײUY?e.e*,빛mK#&#e~K+jtYZhrƞmMkCbE^VA<5ZaYy#YcqudF0BB&N)+f]HЇ@KWӣ 喼l@1-}E7Նp">C &V1:4i4((iGO!|?FY%&m-&ɲ6T-ijbl<$YP~;zV@?Dx>Ƅ,o6;# =343 ZA]UfXZ/ɂ,ڝ'LŪl~2HM&<^vS^j*_=jM̑;b-Oj(p*f4xK%kRPɱ2eVrHf֡ 0dFt\*I$N?*֒WBxI/CU//C!꺢-beɝs8UŎr=Tv\CؖkUUU%lı%YIyLTD *\-+#753&Hz_FuSilV4]oݪB3olyOݵj#/|կ]`% yri!-@<} KllZ#z5\OhKGRfA?Yl7Ւ9r~_#Rʞ5;]1yjh4Q4׭QkxgsJ C:rލ)'~mRi9=8r3|7>/ cA!1NzHp0`> f5,~#C(*"W)7j}[V$ߟDUU?{j}Aܫ* ?ըՊƍ(";)r^qZ:T&qOpiF3VT7!Bc|f铊gaPL=~=MXj<p.-́a-w.@+xvU؎"Za@YڷUbAyFx̥sV?>Ä(e_޴Sej4%JgmJ yZZiyJG{J˻X}qeZl CSK!C&J' $&ڿ5;OH%&^L}'G?cBWd i]0NTF@!9>];& +ܮ¾B&^MXC pk^?a΍-PÁ?%3xBUwݎg0MMUHJaNcY˕|NP^JיY~I=BQ9p"bP5kJWVHUFjYCoh|Z8_JrD>GŌƲ֥ I8LBk./gNj(ĭgB!ٿh SQx\`Y5[҉ᨙݑۧ|t/07k/au5oWm[¹2ϫRk ,Z *ɚ?Mf1f) 9;rAoW].!SI\zf tye"Y)b9%+?Yij_G0–F3Dc^YPhIyIN~8S.X0ou7Z?]{NW0ʨ4<*+:g4puU<#ZCK3ϙ~N ^򻠏Qߗ/bR~YV?=eAO li_G_`,JX TʚnKh3hǘ)SL\鍞w^ x4M&wY>ӌpЬNDBNq:Zt[a#?|w7tBg>ҧjG B:$4s $v:/>ץ஡}-?i>!F0&*p+(F>q&#^c |eC#jx>jښg:~A},⧙tbxz!W^@/xx+sYfyF-p| =C2 ݽӗ]*`UjwJ2UӫTwi@8ȘQƙ<1V0:9>+~~b)WTzi:$nCa,$Z?ɯt2:vP/AmRkoy-iE>T`(#/d>~L~fۤ+Qُ@F}5bvsJZ~/u&sN ?ٖ=<ߔu $kd;豻h;pVn %|Qӈf?3-*gDžBZ^#R_Z=wI԰q^ gՀ xJʂB ψ~:IVx$OslWct2*!'O5%ǡQWaOw9gCtRgD>) uFJU;+0!:r){ԍοpP!l oYeɕ Ɵ!$KE(]b匫-'_U#$ԟC=>_6FXPwJ{.5ܔF'I79( CWћw=R_#(i+aK'm 'C?/ܠ5o4ߟO=ֵO+A z9sIŧ|3co=JQa͸Itcw1&W TYSÀhoQVc-$-IyԍN0JD2C+[>z8j`Sq~4R޿,=~Эww$ƛ:,f$:aHɊo^9rQR܆FpQZ"zAB/"#mMN,EW:5rب7zn`NTcmXϋ6 ooH,_9)HQf J~1jt^qmec9yF2hYxMy)`ct<#&uefT3 cW!*s1BbE=l8 m0Ci/.#^Nqɡ6U/(s8)PrUuaC'!`NS9u9 g<&tRU&T^Zɣ"YwrWѭqX]!ֹ^wA:yqiCZ~bR'h쿵wt {E[o2>!pUY4bw Ul;PFϡ./5=+0 ZSNJizB/ _ ]Պ>bNQGU*{G4{ڔ'Uk7k/[|Dv93*e@<)nH<2ѱDGqJ޻ay.ߥ ?>;k(F>D6v!0_ɰ '(B (zU9wJca7)FFf=RUkB_]RfժCXaqv'$hgC1YGBӮꆰuQGϾ{i:SVU!ʲ3Dj-ϨĵĮɫy7){* NQ;ʉD'Y衶2_p%;efQLf(%Mqӡ/zL +6%fg߂sDW wklYq06 ~«QوzC;2ug1fC-t%Ŝj.$({Uuf*f{VLO.zlF4<d0 &&ɪ=I'aAc+M公 o YNf֙걩nΘ'Numj yѷ#r W jӒŧ$JgӜgު$1N̷R?ŪK+ˊWR2#F.hU\,!sטu4l*V*[-JH@|(ׄq.^NB']?8E;=ƺ;x NU_b Ϯx󣸟F@rHl;zފ^=c>qW_`CLN@<3?bjw[ZIb ,:ej gMogN(B&u _"E=+[1϶pn|VM{O^u(X3Iy9:w7eybQRK0]$ wa\Z|uq$ZzSU Aknۡ8}c#qȐ8q| 7 _Q%yӒV?Ԋ|DI2C\}HޘCYۀ%@97a6-Y!u\z%Ͱi*[.hN/u9ѻ̱6hrC]У ΙzHM.?ypST>VHs8Xi!L8IwfPɓ(O1 ]M;UBaE],䌙mFd }bL7IM^6r8PVIGHzJϒbfN[mP@[?R] gTiM'у~N`x^-6_e&9*p3@ytLeS|qe-Jnm'w[M:טO$g[{4ӭ 0Z>3kB]i) 3LzGlUBwVkj:r;pug>%,Fۖ||Egi NI W ]U/_g@g}F}(%X=*m~?kwդ09F^w5owBMb V({L'-Qg"q (dZxօ[(;Yk }rm=׋\'*QI=+W#S#ܴSV'X"~~\R4 LIo] U>XӍxjeuF_iǵ|k'yvuVDVyLؖ2.ޞUchK No2*+xQohdqMY9m@697VCF5fYUR]Fq5<>;WӇo2H~JI:1c9vEU6ƶYd5$)qayuu/~n&㽆>YwvKNC;:otwҊ9JzIm[>OK1+޲k| hkD:1<[g{5|tiHHHت)0%Sǵ|[y?#hW{zww @$e\}Z!N) [Wǯ4b 2@Brâv0Զ)AYRk8Wgz3fOpc&* 5^nu% n&o }Og.2Nq1kIp4>7zJIsz> {ǵAŊ#/M ejOڠ)!Vd>m~t[~I{#5=nyʼnwoГ?,OxM2Q] ΆHiuQCY4T+qe'Zuj]KU:dQ,Z5뉾t2ӍưY䅛*-qhG;7, 8ɆDtaV2= vbB g͂IqRgwƣ#} u㇨K'Eh/|cnK?9RDP5Q˓;QVl٥$篹ʍy jqVrm#ĘD[]cp`Ppʱr(!#.rT/X-ec 3ꧠyouHM_9̅WhC v:'ɱΨ.Ŭ*W$2ʤ8ٷ1"yKMY Kec2QSC|cQk/>_>~0=7m_¿q ? r0?zB%nyeɖrN#G[jmgs:O6F#;wʜu5e§W3*e#Zz8UUG17菃U~rWo8X[g2b MeJ)E UU&5cG$)tCZqӆ2Ư@;9J;uTa`XuZ\=V˸~UV77fIU'cvI/8vT ^ snQ\`(9p\Uw9k/kbDzO#/z=4kؓzȫsD=l5I]Hͽj^=:1Zf0?Q5WT2u6壾TΜS^g<0+68ʵ",EI'Q֛kr*HI➈WzUK& {\xc[kpU '' ~#d&<}UОQOnRZK_%$a(J>mt%ӓ nrIsYNx8t"3m\R#4ѫ;2>}~'/g\.'3 ׂݪGv=#/&>9G,jE飢;/qMYߍGs]OlgŊw.pI&l̮jKÇEձ"6S{jNXyp[ft\$PDUњ H2o3  ;Yo*5Y6nKZVޓWWfctQ|uJ"<)/nC 4L{U*IDyLrw+%lMK)ZXyT\pK)3hu݀L4 Sw>N.3jm= kf蟔mmLUݤe4ЫEY4ERrߗ%[r#Z6\m3s&9H'7+aCk\ QiѰْpmYIJ1cr.:=+CƫX=ee D 6$owG1~G9MT *ہVK4cYnW]M$dKx[a ||i(rQU!B:ApV i͕<'kr Ǻ'f^iEm1TҖY rs(% u։$’PR=*"sDI59#qۇFuMeb67(#ʰ2: A'NyYV})xz|}yL(FNN^r՗o}7ҩi6\qYlJc̦t\n~GﷴwKvsS2$#y;jY^tAzj{zѐnf&oO@~tͅzhYT,u[]x:4`b &y ¾Z;YA~d+l/Xqb@yGJrA+ʩ;@On'%B4}[aѦV.*>g25TΈY)Z9K {BײO= ŐPexA11oi&v\{g]Yk)d)l`_ik}`WoS`gj2_@iWbristol-0.60.11/bitmaps/images/cablered.xpm.gz0000755000175000017500000000140111233572001016061 00000000000000eHcablered.xpmUMo@=_a ^Epkc%˶R4JΌ1"4! ;3"73V֟nGY|r{wk^(Seӻ,RS+wZ+og5XH9[qtFT[ ՐFc.yTG:%^i̅tjeb.:TN<# ^"Hj> EƂǜzt#MW\%RB"[aFH7dIPq DZRo(-"0Ҋx$F;ˀ g-6Ţ=m4SNcX]<;] (H2I%n@B)zݾ뺳Af ixCHu$ *p֣j>k| is7I5O۽kc<--NgÊ<4LOKu%j-SQ ̓ץ)<֡8x9_5I7Q bristol-0.60.11/bitmaps/images/alphadisplay.xpm.gz0000755000175000017500000000035711233572001017004 00000000000000eHalphadisplay.xpm1@k+lvM0" T,95 N;ne5`2W at뱦ɟ/5ߛOrtRa))QL?=A;m )tVh%jTA'@@5t<P#:PuUZ$#(nuU p@I (N'h=#-etuFbtbristol-0.60.11/bitmaps/images/algo22.xpm.gz0000755000175000017500000000041511233572001015412 00000000000000eHalgo22.xpmRU*.I,LVHH,RRHI72(ȍUUR2P!C%.%dT[V677W5t20q``$Q=zF m8 AGt=d!!5Ȉ>|)ףM @׃i6zr=h!I Z! p=pgMADmL4{i@8 nGmCC@7=\ws0 bristol-0.60.11/bitmaps/images/cableVyellow.xpm.gz0000755000175000017500000000133511233572001016756 00000000000000eHcableVyellow.xpmߏ@ǟ_,C ѷ6}j!Jɵ״ j.}u~DBޏB)>m+D)ǟo_%Q 1{7ʛByu/-RV+) )cTʻK)U)ȏ#@ "CNHʑX\J"jyIHqp5rA wmq)gX<҄k{4s7mm~D:u@"*$-󒘻Q9u;ƽ?`d;* bristol-0.60.11/bitmaps/images/cable2.xpm.gz0000755000175000017500000000557111233572001015464 00000000000000eHcable2.xpmXiSlB$$}4DM  Dp}J뷻:ڻErpͧՕ|U0:d苫냖io^!: oOVV̈́x& =~ҘN I~Tb`~'%f1Ľ}ק㦟Y'0.,*4ēyP+0KKϸp7J:8}?s~koQF!;@8GiD ׼8Q^Eq}^Tƙ|}>E(qkQHqq>O8Ua@Ұi#{IP=6y?q[R!Jbnk=04]9= ԯ=d~9k.0qLj}N= _~|/3CJ#"qoq#&_t_W7_VJXw״Gq8sRoojboW0)iwJh{ZY?i~ ?|So_t~j~"㦋N|ϸ!Dx$K(<aR$t~Y+ q#qğq )Eo ̯E6tOћ^l=`I1#O2. =O6̸Ɓ{SIz҅/b$u/n~Xp㩸G77J?=wQ>cz8J7}]!o:A'fL 7Uih]荼O(sSCwW(z~̨>q>xg;C洞9y?ћ7:o9т+g4?ї/id^̈́}d\/3.,eyRY*d>7Կ̣o=GJ? o:o=yeT=}};ܯ# 'WAO$\zJ9R mPq.zbwWoT5h'dDO5}߭C1ݗytxA=̓S7 !{oC7YS/{EqM'~(|~3ɸ>niH=AYzNޮ#z| />ˁ֯`=:^Q=WktN}QΤzߟk]|&w˼] j<^3p|Ek[7O_wGVyֿ_r+xoCC+T/"R=jׇ;P<:ڿy?rzH^6>'{o^ o{j3;7}_y,1A~d^.}O?ds?ſp?w-1XOOl>!G~‡Wm}?d?a5{J}*I۾)a+#o>9@bkI8!3aFLL~3h̓7תY3f13nV~vxZ&0$21啘TLffÉ "n?^!$c?b>=nc8+`Ƙ`MŸ_pwppOevxxEh^Wox5̱ ,S 3gqayugi\=. ?ㆻ,t:n^!X*L0Tݯ Va q@yu1\2+[Ϊd Ɲ5yV\4"!"!*N^`۰^{pGL83P(\n=Ǭup Wpj{\rǬ8 S0fa杯..X?eGya>gpQR?˹ npWhZm.ivV8/^N/סa꺠.Oޮ5;jWf=1;nW=^Nv[ =/Κ¬ìrf<|ַ md7Ll9{w6v6R[ݴ΋<[8.?/W˶әmcwp߾;lC{d{:fߙ;{bT$?6Z6ꋿIWy%bristol-0.60.11/bitmaps/images/prophet55.xpm.gz0000755000175000017500000000147311233572001016164 00000000000000eHprophet55.xpmVKo1>_>8ͣ!,$  !TUZz7mtvc>rmûO~_l./^_ݯV_~~ͯ|hflG'Gͫ+SՌe`nf|,`z{=`Vӝ L k`A0 (K>V0=nq 0r-;'J?:RDJ)^ZվTTK&Mt*HFk$E2y "䌮2R4Jw )9 Dd@䵴#QJhczL1z {\\1҅CQj)NĿ='y$rFz'-c.tjNz>x6>VH1^'uϷ1 GIр0IiEH]qH)ew#ɬI4=ΩoC{XX3R7ESZ ғF|p 1Ľ?Jp  NU$RwpйIXIWtH80҇vI%x}JrhqOQ_/I, 9QE )zk$BjX{TuBEt`Le;~2Hmmk4CN={.BwшڨjiQ҈S )ND}8\[ 퓋pk\T`rw~㢺:hu{u?7|xw2=:>OŢZLOճKy݊k8"3QN;Q@$R| Lǯe\/DεHa[QKP03Nd- :11w 1kw 3u/zQ.Yvnݱ7G\f;-0}';u3V3T@zʓ#yM=JN(ɔ6U)?RB]R'3FKP-xKc !G= I%Xw 25.F¸Cփlbr8[/r psw;:+qt ,Q'"bL>M T7 ~VPl;xwn&R?ԢiFUMsӎ mLKZcp?bristol-0.60.11/bitmaps/images/algo16.xpm.gz0000755000175000017500000000044311233572001015416 00000000000000eHalgo16.xpmM @+9d$HoE "D(As\u]tavgٝجh3p}~`oIO|`#I+v C=%i-t"K;Ꙟ?0I3v*l \Թ,d?c 0s`|0.Pg|ھ@"!i~!S'C/̔%V_2tFJ |lr|,)nlu8; wLs̤/0 bristol-0.60.11/bitmaps/images/algo11.xpm.gz0000755000175000017500000000046611233572001015416 00000000000000eHalgo11.xpmݔM @+9a Eҡ[1/C\lYݨ/uqf׶u]6~s|X,a]-ˆFqY,G^ {yI`.u&Ȥɠ>ݾ'QuzB.·_"M0gG<%c!}6{0-J?k{,6ݾ̇HF?`x)1ٖ1.~CA&_z>e}K܂#cJEy0 bristol-0.60.11/bitmaps/images/algo4.xpm.gz0000755000175000017500000000050311233572001015330 00000000000000eHalgo4.xpm͔K @)iEIt^t "B$*EulV4(˱`<ǓwZ/XLЃa:4Ƣ>0TS\#'JW>Pw҇ X* "ƹaPe0yu|We|f 6·7և3z239(fԚ3i3hv>d3XG+~;/ bristol-0.60.11/bitmaps/images/memorymoog.xpm.gz0000755000175000017500000000724511233572001016526 00000000000000eHmemorymoog.xpmYks㸱Fe$Q$ "D%1|LUj"ˑ,[sf*9 el{+mQBs9%?<=Wϛj]=~?tMϔ9qÏg[~ h>MSY-ҋԐ`Z'UH ~΀U# zR\K;VqIT)?\*RcV i%wꥼIUVJ:d({V/ԕZP|?XUޖ"'VeJV)$~ivMHB+͌}|o%}zy~~zz|no77fcϫ?pYfg4%/ nMKW 'r$7TտS5'J׮8vO$0/~f|Їlx8?\>X7 >o~; ':XvX:ބ<:ZIZ[tR|s k黓_=iQ-v{{{w#*{ÑQ/|#@&7,'=D 1BlaoOc+ɲrJTN5t-38$$d^3x>x8a^*ɢB;z+ :oD4opمl:RY8!"|9H!/7vt}MO iײmNч'jaܢ4eOQLyΡ qW?p愼ZGupiZYǚ<$@'1' r>y ډϬ՝W8NDe̠ >XLڌj[7= d#~>JӼZEi%yUb@6K1+gzAr4>w<,Ie5> V_5(9q@00@Okn$VUqJpy>Ӛ)/Ad07|6OJ|pHgQf gF6EǑ.q'c;Gh\+e@!ŸhJ`8ƪ!Ҿy4UZg^pX: uVB`;B}I2QsJ;L*PV E!P9ޯ"ϜqAtt$ R(ňٲ' O!* C*EJ[U${>t|%xVɨM̴YVGmYfBsj>FMTgs99s?)]^ x_Xɧ4LFq\]^TQp=Y4/Yffm5Y ƣi9B/ X^=pK .p5k-p 1qi#kC`<]R :~1=oyh3d~Pmjݎr JBPxk0. (w\#Wy9<ˉsJO'\ 9Pxa8/̡e#欏=XDVdTumFFFRʪ-'z]$z# yH; nP<2Ib!Th \" ^xb"`TLH(%;f dVNy;`QHpnQ777tno(4 ifL__~Ud '*P'uJtuj`Sp֕y6ayv?Hn]7"AgCaK7,rP ;\ñneUtiEr(6ּ]%ǰyEU$UM-{&=A0ik(ȜZ훿-J/ϏxJfOCX )5n_ȁHp'|G?_#zav}-诸Rh9lx0s*'Hb Td¿ @aP4q*eY}^_ ewg?ń[WThJ$ Llݦ1#x~3{߄\D3R~@y$2G&4ySf€4ᾛ(9u ;@!2, ;ҧ}"JXAե_4QwDn1׭7~{}F\_&); _)C\sԧa_z}T7?}?B> bristol-0.60.11/bitmaps/images/prophet.xpm.gz0000755000175000017500000000145011233572001016005 00000000000000eHprophet.xpmUMO0=wEc&ee9V=V !$zhACfl'Y'z{>O*( ?7 H,?}P ][p|&om֖$IxBi,-×i+25Ag♱7JmI? eu8*HI๘FQ@DAJ7"_vufŞscB0 QN )>AX$ҵpY(00E@%*\)v d4 nA)*h$ f\EO0@ʁoÈx޺4\'5|0HFܡLz }BMJCX"fN4x9s5XE#(Lxk{^M>Ƣf8+p9Fhf]ֱٴ&JXbs-xVZ'(AS.ÿAֱۤ;5=2u(vI>Dc:,w^a~ *bristol-0.60.11/bitmaps/images/algo13.xpm.gz0000755000175000017500000000044611233572001015416 00000000000000eHalgo13.xpm= 0g+[QA8)"*vQi$ .rm{=1UL2:Gzgf2."VJ1 w9Worp~`n m 6?ge+c *3x, en\ ހܞ1>P~(,ZQ >qr:i,Q /{Fm̛ALN 6]q`ǘ>[mƸ }^:j0 bristol-0.60.11/bitmaps/images/cable.xpm.gz0000755000175000017500000000137311233572001015376 00000000000000eHcable.xpmU]P}\6}lBl&mүDwf]wK;3F~(?[~|W%/p*)TۻQ^m߾dRidgHD% 4p}:9H#.S(K@jSC>A:C:Ktt D Hu\RotEH6\>P; lTE(D!-`T\{}.E#<"|L˱H7p":1N)g&'Yvi9jO: 9V!9D^y}0LR@IӨh(@^8|]9Hxia05Rs0NS׽p;t͌an[ 5(TGC}eTf\Z+IiV8)gyNf4j<04 %` <-+ϓKAUN(4-AZSHִ-+.ߑSaA>e hυUEwz9&VGZ9KhQhG*8y>pU_uIIϠ<lW+0,6OÄ}6ӠWkAh=Ɨ@9D[#ݻэ?jR|6t5T^>< (pjxٌ]Z~)> bristol-0.60.11/bitmaps/images/op6.xpm.gz0000755000175000017500000000037311233572001015033 00000000000000eHop6.xpmRU*.I,LVHH,RR/0(ȍUUR23Q02T0V0TRRLVKle psqA\g0Ro6 "(jS0\d3PGeC2YΆ1Pt3}0kql=@ xg6azC")g6*70D*Є%,֚ -^bristol-0.60.11/bitmaps/images/alphadisplay4.xpm.gz0000755000175000017500000000020311233572001017056 00000000000000eHalphadisplay4.xpmRU*.I,LVHH,RRH)HL,.I4(ȍUUR25P0"C%.%dT[Vv2A0d0kTר֚ ľLbristol-0.60.11/bitmaps/bicon.dia0000755000175000017500000000446411233572001013473 00000000000000][o~_ax_ z}6Xq*!+MϐR6MYE^@v }3Cr񧯏KRn"gI~W|};|R>q?u?\jsl(,}q t=a6{*bsWU.dǏ|.|5"+ٗ8uN;GdY&M#h}JӛoqSlS^6"-혿4R[ן?TUR~֞a[UqNC]?Y$TSD$}UW]y^uv)ʪP($kUg{gcf[Ox81qCٻ.qH򜮪@U/6]fӼGz𷟏DCZkX'|xX?d]^ߗ1mUdKR67yd>kFq9ﺡXU}Wq-#]Co467H()pD݇^Mr|%Zn5*RLqqWa~2ƺC뾹Q}]I~*>-r]OsŮOhIщ*‘vG!Zj-x>m J%g !DI|]oT_ώ˺Pף]tr50H)Ȯܝy.3O >;>C@dhH"tBU^7>`iJ㰤 )C $3N`hhN8mtˆ/H(wťby=5VE: =0fQJ۹:Ǽǯ='R'R!5Dj^lvJsuL!8uUR&N?a-Ǒۢ=R.2fko B+[<,UQp}Ot$]$I.!3g̀Xa)rsU ѿLYE8j;amdݲm0tt[(\I`zBL>cq"`v%i3:OZ;53@K񜍃8b(+L"689w٤/aGȳ$fBYA/Q-́ZpޖkH-eD8rwZRO905}yAæjYj H-X}Sv{|9e-L!ӀNwZ2Oׯtd<ȍ))#Y3,չdNo,;j i^}fv*qIVZTM3Z-v,{[g.8x̀ИM̫S &&&4sQ{&Gu!B%a5e?:%Qb)=ټS+"I+9UJהI+!!!if ORcH 29!lvsZ#,ٔ5űʕWS;gw;#?6 lbristol-0.60.11/bitmaps/buttons/0000755000175000017500000000000011477136753013511 500000000000000bristol-0.60.11/bitmaps/buttons/jbb1o.xpm.gz0000755000175000017500000000121411233572001015550 00000000000000y9Hjbb1o.xpm]OQ˯8~#bXk&&m֦ oJ#Ζ!%'EiTͧMQ}sul_n~v{܍>66&r&(Kenl>_^Wk+sXhk5gx<נ @$ùv-y564Mz: m%41a:%=:Ky=vmJ8o{^:FBsL 5)c1O)ckP1S88` @GAShDЌaP5aP%9 ̙Ébhk\0q.vx Mqc;Jq^%Rф,)#ōkԍZ+7r.(mKF7:/VY4n!4+9'F޽|i,%٣8!4rj~@|,%jd((}P:+Yi+Ɓq`UlHSR@j\*uRH8Q 5HGRc@j HkR@j+#R\ԸP 5 TxP 5R#T 5"R#VF@jXRH V `MRc=v]c5vYc*=Wcrbristol-0.60.11/bitmaps/buttons/presson.xpm.gz0000755000175000017500000000052611233572001016251 00000000000000y9Hpresson.xpmAK0١.sND)e ݾvI%Co?oomq Oj}P/fk 79̦0,<B8+qZyZ  ˉ.XoD`eXBc:j~8%LN闱. DEI͢O&IF%77ettcQ&Ҍv?A5c|nG1!_C,mތ¹NHo l,lldiKN2?/\ bristol-0.60.11/bitmaps/buttons/patchonSA4.xpm.gz0000755000175000017500000000027111233572001016521 00000000000000y9HpatchonSA4.xpmEͻ @}!mv$1U") "$h A|ww\|Ll|܃ի+WOЖNw\adA I0W;[/|yDf*1KLI̐HDЇ`FD$Gw~bristol-0.60.11/bitmaps/buttons/jellyon.xpm.gz0000755000175000017500000000413411233572001016233 00000000000000y9Hjellyon.xpm\n6}nŽ,amP`o6֢X,hnC^*9I6ep3DYW'~y?cA~ϟ~~q-99]o^tŷ?}W3-^ۗ -hqrw@v[|r~ŇZ|_o -<^B->\߰ԛ͛[Zċ{%/=o 缸ްaf./5*lԡr;ţV|$hY'>u 4GTiȁXЦ>r"ۛ>\kjK ℥(i5ft8w& Cx[}8dž)0GBٵS[hT'Rn8}g%Ds*#Ga +&³;X_ZTX1.0k{ U.r*A&x7VVIF>fAK*(|ʉ#@]繱GEx0yX nMLёx(DBv*8>պMy)5} >fyB<PF #?ZQVC>W&J#3}lJ1Үs"#ǠHek*lqU~}lBa>"~&ʲ1X?:\ y3bZ O᫒]+~&+vmQ~&(ux qϔă=i>tc:pưqaQggqxÁ>fy8<"~, >o68<],,磏h B 㑎1ȕ Y]wMR#9;&TR6v ³Փm$F_׹%%%1i<H='1;E)-"y|OZy^I Mnk 5cB!1^Q"U >:WǸ]. g2kmiƅ%CMy )RDrxL3}:&NI48=Ğe֩jj@c@l\1MWe"F=6]; xEa۬=<͠42 (}Dͼ0#Cw5ݓ6V0')|$1aR1 H88]Nk=BSԮHS'VYv%O]4f*p;"K7`Zx}ARY:- qu N[By 'DP P҈_A*H]U.z:ԖV =赀G7̱o^b ;:F*qe~l#bt#ߣ5Gۓ׫ofbristol-0.60.11/bitmaps/buttons/touchnlb.xpm.gz0000755000175000017500000000041711233572001016375 00000000000000y9Htouchnlb.xpmM @s+YhA0 J .PPi|Pםr^E\H-In{?9F0pźN<_ݡ/엉"^"/G"ty9۸AĶ 2XA> b6Mb4b22b0R7r5 3*1J6j42<iH{MC:^ I34H34{3vKQ7֤2]S4[q bristol-0.60.11/bitmaps/buttons/blue.xpm.gz0000755000175000017500000000017011233572001015502 00000000000000y9Hblue.xpmRU*.I,LVHH,RRH)M(ȍUUR25P"CC%.%de pssIFu5kTרQ]FuQAW5q bristol-0.60.11/bitmaps/buttons/pressong.xpm.gz0000755000175000017500000000044311233572001016416 00000000000000y9Hpressong.xpmO@*1+[Ax"ۡ?d zLc3C=K;/cۇ7m'?U_veo7n=N+>tݖGfϼxNTqgtpz׉lp2"M\P몛TU%LH5b$bBϘ-MDs*d Qpn4q% &S1kk浆* DF!l bristol-0.60.11/bitmaps/buttons/patchon.xpm.gz0000755000175000017500000000024111233572001016206 00000000000000y9Hpatchon.xpmUͻ 1|R, iB]4 upHsr_m~U%"v}HίzZth&ܻ^˚-S|u)bod<*vtXhBw cF):fq_5PT`P5 0.jb^W1bĈ2ea0ncX1bĈ[~S7nlIXؓigcpYbristol-0.60.11/bitmaps/buttons/touchogb.xpm.gz0000755000175000017500000000033711233572001016372 00000000000000y9Htouchogb.xpmֱ @+\,L#܊@"l( P]~oqsak*K/BT﷛aa "  Z iGne8lSQN)ÞM$%RҡˆcÆ 6o"47hnq 6lذA5&i]0ڤ66Xsbristol-0.60.11/bitmaps/buttons/sidb.xpm.gz0000755000175000017500000000201011233572001015467 00000000000000XCIsidb.xpmYSIE_"]. *(Ȣ#o<21ԡ9{eխ.M, iL㣍͘ˡ"Uc/FIҁO+ۛʛo뀏=o;5'm }ﺼ{wyi{wpyaW_z=}7]^|^^~mW|F>Ё߳/a~%Wxao^kfo^WoxM{x׷xY^kw嚾߳7߷w'/^^ցkkCO^ yQ OPԮ3k^ OׯӁw<~xW˫]v ?Q?{| //+O|Z?~(@> | _ eˀ6=7On_wRP~{5P~:jAn S~~Vr=ߜ]+ dS+_7[5,o4AmۮCmo]@-A@m巽 ~|fnX/q?c<&b826s|N2O__QͭjȟhD3Z75f{j'vc/L!'߇Q}-?QǗpIYgE|s:|3Σ泓)E/1xbG8b9Vēxn>m3xWЌWlXcޗc=Mw[qV)ujUcTO^hZ:n=˼cEwZzsݘM~v<)p>eR)s'mnt/ms1JңH[1r5;hy bristol-0.60.11/bitmaps/buttons/jbb2.xpm.gz0000755000175000017500000000104111233572001015370 00000000000000y9Hjbb2.xpmoA寘B PJ\4>JZb&^}0o9;j{qߙL3R_PQL|Qz{N}0Ws*3*6*Ul^~??_>גNkkxͽZxy4à^Zz=V^-zuUо湍sO5= :2<,6-p*?ў(hCԟ]ϋ-Hte(Dd^^,ԇ14 Ivy˸rmh D "0 ݁aHQQ4Iq)%CrA]C "ƠtHcСhi4fT2{%A)c:d Z2G z2ăA Q GD3hӈA9,P` E*_Rs+2|*IO6Z7^Ԉxf<5K#gAcu˺gVJ+R56hƮg`6hƱ55. hq`@k;ƣqo@k hkZc@kZ̀875F̀x05M62Z#75A hUjT1o̺'ڨ=bristol-0.60.11/bitmaps/buttons/slidergrey7_3.xpm.gz0000755000175000017500000000072611233572001017244 00000000000000y9Hslidergrey7_3.xpmnPqyn6+PY+YƲ(j#&A*w-aPUڵۀu|9cS~BM}sVwV՛v%T3tV|gk džO3anc|{_Sh~F}{ڴt2fK Jp%;p*-xDA^QЃ# <[r$RJ`b{;A(0Zpu)s+>+b9*R1)8ĊzE#$ >!;5?T:*bristol-0.60.11/bitmaps/buttons/switch1.xpm.gz0000755000175000017500000000034111233572001016135 00000000000000y9Hswitch1.xpm @u>E'3i%(Ce".!\ZXCIШ *J[_%0ф"́aRtmϖ&@P~8`\(hs(Y q@z(!L?+;\@i#Z>Zѷe=C!:| 3bristol-0.60.11/bitmaps/buttons/rockersmoothBG.xpm.gz0000755000175000017500000000072311233572001017507 00000000000000y9HrockersmoothBG.xpmMk@EWL|N4ԯ jHP,ZE!WEwa ya69fbf[z\ۻ2ǒRnv]wYl*f\id5C9mZ!hiL:PtkG@kK:PA:PڳTn@uT" 4p @F:&EjFOcRAh+>uootGRd?QY$TeE1lIQjsJ^2in 5u]ҳ%N']7]Hz?J H\%q(+"y;g$oAI OU494UUD${%G'܈lifM95|?'p7w L'/CsKJ bristol-0.60.11/bitmaps/buttons/pressoff.xpm.gz0000755000175000017500000000036211233572001016405 00000000000000y9Hpressoff.xpmA 0s"3̊ [1 Vj[!?f[\Yo}nIfYESrXagf}\c41}7-HCէ:8^WjoJ[{T O)GA*п)P|jPm cʅ?AuK̫k6h E4D4D0Ҥ0D8G%oː]X bristol-0.60.11/bitmaps/buttons/rockergrey.xpm.gz0000755000175000017500000000054111233572001016731 00000000000000y9Hrockergrey.xpmKPǟƮ^q˷ "HEPD{;g ffhB|:-Hq3%լ+|z~$ yU!#N܀ փZcc49 "FLPC}ꀜq^1)/|g Vᨲ#'9` Ep0tC/-@)X WxUu"`14h;t[4ŠZ)$v\[[uql'j~wa2wMtv&sM;]wD0)"-NηXy wbristol-0.60.11/bitmaps/buttons/rockersmoothBW.xpm.gz0000755000175000017500000000073211233572001017527 00000000000000y9HrockersmoothBW.xpmQKPWܩtjb1|+z+9D#P~{;'><{{mS<= .֓TLg0r1}}^z6x>PD\(^E.hBQ\LZ. @ l38hܽA*A qw@xD>-"l"L(_C~*8&QMD~> -إ\G+@j4 $Ubej̕咔4^}Oř+w`ge3WaH|'%(q6tۛKP~ 2n YTL2IXf+g)e`F#B𐇄uBE.U+$*P]j*'yBlD:Ԙ 3}!L[8E%yQc} OXߏ@IJ" bY,$L%F7վFʸ+aRZ@&s`L D28+P*PaX$} iؠu qV j$ɋsE B 4)|T`-EWc }ϑR(H7IWݫK;CH.qs9t"D7M`9uC5GPd<&җy0i%BMw#o͋KgJX)*vmP1+>gyQP LEc2wi8:.d&h56!Og8r7 4gwc zsʧk%\ik\YR^zkQ}:Ssxdf2[ڌVbԫgs5ΪS'߹ɦh.JRq&dڰי调/\^]p9_]뙮oۻxmm>x\,c~=Gs ݧgg=GO).rJ:g'UZ{{'I6n/:xt|}mn׍Ǻbristol-0.60.11/bitmaps/buttons/pressoffSb.xpm.gz0000755000175000017500000000026111233572001016670 00000000000000y9HpressoffSb.xpmRU*.I,LVHH,RR((J-.OK N(ȍUUR2P02T0Q0TRRLVKle0qa\ 5A0D0A)zA&zZph)z`F=13~D*^0֚ bristol-0.60.11/bitmaps/buttons/rockerred.xpm.gz0000755000175000017500000000035411470220760016544 00000000000000UM @ɒNd7_?F6y> ^Û .{eΧ'޶V}Oڼ~=/:F W*#e Ȓ0Ŋ~ X'&eÐ.6fRucJ=0LX8ߒWv% rp:-zOIK g"\ 귲#ԟ{Q(W,Za?Ԉu|M␠ْw++ ȺzB;H/VZF&UjoQj`lV2LrF 46Ұ [dۢ4͂m!yCN Q\\|Jcb_p wpPesS-XCأȖa1 d1zWa3E*0uҸ,`<X%X -sm.PDlHO+N#?! \X^,ѯI\&qcvVΕht -RxU\>u_7=ѻGjk3>ao'U(Ҏ)E)Ӹ[mܡ_7Cm6ppX㰍1=.Phs/~|N(c pxM/[|[hpX?$ef5=Or$utҨ1Bg{ F)MVӯ*Mz?J Ii e#MM8>Ms Km8[c|W佯0*5mch6XØF86^\xm=ڭG4t_Y||3o4Y#:s<hw;iz_WnZ"5ѿ?v^-ؿb#zR[ O7܃3I[7܃]}1R$^BzJ;4nZ[ԉ-Z覽!14k]Uʦ:s`a ٟהpC6DwGZ*مhM0Q< ..xḥi>;f':j>Xaf 75{lPgvol܅~Kefo!K6>o9ao!8Y6o Йͷ{k*tn{޴7]Rd7k{j|v/ϥo N(bristol-0.60.11/bitmaps/buttons/rockersmoothBGRd.xpm.gz0000755000175000017500000000116211233572001017773 00000000000000y9HrockersmoothBGRd.xpmKo@Wy{UJFMJH<~{=$`j"eV9w؃Z>\pZ~Y۫Zn>_~<}~7*8hQ(Yofk7ӸLvscR 3CeT ƉAIHjl cAٱ i4u `c`ĬEԒ *R9TnѠ$Hs[dG:RZ&e0F!LMg!|d*8א%j,1)p `-U\q sj@Ec@3-Fuιű(%n Jl1 8fcb#l6لj l;;v軝Q=бg+:j5E=Kݮꯩ Akӣ$ y c'8_1Mj]7ڻL<qϺCim3ZAVqʃy{ş㑧8KpS5 _w*7=PP;< Sp4ӷ (5;':;>dz>n~,m=쟟vcjlu Flqiu؇-@Pݑ<' #? pI(1$a80y 5BɈG:PH!Fa6bJ@5)T;k@q`>!̽P5pT&srGm Q^ ܹNPN8KȀ_KCP),BAIQME+BqOaJx"t4+Jg^^ bݞ떮k ^.q8ZvdIKlcmS6vdFmT ޅToNn;͸7f܌1Ǜ|~2xjzaTU&0ֵ֍mj6*۫~1sbV/REC̕p1Vc,=VgqkDT?ŭ&? bristol-0.60.11/bitmaps/buttons/touchnlR.xpm.gz0000755000175000017500000000162111233572001016353 00000000000000y9HtouchnlR.xpm[6;"BPruB"j*,vig ǧT%|Oio6"]Єᄂ?^_ LJGl[p`L??4f3fg05\OL1C qlʈsPCa2,Hh[6XaY0o1`^qd1lqMdxF$6|ći0L׳a"m {ہ$ۈ"ϰ;:GbHcXB]xhi6lā%X؅m9ză^6oiP Y/Q㯊} V‡/.8ۢܨT[sܮ|8}N< +&o bristol-0.60.11/bitmaps/buttons/rockersmoothBCd.xpm.gz0000755000175000017500000000120111233572001017637 00000000000000y9HrockersmoothBCd.xpm]o0ǯHۄNL "ݦ]NBUUcj{Q߾Zڑ*bz ȏ qY>ss{vea-.Ϯ-Ϻ^._\-B~_MgZuIh"܊Cvn6qqa7B(Ge"$mi :U$   h>OPpPTEԱR,I)iZ 0DC1xJQwYBB384 05b]*FD@ 3Lr lP` k`-$I1e"s dB3̊Z"e%TE2,db P g3% r#-(Er(2h0_?y)d;]o94&^>oر'{y~p{k3VYoc[ívz:1ujSo ͻ[׳1*wy6Eu'j=Q3'[4oFADU VMFmѦr)IR6dIaIa>=K?bristol-0.60.11/bitmaps/buttons/sw1.xpm.gz0000755000175000017500000000025211233572001015266 00000000000000y9Hsw1.xpmRU*.I,LVHH,RR(.7(ȍUURT04W0S0TRRLVKlec0qA\CKq@\0qA\70qU@\g0 zz`h9@2((pP8֚ gbristol-0.60.11/bitmaps/buttons/jbyo.xpm.gz0000755000175000017500000000121711233572001015521 00000000000000y9Hjbyo.xpm]o0@ǯp@vR$ۦ=NBM:m}XEoa@nEC#AI> |`ue0klZESjReo&÷5eai4sru89R/~= (sD\N 6.45gv@ sMMki̍{sz0m/2\9$M9w$p8m U8MRíӡS+-P k56p> 4Zgw*@M$Wf6`HX`*3&NP/ 憠* N2ZjT/*)g:a27"n.)m6Y?zpFo_vlV"k teYm;l4Eg&Sj!nX;Q@%-em?JJEJJBAFkg8'p:%5 !5`&qAk\' 1%5=&5. `!qCk}XcFk<֐Gk(X'5X#$5"XC>#qlƱqlN7Q+dbristol-0.60.11/bitmaps/buttons/sliderblack7.xpm.gz0000755000175000017500000000110611233572001017121 00000000000000y9Hsliderblack7.xpmKs0S8'! K %dcgCx?Lg%tiSp+㯥V~k|gMӝWl4 iP_UﵼCșy~R(z_2f=UĴ% :#!o!Z"C?snG8ab` c  '|.o FX!L$"7=3`("%|loCd5 C`9!M{sXe(0ؖ€oX*&Է 908a`AɤCU> Sܭ#0wFXrf1QzB Cj ]L4B_#}--}M٧Ya#[ٕic^QLD-0&Z;v^!ݶbdz=7VbX:tVn5?\ݜ`}mOvw| ;*UXC0VJa6ϓ hFf9hK-]M!z}@yXl~] bristol-0.60.11/bitmaps/buttons/sliderblack5.xpm.gz0000755000175000017500000000111511233572001017117 00000000000000y9Hsliderblack5.xpmn@%YE.6_DEdRI^& O>( @t%CbCq}erP%R*҂r}$ރ]m= %Q+<4>M'Mn!=h$݄j+)ihC@O>H#MQ(F"~G>1 14/gd>ۧƠDSD^Hrn4&J-m yz@k|5Yiml Uʝ݌nU[" sOh7g'jU2.OjM}xvs!D?Gsa< ϼ(,Wu=;Q>?^OXU1bristol-0.60.11/bitmaps/buttons/slidergreen7_2.xpm.gz0000755000175000017500000000067211233572001017375 00000000000000y9Hslidergreen7_2.xpmMO@*`t"MѤ A$~=@vf!*\h{3ζumr}uAl:yOn 6yxI,KNDH*RM uM$R`u4JjZHcRE5l,}{@> Pxkt"=GkLsf ;el :B@9ĻKbiLqԨ]+8*3bqOAx  fͶ &3hrTS#x_M?7êuU ^{N|nn[^yf=)-}$[;{oξuC+Mm C`@05(C=И`C`I7 Xօt{b`_\"螋bPr "w:Gp$'bTX כ]s'~R >5m\X nD᣾+ޙOgwj(sl&s:Ռ]]ULu'gfNvzvnf7nqiw͜;Wfh&(nF3KQ;( oӹ'fƣ~:M^Lg~/,~WLz]̿=s/S*bristol-0.60.11/bitmaps/buttons/patchonSA2.xpm.gz0000755000175000017500000000031211233572001016513 00000000000000y9HpatchonSA2.xpmEK @u+.qgN"+6AD"rD=8-ڢ0e5e]n lC, XKbnݮSHLȅ)2x!md*RHt}_WJv݅|ાpc!?<bristol-0.60.11/bitmaps/buttons/touchnlg.xpm.gz0000755000175000017500000000032211233572001016375 00000000000000y9Htouchnlg.xpmֽ 0\šRR))AhAw"`"Kx֫P\>E~ uuEyo&<q"`[Cb@*w55KSL'1k0NBO-3dqjm!A}?ˌ1c17oTI(Ψ3)yCKq bristol-0.60.11/bitmaps/buttons/touchnlr.xpm.gz0000755000175000017500000000032011233572001016406 00000000000000y9Htouchnlr.xpmֱ 0<őn" p8 "RBR+--}E \ۼ=*Pe:5 Bb:&F uU}e.d'%*FנK򴷎y2jݠ&ooAƒƖƚ ƞ ?xjMA#Y๕u'/ qZ8;,NLNgIq,1Y_43cYX9zg?:wP2pFR*kC(2(C (0)8)L9s1O`bristol-0.60.11/bitmaps/buttons/rockersmoothBB.xpm.gz0000755000175000017500000000073411233572001017504 00000000000000y9HrockersmoothBB.xpmOP8pPGi .k]9dllEneX^qv} w7´ oq*Rb>͖oϋj>DϣPD\(6qƥBQMey-XG~K&, ltF"@l!}Xe VC^. h-(ޛP r`U mbVKA>QDvp.ߨ&VFC@ ?,UM329rij$%Wu}ș^5t2 H/#gaH|~'%(q2LVfSLk50ڜ` Rk oDNk=}Kp_|usott7h^tXGO؟lubw㕟j*3viq{^O^:AQ/fsbS?eUrƙxjGP*8hbristol-0.60.11/bitmaps/buttons/yellowdot.xpm.gz0000755000175000017500000000025511233572001016601 00000000000000y9Hyellowdot.xpmRU*.I,LVHH,RRL/O/(ȍUUR24P0VP0TRRLVP6W5WuĵWuWUq@\5 ZeUe54Zk.pLgbristol-0.60.11/bitmaps/buttons/greendot.xpm.gz0000755000175000017500000000025411233572001016365 00000000000000y9Hgreendot.xpm]; 0CvH%}B@vh6QuA ]y v TΞùp6XxYKƱ @MkbFt% be1UU`bS-L.FD_Y/4bristol-0.60.11/bitmaps/buttons/sliderred7_3.xpm.gz0000755000175000017500000000101611233572001017041 00000000000000y9Hsliderred7_3.xpmo0+ RRq8Ƅ68 AU/*Qۗ֕˦IC>/΋s}ŪO効bZ-Q!_36dF,Vb*%]_m^G/@u7Or&~3b v08b.Qـ 9 4 QE\rIu*B8oiH˘i!618u(5Z`k̹ϱф*V(5':#f zuZe*#XKƳ4NQyJFtrJ fYjR,AThKLf^iۺm׶ -C0C58ܒ>[>݅vz%xD?ɷ_Ϸt᥍ɨl8m˯Gw(`x"K?ɟj>/[4 d1 1(dJP᥺9Tߏe\-~obristol-0.60.11/bitmaps/buttons/patchonSA5.xpm.gz0000755000175000017500000000047211233572001016525 00000000000000y9HpatchonSA5.xpm5n@@uy2b RD 6®Mn!4i]4Q|z~dΆ/0 8Z}(Pn:nO_z{Q:@ja6P'׏{i p" =-O-Lvc&&ܝSa@0cB6$h }]aBВ؀ޔ>³FNf27!&S=9 g38YR>P,,aE!qj:bsawFH&0pv/#ͳl]W+/V^K)Cy_bristol-0.60.11/bitmaps/buttons/sonicrocker1.xpm.gz0000755000175000017500000001754111233572001017167 00000000000000{-Isonicrocker1.xpmE[VȲ})Q$$%cĒL9{ۮ]e׬stWwծЭyD;cZXp|'~Oşw*_a%pW~e~-x>kaoᏎNqTq+&$?BQ~O*x|n*^ ]*jcpKza7OF_-oLI= ?;>dK_8C>ﰾ]tM NCiEyD%Ji9VS)G'1ٻ nEԯ?[ .a[{/Oޯ'$ѯ4߄8U<#w$~C?w͓|<֧}'%ZDBP$!,FF?fD@JEA IP&_&}.~p֧k #%t;ix%UL|%-G%䟀 },(^?{c'!?4NO<'? 7:MA~<37ET?oweO:1 \9 G +LuJ&G` +YGk13N} Q.oi7#6,/ė'C8jQD7c}̏2 \ {}bdϘ N:OM7G`\i|^}#㱕 θ~7H>g67w0&E6}X?_d:'&QNKyS>^H;Xk# :\{J:h*"<i'A? WA սAP eIqU=_,!jߟo@N Ey\ Q FAD"֛??uYCxy_V98_Ga cimѧ }wxw#'%+~J}߄iF%/:au`%Mbb~;X^=^~6pp(\ݧ[&szb$X? ?|ܿ!sbFD⋟?E_QOMgy[⅟+GaIяO|LKpboYI>p> ww|Y,יo go2䷹;yk:Oxm"?ԙ_O{|ӸY.+tܿuu>Ou>2gB|?#P3;zF·[~7w0*h|>ՅwExqN%~q/Aү9^X7`>q+qƱ|>3ѯ?:Oh~?<rԫcϤ?{Q@+{W'sw4~wܒ꺏=A~i= @ #*&v3?/qPqM]p_E4*܈o=:~7_f V~pC''gO7u"Q1gj=c|8RXoQߒ+iy ' 05ox{7y\/ooJeOCݏ?;Io2_3/{ \s(!|}P'> ׀[j:c~H1p%>NdA?__sGNU="|+L=_?૎?N#&7rI0,8=oY{2?}rd^/O:"~zaqgwk GH/n7o+~|鿤f|xNp&~/7p>1??}? ?lG=}e=ֻ7m%On9?w>ߋ`{q~?,O~+$o_?i` B/߂o {}}-gJAOd{Jx'g?Nx [gB _ u>^ygp~z_!6E6j_}{)^v|~oYX?>Jo"gX?x,Wu'\wgm5% -ޯ .wpoX~'6Ge<~C_~,>;1·qχ>_/''9cMDTg?x1I %a/-/)A}\J4#O`C뾿Po|?hq}xxˠϽc}})?)O}LEy[qx *z" ?>o`_'oR {##'[cI|=VH~ rYjO Η(O# !u 4T'~|_?/SiK5૾??!?n߭w2۽+l4؟OOoR"AOg}{z H_ w+ф?4ׂ?9⥍2WA\!;<) kr~L ` YOs蟈/D>z-I~1|'}~s~'܏_2|l&S-',UΓCV\!5k&ܟ1s\ޏO/>RwtФ--H]'_}\cuo_$?"wc7 GOq~u_>aQ`/|_~h:CLE6_Wp|+t{-kO'KG@>a,i R/'|p'd>Ϋ+O.ק&|>n3uP}Vyq܊}#"=|~Qwߑ?7kߏ3Vo|bZzƿ%ِ '}[~˓p#\3I·)%*g8޳ZF1|? /!^K$ `E9VEoMn/!MbK{/E Esd\nE |>uz7wI8ROs}]=yF W\`uCRoO^dOK0QW7pD߄ W?Я-ϳ{Z}0_%w+Թ_>RoDŽoNso a[_|e){Yյ mDToXi?ڞjCځ6kjjkjk5׎X;N3\.+ZnINWrڣ=k/ګkڧ}k VimRҦmymA[ԖemE[ִumCԶmmG;4tLl(7xް7SoF!ƽ]/"//%˽{Gޱwzg޹w]zW޵wzw޽=zO޳zo;}xޗ5^uIoʛfYoΛEo[VUo[6HnP9sttpLrlp\L8#Π3 8gs(Qg9pƜqgs~ ȉIɝ;Gαs:gιsArΕs8Νs<8Γ8Λ|8Η4rNtIrg֙sgYrgYsotmg9TaNYzIu4Kˢtz9Qp9P+ʽr-ʃr/w˿ ʐ2.2-2/U|~yT'iyVeyU^7myWޗcDrKZGY~el]VeGIMS嚊r-r˥r\)W˵r(7˭r)Ux[ >?GQ}H?q}W@HDOLܑ~~_~~?Mr ^}Rҧ}V}Q_җ}U_ }Sҷ;TQaaQQ7&c6ƏgƐq`T]5#4"#6#52#7joƉqjƅqi\ wƽ`<OƳboƻa|_Ʒ0Fh1&)cژ1fInΘ7EcX6VUcX76Mc6vCUU;fiae&'k s4c9dc渹kf`fdfb$Y3}<6OS<7/Kʼ6o[μ7G|6_W|'2͆4[6+cNS4͘9o.撹l$f榹en;*X5B˰L˲l\nMX#֠5l Xt^Y?ֆg[֐u`Y֮F_+B+b+R+rf,wd['֩ufmօui])4e^[7֭;z'z^7{>OJiUYkҚk֚܂h-Y֊Jrkֺa֖mXpl.m6 ô-{vavݞ)A{>gۣ}`gځڑۉڙ\#OS>/Kʾo[NݫG~_Wݴ[vۮ=iOUrsjy{^e[Qrno؛m؇ ( 0 ( H1X}(?^_CA1V_[EXDE\$EZdE^ 8*I8-Ί⢸,⦸Ux(x)^(>h\h*:d1UL3l1W̫߂-KrRkzQl[6*๎[kkq wtKs]u7t#7v7u37wk{ꞹ{^xqo;}p'}q_7p?/mM;?ι.ꮹn{.4^ݩunͺU=z}>R?~}>T??o=eCcJbristol-0.60.11/bitmaps/buttons/jbb2o.xpm.gz0000755000175000017500000000113711233572001015555 00000000000000y9Hjbb2o.xpmn@@+&!;BxzJUj+,*\Op|_HH|43h{k,Oቯoәe@#"-zVO"nCզUcjj VZZ0# FVjXJLvdhܩxn kCi${t,38j+ƒD9,Ǭ^}+ER%%kV.aI?}`\? uWy]n%ol3F%FXkR= 82OR΍}ҽ*3y#xi/KHvY 6h>?r\SM@db.nuJ#K3Jo0(vө$h2š!Cc6IU>|AQ!1ՙZrQz*y TuajUɜ{8@P 1Y)]g:ITFɲ49!W6/KҰsrsې?Y1|ϳ1$佰D@ӑ7/cKId9pTy`).nn(PGg@'vFlȹY yĺI;%bristol-0.60.11/bitmaps/buttons/klunk3.xpm.gz0000755000175000017500000000022411233572001015762 00000000000000DUHklunk3.xpmRU*.I,LVHH,RR)6(ȍUUR22R06R0Q0TRRLVKle70qA\ sq@\W+@@ m,`8!3F0 Zk.#UW-bristol-0.60.11/bitmaps/buttons/touchoy.xpm.gz0000755000175000017500000000040411233572001016245 00000000000000y9Htouchoy.xpmA 0s]YD`` PF=mBhi/۳ö )rJdBG!a_חn; XjKQ,opNǚ1U:tgmfof`~gD ܤ=L9zg<؈[*#4q"j!↔H#4H# Kp%MrOrS"fCBߢbristol-0.60.11/bitmaps/buttons/jellyoff.xpm.gz0000755000175000017500000000754011233572001016375 00000000000000y9Hjellyoff.xpm]ێ}bWٶ#d\7%c  F8q!Aϰ/TUsn Snp?~_M?Oo7??n/_{電g~ݯwG'[U?}u~{\lnyu\>Vܖ:lշlVcN[7V]oKśVq_lǭ峭b~v[V}sc谕YO |僁|(߯ldeUK JLv$W-ם&@Z.-rWSխc?)Y bc+/u~_ҽ_4x6bz@ s(P/,YJeg _QaRP8ބZ("k\Wsy/2F&n;` åeP*&;arm9ː21Tr0/|]->)g3o5m8/zMjRw&.zYFy9μz%M8R@EnmrT oEZlU2˴YSL;n8lr*uuuo)rӁ*I(L.K"g$B[RuIW @:֋ =͓s 4Mŷw`IE|KkɪnIp`KI .-w_"ВP%BZ.ǁstSwWbyF)-& ;,ͻIjpN앺 dR`2Uʊa},:ΞM[ &$ ({*(ɜ_J(^`*ÛH.89M6 `RUu΂t(g*G }Aw>o/4m(R'29BbyfPAl@;Q rX\ D-݇ gCG zL{X&qm8Mq*Kjs3(weRB`Rc-̀!|I' ZJ"t1BA+X1A8ހdiqT m4jb7@FLZ̼nDCGLA65̍ * 1 V%Wu_.-MfYIhۜ89+&! RWf(.fkqh`)OF*@&Wo`ރIcƵ5PLf]\8$aI8ω-~QD^%ܱIhv|܀P^gMnG06I>|ŧ53o}7veJ0Z q@2Ds&|2y&`st0 )fJoqُm䄒4%w_lLGz[TExӹ>92 cM"%91̳'3dۻ%*ca~o!sdcXɧ)'m3&CaZ+2D" R@p ZY0S;'i2+cD2`OEƺ4Kc"/?ŒË'F#m8JgIޠkw$[ID>СsV0EZĸQypF5?WAk$&7&_$&:X5[ɢFS!Rz(naL*|*BoѴ S0@Cr(4FO$*g)sn?0)Yۏ.Hn;销Qҙ&u:9'_Ƌdt{1I8 P0Jӽ`?|{J& V74U#28չ mp( "FL68&[\&aHcB/8s1*j.FJ*7\4v%P}OR!^97|&ȟ C cD ۹!ftbyQ7*9(c!a||@Ю6y6)7i%WbU68(8v 96i,^]*}>W#`t6I7N1i'C0/f'ʌM5lR9i`|t^;-c B+DwaءLx$gIo(HͰLY&z D7L 'NJS- bKhCXۤ?'MD =b9tqT waFuB(,ZYP aT>Ӏ Z7@TkD{]V> l2&w[ =( 'NvM:Ȇ{AQi*>v- <ύa+y!A̤Sm7 +ܼm'P,*lKM5̳RY#啋Q[3mfxҲmӽHpvԘÉUg˕IcA@ A.  r=wfA$Ilv%jN9"s,Hn#UjiY*,OJt~ qiã>-A|R`YPE0Zoz7|h`,j0(BpBq7 Jһ$B#C0cA^dH0eU>yi۽>ְcv&X)&' r ĆCG#Q5aSn@7rH) ~#B6fr' Z8 Ԅ&7i&̻fj8EQEG$}3>H6HtT%;U>E6FL]'[Y?7Qʯ$ dS~;òU*N̂z~ QY M(B9B$J*n[cAm&/,.iAgfAU~Ԛf$TȰn}Y, jܶ̿oOF KhxwI23rݥDȗj/ ggA4>I5]srd͌v Y"΂ m8'JSkΤ?? jgx2^roHɇTN[ʒJ{O΂hp` '@A*,[?=+xdZ 4Au*1q[=LFRS0Ak<$ ttqn~/hPA D(/i*l) Yu4BxblɯsTGL (eOWֳiA'@_0uӤH>zM7T&W ﰤx]e(Frqϡvxb FxDUϸOwG,y 8!1hRwI,C}[iLD5-}B70q2RPIk,|R$jde xKWOEơtY)}WA R?rt\J0$Xjݕold"J"4f1L I[ty})R#A*hYYA?)? 0>`.]8 [KP9?O8O<D)J (7 +}hVd] @R@ƴjEhtEQ {)ifbristol-0.60.11/bitmaps/buttons/touchog.xpm.gz0000755000175000017500000000037611233572001016233 00000000000000y9Htouchog.xpm1 @9?Cŋ4"pɭh "B2({> Nhw,SlٖK#Xg[` 7M0th1 |7\ݢbristol-0.60.11/bitmaps/buttons/sliderwhite7_3.xpm.gz0000755000175000017500000000074611233572001017420 00000000000000y9Hsliderwhite7_3.xpmKo@um %D̮UX 7%HD^ޏzMJ9,|`f<[F^~]W*o;ejL0q2U5P PJ%ǯǖ1B}m4B vc 6ah(lPh8p @} pQ%-#)M>$poN8p&Q c \Ca.W" /I)GVB|j \JSؕw%0oRVFXV!051Z>,PS ),܄¹0f.``?__cwufj>vi=itnLgx<8^NCkxG pIr:.ZrmBtNݡheq{EOD <,rϣ!b?Ȣm5*[1VM(ܰZH6*^Swz*d6yPr_|vhHyym9#Okt6U!p(BLâym̶bristol-0.60.11/bitmaps/buttons/touchnlw.xpm.gz0000755000175000017500000000031311233572001016415 00000000000000y9Htouchnlw.xpm1 0#R UD8) TV4 w{"4`"KX.f cv6iE~ _7a1WP 60-ݝ:YF39I4fڧ4Szm" A?%L0n#+3i;i/y -q bristol-0.60.11/bitmaps/buttons/jby.xpm.gz0000755000175000017500000000113311233572001015337 00000000000000y9Hjby.xpm[o0ǯpW`;ťT8jE&mvևM ZU;C|S/mފfvri&f'?DS|e8}1##D%T]73qx<<7C $@q JoQ#kJ=Bu6)5&֗Gn:G uqWKKmyAOP4MR@3RQu&,1gL@o@sF:S,w҃AR.PDw [PsTziF-|oPy` •fjP(scTSh'.)IA'+AQaB~TZk ~yaMh<9l8Y<t/)Z[2tCckƾ T>G 1h2}T>=Th3' qj3sTcĀj0]T3 %1d@5 P ̀j a@5BT#b@5bT#a@5,!1aSTc7FըUj<4ebristol-0.60.11/bitmaps/buttons/jbro.xpm.gz0000755000175000017500000000115111233572001015507 00000000000000y9Hjbro.xpm[O@_1eMMvM\7&ݞcbS96߼Kۏ вďj=/AXvp?}{7X'HxJzVO>Ibڠ772 :im) =ԡ}P_jPF FZ=G;5%juQo)S朡SA#%Bue@Q},Pd:%>2BdCɾ}9u rau@c|7r*Qr9Cup9{oa7l7g>7,Fm&ot)؀Sod+9SdžJȆmn{#w965Qln"s'˒Ilkc)~L6J'9 .mo1 lX FAcT̀j3MT8b@5vPTcɀjLPkTŀj2ST8c@5 Ɗxf@50.1>0!112AmoPbTQ5FHvrbristol-0.60.11/bitmaps/buttons/pressoffo.xpm.gz0000755000175000017500000000036111233572001016563 00000000000000y9Hpressoffo.xpm @s>Űޜ05" Vt "BDC)!޽6:d4^4?ev lKPR^1d@Eyqfp9˄/1腰J,4^W<}ī-y*MayY%+P 7i@ Ʃabomާ?421- V#0sߧ6R Fݦ9r bristol-0.60.11/bitmaps/buttons/rockerblue.xpm.gz0000755000175000017500000000042011470221722016712 00000000000000UM @5S9̾ϞMՂvϓRzHndxx;fKczjz SHtj3^w!'#ɴ~2T4] 㐩YaTTTzތUS=a%Je e%QxbGBS!db<&rx>SO:oSPL'``L-ծnf6턙tY4_# ob9bristol-0.60.11/bitmaps/buttons/rockerwhite.xpm.gz0000755000175000017500000000036711470221256017117 00000000000000U @=W 'J "nE BDpɽ*ò}DQ`w-:m.\=u湆POJCh,4H ePGhRE܀5c%rXߦ {RB1ӵ3Niy:=}2M'`:Zp3]#1ngپt]ƟSbristol-0.60.11/bitmaps/buttons/sw2.xpm.gz0000755000175000017500000000036611233572001015275 00000000000000y9Hsw2.xpm=OK1)͟ĤVZ!P,zS<J)eP[PyӦ2?ɈiH'_*TX眭p{WWpΙ+r1WD"YrE^N}{,bristol-0.60.11/bitmaps/buttons/patchonSA.xpm.gz0000755000175000017500000000026711233572001016442 00000000000000y9HpatchonSA.xpmEͻ @}!m2* ) "aba4 ;c.uf&MtAW[w,@Sn ,ᣢr`MUaY9&23IL'15s+1cFbZ} @ҡ0f`Ivw~p t!a^t߮&eRQT.D:ITAS6CD[ ~0938 M7D7D3Ƥ66CcȞ$V bristol-0.60.11/bitmaps/buttons/klunk.xpm.gz0000755000175000017500000000026511233572001015704 00000000000000DUHklunk.xpmRU*.I,LVHH,RR)ˎ(ȍUUR27P02S0W0TRRLVKle0qA\Sq@\G0qA\K0qU@\s0qUA\'0L@m eUU 5iԤQFM5i$TWKQŤZk.8 bristol-0.60.11/bitmaps/buttons/sidbongreen.xpm.gz0000755000175000017500000000262211233572001017056 00000000000000YSK/"Yْ }@DD@EPPA~3it |TegVV{2=?rxq);dZw֏#N4׏VdINGB Dّ16-ur h\+y'Y^pr<.2s&*.1.0?4t4D/.$γCP$9 q9O/GɝsC)Yc"M/oyrs93s9/|/\Ϋ*q9;k\ Cp&/kjGzv~i%7MПæ갟șՃփ'.-ph\C .]2cjgOSۉvGQE/U[c}o-qXo֦_7M״X!;xй|U.矌o\Ǭt9/?a3po~߷:y~0G4 e|9ޅ

MC$ܯ+"Ur<_}.i%Ʒ]ϑ3c"]Ж 3kۉO*ϟSڬE}y="ti>;ȿF}=.78N]o ~.7 1E?8~c~my뷿3xb/?3W8O-0xyѯC'Cj]o[FCo_f0ER|~pYo1CWr ܹ&.?f=&¿Yd&ܸdE.Ȋi\&LW$s(2+2%r.&od^ɺ}.u]3-{ǦDJ&ޑ y'{K>dǴ+M왾Wfsm{9ȟrl:_?cH+ܐrmw3ݗPc{?~*兼WO슈艬芎^ѫ:K::S:zwdMmٖyE.1jzu&:T3͵hH7W_letCw[5+kW?ڬOG~UrYow?;#zLK/9Nȿoa@ bristol-0.60.11/bitmaps/buttons/green.xpm.gz0000755000175000017500000000017411233572001015657 00000000000000y9Hgreen.xpmRU*.I,LVHH,RRH/JM͋(ȍUUR25P"CC%.%de40d0kTרQ]Fu5kTtZs{H bristol-0.60.11/bitmaps/buttons/klunk2.xpm.gz0000755000175000017500000000025211233572001015762 00000000000000DUHklunk2.xpmRU*.I,LVHH,RR)6(ȍUUR27P02S0U0TRRLVKle0qA\70q@\ sqA\W I r5iԤQFM5 0@Ejd}%Qbristol-0.60.11/bitmaps/buttons/touchnlW.xpm.gz0000755000175000017500000000030411233572001016355 00000000000000y9HtouchnlW.xpm1 0#nX@ "D)n "RBۈЌý=o\v+т+pisx\λ=ɸ,@J0#a`a6']3,6OS+Us" $C 2d`\BIBKMzOzf^3 db bristol-0.60.11/bitmaps/buttons/solinaOff.xpm.gz0000755000175000017500000000042211233572001016473 00000000000000y9HsolinaOff.xpmM @sJ1",Cj/0::&L0EYC`qIhZOt8kz#υ\PaKok{tg=b1Mb$E݀ c#yal7*[01p"քRT> K ,yan*2F/*5s#_m΁JBܐr3* r# Kb,֮qbristol-0.60.11/bitmaps/buttons/pressoffw.xpm.gz0000755000175000017500000000054411233572001016576 00000000000000y9Hpressoffw.xpmK0+BZ U7oGADfЃn7/+C;ƎyB^:N[+V-gm4{ e)b.*vq5Clq:Kqx5r$ F:ĘY81X`Maa|5QX4`(&r_zA{R138BN`s >OyMBl>{ ]g~GQ}a%;^N0n(QͰ+SXc5Xcy"Tk(5$74b (W9I, bristol-0.60.11/bitmaps/buttons/rockersmoothBBd.xpm.gz0000755000175000017500000000104611233572001017645 00000000000000y9HrockersmoothBBd.xpm[P8 .rS#oA2LLm&AeD&}h/u h )ZuaSn{}nww/,iLlL~m'cI~G:#T.r@eImC9*j::@P)tdhVihVum҉B2lMЈ.Tp]R @c C}ZutBs]e'i>:@uZA_@MR@-:U@m%:,ԥzTe @zuCJ\z UI\n"um% Ld&)`!1-Kz1%%N -"@qOĿV<|KnȾ9%I֋#ot;qCOğQUYCJ# !O ~(c%RRn*U$L'򌔿u<:[3'-gvzݚOOtMq bristol-0.60.11/bitmaps/buttons/touchnlo.xpm.gz0000755000175000017500000000032111233572001016404 00000000000000y9Htouchnlo.xpm? 0|ZL"µJ7Q ڈVnfL{gЃr^.M<>t\o`w8b XzGwnԮ((}|QD"K+ý9D45hn~5Xc5TITKM:O:bfcULq bristol-0.60.11/bitmaps/buttons/patchlow.xpm.gz0000755000175000017500000000024711233572001016401 00000000000000y9Hpatchlow.xpmRU*.I,LVHH,RR(H,I/(ȍUURTT0Q0TRRLVP677W577Wĵ46"us)(GOO688y0\4=\ 2bristol-0.60.11/bitmaps/buttons/dualpushgrey.xpm.gz0000755000175000017500000000627311233572001017301 00000000000000ʺHdualpushgrey.xpmXRK}^}E!<I{#!@x= ߾yfn,}ظO+Tʞk52bbw]ﬞqzpry}spqIMgSO \G=W_f^kz k^83?p/p} W8 ?po  4p.2(*< \c)+<\g} }> \9{ <_ \5__rqn0d0Pο,8 NQEN,J*p"3'AQy'ЯpQ?b!H|R?#_p~N| xZuU_66\m;!ww]|}_8#%]g? x_,~\gM9؏H3X]x_vCs"W58xtj_s/\_95PumI٩_|<ϗ_~)\cx7Y$?]=N_}o9$޻dGÒ>O(ի͇ xq EpC|+I&_,y c9b/Qc>} g87~Wwl6Qd3D}t7C6}(N]/b8zNY{bߒd9#{? ޖƳxN:E6~E,HX0p RYg_'γ"#z1NzW=x?I(u/W;k˿Mد-8E6p 7p-'/=tkzH@϶/|x85SWo 8^yZ bJpq!kE{7/dO؂>K `/ /JWO9Sثw/x?tl:4p_?/?ͺx5W?!y8D7wG!{~sy@\web &y=EZH<^;pQܬyK |XD? =(,LmI*i[o>_0G;A?n}%G~iOtxM¾3;oC-ֶc{{ݾ1c=3%'S| o,⵬L.2/^I-pZ~֫W@ |"_Ki},h{_g *.7~7f"W])$C,,7mmmmovssS7pFE~y}g7q_ .G_M ALI! >կԈVcjR͈>*V=^ݪ%_ՐZVjJ-jN*T6Te5W[XeKjM U6xmMmm~{G=I@#RD3u@ _KuՍ~ٔOUC5 RͪWjN?9~>^7jXUCs>OojA}W+a`W"dWGsMӬIQay |閖hzq,!Z EjPH 1%+GOh-̫5Z I[M;do ]ڣ}>s:>GtL'tJgtNln5?V?|9ϘQd/%{t^?9~>/54F見[=}>JhJ] CѽOWqYUz@ccz&Ѯ2kzP}8!|n^74vn=E=kwׁuW8JuϰJt3rUvFWY5ɌW;zPϮ@#}O>]N3WخW?Ysq2e>5] / ݹ89ȽԳU>?Λ?೦u^wO]o;Ck'>kQoÖ~ {{W7O3Z mWwO5}i0#f\јy>Q7R]C^?71 soe>o\ӭY20yǚj, 3e&itZ&0w>&1iQfc*8kyS0fL2UL[fmcv͞cؼZMSoj̡92L3΍gsԞYΟ~>'߃O}!>oM>7' $bristol-0.60.11/bitmaps/buttons/sliderblack7_2.xpm.gz0000755000175000017500000000047311233572001017350 00000000000000y9Hsliderblack7_2.xpmKO@ch`6jdqibhHۅ =.ntl; \$z^QP.ɥb~?[-1ӷקۂR5#T)  O3褢TsP6T ̘c4@!Y2/018F#< VCtC7)BG 3F[}27z)3j̤1^~2j&:b;.&}qs=}k~_Bh[>xs8bristol-0.60.11/bitmaps/buttons/patchoffSA.xpm.gz0000755000175000017500000000047211233572001016576 00000000000000y9HpatchoffSA.xpm5n@@uy"T"bvmt1.ZM뢉9 3 `Ewڞr﷿P)vU$*Pg)O=5jZS=eG )%F; .E u#ÉKp)\4.A]Z9l~_ۆgD:SY1 gs .dVea!7/2za]a/vo zNCK7{YgڭiQo]?g_bristol-0.60.11/bitmaps/buttons/toucho.xpm.gz0000755000175000017500000000040411233572001016054 00000000000000y9Htoucho.xpmO 0s~] ?[1XA( Զ("sz ܚuHɚ_B*vpVAmUˆa]쥳a k+c+ڏzMJj4nuᇾfTDtL:y(H.3їy|?|c$(k!dc1c QllTdӨy?D\:ITbristol-0.60.11/bitmaps/buttons/jbw.xpm.gz0000755000175000017500000000105611233572001015341 00000000000000y9Hjbw.xpm[kQF8\8:1Ʒ>Ĉ-BHެ]h V?¬e8 zД #V]ꐊz(wU,ם5?h۬@5,sOA$ ,50$mL)%z(k&gYhRFFםe$4z,B㲨QZ9`nHU iX㠢ꅙK: KZxa^쯣6S)[u5 gb؋~m <6#4"ƌrC?8n8!cɏN:7-bristol-0.60.11/bitmaps/buttons/rockersmoothBWRd.xpm.gz0000755000175000017500000000315711233572001020021 00000000000000y9HrockersmoothBWRd.xpmiWK?_~Ea@3vH&.91  E~kF0w^'oWuuLG'02wXmlա#W^?klV?Tk0 } O(GBg e.:$ sR$gK8'xD'$i@"c.$If"H>xT8&2W $aaD/K$ O 1{>xَH㒿xHH+◐'?Dcԧmɗgz0lm>|(~Y/#~g}-'f1VKcwrhO1'o^42d?BǗl6#q'c8<}%|Oks1_듚1}k6؏y|ƿ| Np~.ԃ뽦7Dz/o0(KݾU'y8ejG繌޿pdse~Cz[+⟐x -{$޿} 仐; d!gNإdW2޳ qcK gPpږQ85X[̻m! ==OiUδΑ.gy6OEyxG+o=3?;]~P 1淊^{U$Uūͼc:\6pmqTcTe [ZHkY#lc.?<'؁ݦ>im!}fqg&_`ImqW8D17#!^m:}e1ㅖ'PDʛ.a\,Oг w޽; ܇0z1}5yY'P{S\kݾvzYw;GM>Cw;~ n7yw=4mN3y֓w7ϸb;}w'r\7?11g޿뛽 [>߅ƞY;?ޙs~v{W^O꺷jt; Ubw~|/ցJ7*U}$>v5%bristol-0.60.11/bitmaps/buttons/pressonS.xpm.gz0000755000175000017500000000043511233572001016373 00000000000000y9HpressonS.xpm] 0WuQI]e"A]AvD=9wV붳 ݂!p\uE~970av 0 xZm3E록LEhZZE<[m$q$AN%ƣX&V ɌGYŔJT`dBIoF{R_>1YLUF/|qhύ.z1r!ORzTij9SQsdVQ[bristol-0.60.11/bitmaps/buttons/pushoutw.xpm.gz0000755000175000017500000000126411233572001016456 00000000000000y9Hpushoutw.xpmYOa+AAa`P&Y61BYDEd~2i&1+0m~~7th6o/Fw؞1Y̆ܜe)g 6װB{Ʒvߑ&S'K0 s}hW Ơc4a!G,bX'.#]H0 F`X\-OM%ֹZ:FsU'OL_tP Z:@0N0,X#׹9'X5kX]!ۺd`GOvid^.X'z {KBpk8Yu+=?]c'x+VN};Npgb\o%k*?Op >;*|}2+b`64]};Ht?f`ɲۏFN^w? `u0~mizVdmg:H{͍;/V6g\z~ٸSt3N{N;7 /GW6:~5nIx΃F;K|9x>ŠŜ`bpixskzjy?z%Hungv>y];Ϳ;wR虜Imr e Bbristol-0.60.11/bitmaps/buttons/switch3.xpm.gz0000755000175000017500000000034211233572001016140 00000000000000y9Hswitch3.xpmK @u+.j.|eI"ʐhD .zBA ֪s6yrڬ]V7ESIeq%NjdvG =6RD~@6b $ΧN{ֽ6yZ` ЏPPyN2 h39 8P30! `lX6zOکڧ<4Mvg_Þ;ϘkH5bristol-0.60.11/bitmaps/buttons/touchoff.xpm.gz0000755000175000017500000000040211233572001016366 00000000000000y9Htouchoff.xpmO 0s~.3KފAD$v( 軷גvڄў]w0M&`1M q<;i$~X.@\Јaָo=qXSkk;c`u}\Xi +-G9N1Y2h{deAՆ`+F|Z(Li!J)!r*oh!2(2_0T,$%&O#NsdR\ "bristol-0.60.11/bitmaps/buttons/patchonl.xpm.gz0000755000175000017500000000025111233572001016363 00000000000000y9Hpatchonl.xpmU= 1 P .'qhA6ǵ`'yT % ?{O# \YN階޷f2-9&QfH}͚`mRe¹-n=bristol-0.60.11/bitmaps/buttons/polywhiteH.xpm.gz0000755000175000017500000000073311233572001016714 00000000000000OIpolywhiteH.xpmNPc%ஂt]& Hd94!@S2C@OЮҶᙇ?(_vZ翦ش͡T|c㜱ZlNrS ^}]qH|U<shm-5 X!&;bB&::7!xm<~->[lwGQ~iՅ40ЅbHXK &` Z*"8MG=`ᓖOpzP&Wz >t2|WQ;|ӅR[ݠ%OpnVN.Nտ゙4.Q@3ӊ_ɱU0iVC=OQdR{S]l~m}W0r+fbristol-0.60.11/bitmaps/buttons/sliderwhite2.xpm.gz0000755000175000017500000000117411233572001017165 00000000000000y9Hsliderwhite2.xpm[S@_AQ%rE,s>nB$YPP}Le|m'}z0~f4Zf8FXϲIoltn`}1 u\]mVƗ}H_3E1!c,xK MaB ( :0(0Ge#D_+=&;7Q[aMe/>K<bc3cPh6hQpVŇ^Z@ =ӈCr' B%t~"fw $#\A#ιLU/}-Uٖ@.TcVUʔFA4FLNR U}\RC 9X#&h`oR!GmȘjѥ@^b]#ҕ#'v*ry B?6[J L+ B UkUJn_`.s=}%y|B |%+t%2BF}/O㓺Fyz~G DܷΆx);eY]q@C˛HA}x<֧iYih 41/Y,gy)/aݽx?W vbristol-0.60.11/bitmaps/buttons/slidergrey7_2.xpm.gz0000755000175000017500000000063111233572001017236 00000000000000y9Hslidergrey7_2.xpmIO@ah;ݐRRrx4!$ja~5x`DVit=QLb:M_LgHxD'<&M0/l\ ΅.H^uZ#X3a`GnlJ C9)p!u :teg 5A|mB`($a`LfJ|[q3m&jĆi$8IX6GV-{[ߵϮtKcn#Ѯ1v 9TA cLtiH:G7xo:B2J!iXڦVqAptf<(c1c_ TDJC# /6҇ bristol-0.60.11/bitmaps/buttons/jboo.xpm.gz0000755000175000017500000000110211233572001015500 00000000000000y9Hjboo.xpmn@@+&M !l5ʲ"(EJ-UE%B;:\gh{kk?W汏o/&ScZ]+ELJZw>7b !V jߩji,U|Kj(v*:Fr4ӮU-wz:qzf*vz#Q?HKP&Adu jA;:pnmСX=M0xf阏^Y(|TtjL`W#3po3tAC X5&q*A(p7B-8&@SX#pqI]XhgqDk<KXcJkmX֘(qEk\XcE ` Ă$?4ŨUjT6V|68bristol-0.60.11/bitmaps/buttons/pushout.xpm.gz0000755000175000017500000000125511233572001016267 00000000000000y9Hpushout.xpmYOa+AaE!Y61BYDE~{Lڦ FG>J|4a~~7̄oh-3h Ә.烻墹/9ñ 'gXGQߑct9s 1MBt 'i1+Cб 0&X]1JL,yQ]#G0 SuF_HWb`C&tέl\0,L๮A6|A6AKe uE3:7M3t `^t&:.Y'֭;45zVsg0݄oǓɝ76|3vDJټ . s>>|n~ 9ބBB(WOϮuV7|n_;_9v;aw5}'N|;3oTB 2bristol-0.60.11/bitmaps/buttons/sliderred7_2.xpm.gz0000755000175000017500000000070311233572001017042 00000000000000y9Hsliderred7_2.xpmMo0RF@$4q HԽ0 >?ɢ^v}yBlgW_X>eRv WxKJ -%#F Q\qElݏ{Zuׯ& `1S>!a(sa$j^F_?d~i>_1ed1>}M-XL,nuٷQlYp0RIIDXB20IJ W.U 1 >&42T2 y } p ( 0 T6 jPz a3u @]Ba1!Qv'U}˽!́ږ^rAY@YQFAKa I$,ѣA d9(H #B ̙a691߳T|\p $Ʒ%|sQ(_`pFkrk1O (c d)FL0ܣhE3\K|gk>2u s(BK d TY}ja|Y++PUoYJ3e v6[j%6ټ[btw?GKP?dK(mˆg#K[WohZi:_<ږx[c 2(bristol-0.60.11/bitmaps/buttons/polyredV.xpm.gz0000755000175000017500000000062411233572001016363 00000000000000/OIpolyredV.xpmn0sy %,qHD VJԪrhٛzqϏ*ߧ}/op>1YKP^&9`m93u]Y6Y:L[6QJYaYj }f e$#|0gڽ=FYs-;H@*$^HԊ᠅\%sTe7XRH!3("CJi#9T,()y^RF{aՄ|Bld>(qY|uzUAwnӭ7|7wڷz-\ijs͚܍~uiI1筋l/m_k{[Dw>K4B^st.2im&e|']ƕ?=gbristol-0.60.11/bitmaps/buttons/pressono.xpm.gz0000755000175000017500000000053611233572001016431 00000000000000y9Hpressono.xpmJ@yC..N$ƘXDfWq)H ]ؔ A|w;3&fnS7z2ɴ#9kk bͲmU~{|k &0<NjkVKz쮃*n 5H3ZKZgӪ5yJSf's^"%[%QL~/ (Jo)"M,o4i`D'qaE3FMe?As zdy?3#3*ƄC*QPk~wXcXXڇX 䠠383 m7v+  bristol-0.60.11/bitmaps/buttons/rockersmoothd.xpm.gz0000755000175000017500000000130311233572001017435 00000000000000y9Hrockersmoothd.xpmKo@W8$ûV]VB qT)"ޙA|-KfjlMRbX>/ӛ@VSBG#6jڗmP\9rdB[aA=4IL)d)KSPW\$PO90)e -`#)sFWx h#CPc†ŒdD / u` NQp(\t4D3 97ag@G#D}Aڕ3"؂~ّːFK+ᵻ(CЂ],K~Y$CPatLF%L8 &A,E{4A rcSD #%؅[ e4 Ur@AE38`a< 7M!C/[.n[{Я/m(6.fk=Eo?i?~?PhqN݂idTnkv 4-Ԁ e\k^-QPkLIIVHPG0L)3HƘTa:l޻ ̾s\c"H"ʛ#RP>*oWM*bristol-0.60.11/bitmaps/buttons/pressoffS.xpm.gz0000755000175000017500000000027111233572001016527 00000000000000y9HpressoffS.xpmRU*.I,LVHH,RR((J-.OK(ȍUUR2P02T0U0TRRLVKleCKqA\0q@\GC3#0W5wA^Pԣ v우ji聅IzqTLxZk.v~fbristol-0.60.11/bitmaps/buttons/touchnrb.xpm.gz0000755000175000017500000000043211233572001016400 00000000000000y9Htouchnrb.xpmՖO @)YhA%CfD=w t EN`;v0a:2) XC_Xt\o`7ǍE0s\0Xٞj rۯ"#!n=n'Bbg(DeО0F[_egS@!E n2HYk O;i+AN [2h2;%p6B &BF oo0C0IWbT5cԌ9R3v. q bristol-0.60.11/bitmaps/buttons/sliderblack7_3.xpm.gz0000755000175000017500000000052711233572001017351 00000000000000y9Hsliderblack7_3.xpm_kP)NvǓ-CDnca\XCu1y*o}n=GGulvw{lGYլdS`6[gü(>g!U &%sUd7oS\_n5,;D_H3 j#`i@JР3A/F{إ*A&#`JpMgv"0'(!&}NC?c^;kmg~8uo~Ʈ׍ f=jNkVwׇ I2cJ>[#kn(OcVK;5<-gzƥ2/';)a bristol-0.60.11/bitmaps/buttons/sonicrocker2.xpm.gz0000755000175000017500000001704011233572001017162 00000000000000*Isonicrocker2.xpmE[gWʮ0n,w$L`3E9g}z=gJUҖJ|\cO龱{gƦQ/΍46ef}Yeq8+,oe5p#^>f>7oK{>vFyVd> þ ƍ$/?iV7e'Y/NGŞ?C1ᬏ1N{>~nMM.ao O1~p3qI[YWQO {۷z>=:~}I/cF҆<NOrƙs,i?%J#pٟ8.[I7x &}K>?x ӡ Yp\P{xY~"Fs#c/W7< fy 8J%ڂIvd,A=!3=%8_f;sOlw!I֓1~Bc~CK{oa?|%'ϲGw V$Y $?3,EԷ01.qpڳd<V 㕨gvxxNz4w^UϾg__c~MaoaOÊjߐSԣw>[lC>2hm_)g'sȹO`Z~72pFb' $q/̀9W|D-j_}m8z7lϾ[zҞ9-y \fmw0}g_<9py .GFD(?Ro5>m̏;{ƴZXfy'/z| RK~6gKQv ~uU_pOfZ3j_ 3[gN%9'"ƯVada:-']|4g|b&!+??ENo*oy_|=cmcD!A>IEk5j}c{8sؗ(.TKoI~+Mx<~C/!/֋݁={X_!(|~9?|?dH,Q_߲-eoGn-ϽZWZ/yC,`>֋ciO|8Tk3z|^z,wTyp3Zq Q{cíGI>!Wc:?@f)5߻%B' y[ӿ8$$z?TǺi/uWۗg84p'9'x?H:/Ad>L MXpEģ1r<-c>t67ӿ UoiLޢ`:OzX+:ӔzY@29pxSa?]1z/onSEgpv4o[oXpZ19CV"LOg\%0h߈qq=(Faq#9gǸoӌ?@'T#G"SA~o0F\qnfK2*B!S܎oŝ'8=?~K0>h}f4>'NQ{N{Q | !߃.Nz {g(`8$}V{9q9ߞ8!ynþ&lB[I6?/cX_R?Vωqo8[[f?bߪ(?KRs8 [.[Yd4K {;oW~V}Y5P>pbq| :AJziE=a-ӒB7p2-;yyࣲ$b/rjKK Qj@|"P8qIwpV'G{ _~7,oh>EXB${0'q/|/{!pF;R{Xx')/\{t^j.2KG_\Y~dW7gyߌVAz8?t>a_8>j/Obb? yGHxMe-['4^h{jryi0O|gEs1d=ich}GzEx~Ώyƭ6Y7f6xF۷meWh{oi1hh#m3. 5_#g{M[bƧHߐ>wm81N>i"57tyHqc ۓRHtC?.tehce=0+(Mn+"o=H<)^Gu~531Ňۿh|% yoL)G *<~Er;ܾܦ3?3:^ެ/9TC߁7p!s{;0EMoK/OyX5ߗdzڡ!.a_+P=5/h};OG_]=?֐|*o`iiMg}_Ǒ| ?/An3߻M_r$_sPuFV*+¾p_/>7!/_w v!3H<!ʛh ^sھ_^'p"!R~3Wc峅vT,qϜ[o>{e.Yoޖ?POW-~O/!g{#Ǥc>ć;UB||=j/^Tvh9৭|(ƭ#~&ޑzA`~'<2t>=?}<`~g߄m|!-?DCvt *}o?Q>ߙǬȩs|ǐCOoDY?qK!߻CN5D/JoisQSKw۲BH=ъO.]n}`oqd) 7\7y><5pJ3]鿇F \]YO_q\.0F0^XG>nO`o3o?aL꡾B?K? j_>] I܂[_b9#h߿/A.uqObIzo8?Ѿhv% ԗDx/)%p-/$y)]Cy}?6wOkbKÜʯ~ HE~8&_J?ߕ#߯?(NK|?!QE<$9=|I#~PCv!ߚ)m7iwR}R2kZ%ߌpV ֗[q Z~3Z: ~o$3 o￐(yCV]Y_aMau@ ~W>W RJK/~ [ھD|_*n_RiiB[oj pGKſ8iwܟT7JW6+O1{KK=+^ c8ƆCCEb/~|6"'6E%QYaeAGH=U>w|!Gy7O8K7s/_~7 ؃lͭĻ`<SrϕWU7ؗyO ¨9ÿD>iDftYyN+6Ϙi>- j~VrfȗAq}ZR{ >귶o_3Vվs ^'{|7\s=Kp Dojz3#oƴ/b/R/rkxy78#BމwѿϽ һkƻX{'{^Z^x]M{3ެ7}~x?_޼[`Eo[xɞzk:i{;~AumVmNU5[=\C~7z{ޮsoި?NX/uX{~}PQ}\ԧY}^_ԗU}]Է]}_?cT?/kV7V=Nݭ{t=SsGU׿z^bO^Wzޡ Yi阮Y9aNas2ޘ9f9inY0Cs3c<5s¼4kƼ5{|4g4[f^9kΙO9o6Es\6s\3* v,Ӳ,ۚ1˵*˷&)5lZC?k|6-kqk`OÊJʬ*jXko:#:N3ܺ.Yʺn[κGz^WjZ-muճk֚[?˚~[ ֢d-[ V5kڡG6m˶mv}=aOa{e#=nOaGvl'vjgvnW ;w={>#>O3ܾ/+ھo;~'^Wn-mwݳg;s֞?YOeۿ{e^W5{^0wl?3fyNPx q g: ;ΐYYho:[Θ3l;Τ|:Κ98^N4u}9tc9uΜsY2/OEʹvn[ֻsyrysNi;Kigƙut~9Yp%guVUgYwvha \ϭ]ӵ\u\׽r*w')sQw羻;掸;n/u37w/-Y{'{枻{^7-{}tg{q_7j-M:n;ιO;w]rY]qW5wݡ6ʪʯ&=U}ʵ*ާVfUU#v5^MVgQEz3JiUyUT%5H/jzq:NڴN꼺.ʵ궺czz}x;pZU9Kz=ҜfjyGU{gMkZ6jSuRVj¹e63f:۾CV?}ocW:_C=?#?O3ܿ/+ڿo;'_7ω?ArGbristol-0.60.11/bitmaps/buttons/klunk4.xpm.gz0000755000175000017500000000165611233572001015775 00000000000000DUHklunk4.xpmkOj㯨2xZwR۷IHK UKtQ1&v9g'-9+|8Ͳ `^Yat};ٸ Bc(BÂml:?? X^SddwIHdA@  #k!+(nEH z$-PC@4D3MOkB G`T|Nr OxQu<&k WRG.&kxA6=L*һry}:@y2ҶEaz,,ʯ{7\.52| Ezbo䓊ۆi)\ޑӞS/xV;zK̶1<,IƏUk-zˑ';KOkcۈ)6'E_:mp2Qr*-n:oiSn=u.~OW\3^loU.ߑl>ϳ?.0ӎWE˩i?im9/(\)73V|*\>7# 9Kᢪ(^_1G8)Ϥa mڰ{\ߌas6;k/|.sC/k9w|9~(h$7k]!W 8E ?38Jrɷm sz>RobO[+qD[ʇ$}es9(gv)>I< $ I~lC%TDz.B z! },o3{>LcԵx[0 !Tf}0= /ݨ+խ73>XwjǻVPYgR{l Fꤷ>|Nz:} Q czkv fDרrO+!QӘ\u؀M[m{Qނ5A6z~5Ezl=GQ~2~hT@:ý.Tx=AϪQIy?I2D}ޓ0 3FHBF3H70oy}JۻI^#/g\i)oph];"/x7|nw%56L%x2$ʜwcvk *Cew{7xO8iywDj= Nޭ ^I5>vN89nGrޭ>g:>i\vFג֐GOQnyx޿h6|8;`ijupK 8ޭƻ7d=Ļ7wm{_vqcư$bristol-0.60.11/bitmaps/buttons/jbgo.xpm.gz0000755000175000017500000000124211233572001015475 00000000000000y9Hjbgo.xpm]o0@ǯp@v.iE}H[(7J܌_;M{~'_l%Śɔ٪VӚ)D]w ]w6 %#N[N$xyTNrDszH(SmTJ;T4H&S-Lmgp*RXOJ+1t t bSPނu$a]X${T= T.a+( kPk^42'AccKI+_ڲ>_/N= 8ܺ?^/^nF Tבu!Yu`7BeUG|}:Ɉ}zp -v nbk3 b;˫y_5b|'MHt~u) kl<퉹LqOaKI)_N E=jY0n"]] LT^GX3Vab`Δ#UDtLlDMTJizF pr Ws"'Rf2# LGXP/9ǠC+qGح5l0bristol-0.60.11/bitmaps/buttons/patchoffb.xpm.gz0000755000175000017500000000032211233572001016506 00000000000000y9Hpatchoffb.xpmUM @s=HKc&J)AYh>0v "m^ (-,Ogs`/@èM};SmfV1 Q*+"s)1péRq츴NDvc{#9t`h8F9{c1bristol-0.60.11/bitmaps/buttons/sonicrocker3.xpm.gz0000755000175000017500000001746711233572001017200 00000000000000*Isonicrocker3.xpmE[gWL>B !0Ȗmrr`C淿Urީ[Aq[^^NˣG֞NOnOkTC-X 74N4={#izNvJ Hä:O:I or{=lG=lI=\N/d j<7QpIc,?K1e{VL  '=C8*'p+nw1??w8q+{x%ȟ eoF7[Gq8"~Nd4">OS<%~)ƻ&+:~|ʇGSݲ4(gi+%$='D#=r!>uTvć7p05W{u$DpUr_gw#`o7~3V36'Yz<|#CNT?\+h~A_K(9VPɞρEc>C9 {=^O \af$ao"`_ 8b<'G V;(7J?*y=y~[X?9?z!nJG># _Iޑ1w%A{$$sI>΋}8U=yz 8,؟*jJY~L^mH}M5o䵊[Dsƫ~~~;G> ,S#c=n&v7p1Z1xbOQϓC%BVcuB`=|G9Ş.?#b?ļ`7B|$75ŞS8Kx? &{RpWX _ao0/׏~0q^Գο)SG?4ދ__?U 8RS~_ZE|YR|!x>FhWܿӍ ړ?Ǣ/x'Sw*8C|$9U VBvx E\-dߵ_E{Yׯ;s#ɿ+_z`-~ zߙԛz37 |^%p[ } "?}aߒ#?+תķx &:pK'ٷ!7EM;E~o 0bo4?wgѫT+-gy󄣳?Y n"~|g>_,?I3.k)pS#~ݔmȇ?}1p;ǙOz$?$mg&8muΏ||= ^!'5x=|'Q*93/x`<}9s? c?'/}*6Lq~Q"oRDSh~Fis{_R0N>U!S[r8jnzw#|bpE8(I~ ~Nnb a{|{\zE~8Nkm]k?|i>>mroH.p~}5փt#0 y~b 6<^vțjBE}N~,|?| I|Z#*Dp~}>o/Fv; /d}>{M~b߬ӘC{/~gcEC+WNY.:AP|q8?cyKכã͘׫!_`VW7}8wňC쯲` n~jOAkCO}`g*/A|joHѾ3OnHx7N'"OB!7?.d_!Vȯc_$Ş8!7p!o3@"GzE<1Qx<#Mâxބ~-C y;hdO0 !oA Ư9_ uw$' p#gž6 Z<do`4ޒ[]P|X (^5/R>=U}6%>"t>o8{vѾ7aCY$o]{U6ñ؟`O?`noZ<^P>[?S%ce~ǧ7r)3n*L (p[7$?)V Xcgg !\3|dyOm;)|DsXe8bwA>#>|8BO Od*GWB&~3VrP3[B'OK cB}] B|`;{OW?> ^O?oWӛߥ?!y4}[xmzA|]? 3- >]5_փYǛ|}x2??~9_V՟[~rx]s-ap[-4gx2xdoase\b<f$i|gos><}xo2?o2^6=wmA|Ȟ[r">Q#>Ӝ )Jо$O!.pyvHcvcjK#C|>{;>6gSஒd0s~`˾=w+L]=m{e[؟|{Or3OO)?A<HQ{//h_$]" pzc<^y{:ꄀ-o 5ڽf2/s"iؗ%1'g oO,pS; '#H$m{"U kI߫.#>nR|Wdз/x Qx?H8.$\Y "Oq߶-osv;L[ؿBN7ܗk%,ߓxuZ~G0oT-w ;DŽ[ҟcl/(EߧT;-?_X0\b}gw0C_ϨfY7Ofd>᢫AHG{?`HduI\1B\F_ȻY'쿁b_$OW >[Lo"94^gmo8}qߣ@޻#) vq9=yg4/޴?9?/纔zr#[o%?s~;Oa~+0Pf@~AUT\sٟx ܒ}X* }J]r}Ƞ]s r5<b}DK0x Mڄ[*G~xy]o%ό?_WnzLI=a{ka%!k.gZE}iM]?3oO~ / ՗?1_7'X_,i6p[aE՜wb~:5Ҟ4 k8p,C~'Bևp~JUla7V2\k7(S~VcCwz'08\qKY73ZGr#H<~?Ty gl|q!8Uʇ+¡f؟_7{7T[O)HqxEP=u .~ qXn]0\#~ \# bp0>%}u=b:9O8 ߂K:BP=Q9ܟp}Ix?$>Z-q˂k"wWUE [|g̟|!=G0ր\|r<2ui_o48@V Q\) x#ϩc oѯ_x\KwEx~JxKiW㢟FG8"xL6c7zz7vTٞލ,oӛtLl\Micڰ6 i?ڧ{k#ڡ6ڞ}ijkjkkGڱvjgڹv]jWڵvR?ڝv=hGI{^ګkZSki:ZWf_ڬ6SmQ[ҖmU[ֵ mSҶmW<ǫ<3<ӳ<+=ף|1oqoD o//B/b/RyWxw{'ީw{ޥRލw{=zO3{yޛ}xM^[u7xYoΛEo[VUo{ަm{;ޮ[srtpLrlt\L9cΰ3 9?姳8ΈsL8Ξ|9:;:;;Gαs:g\p.+ڹqn?Νs<8Gyv^Ϋ;Ni9~L;3/g֙sgYrgYSU grgMʫf2***+jTSX5\8PT~uPW#͗j Jzu*ʯ:Ϊꢺ~WuuSVzVS\Tz>&kUuծ:UMW3կjUZ%jZS^m~V]To鞮\uMm]O)<_>~#N_ToKPXOT\/t_?ҏT? ]~{UI_zSo;ԯO3/}V}Q_җ}U_~oVe3h0*C7 c22l4\aLcư1j ?ƧoƈqhLo6ȈH((7c'Ʃqfƥqe\Scƃx4ggoƻa4QmcticeR9cX0%cX1V5c06-c1vߪycVniZmҺcfÜ2as2Os<0М0'=234#36Gybgya^Wycޚ;|0lPffl6;fל6g_9gΛ 梹d.+檹fo2sʵg9VeaeViVÚƬak~OkߢuFCkšo ЊJʬ*,::έ wi]Y֍uk{k=ZOֳb^7V˪ձ4~Y֜5o-X֒lX֚nmX֖mXoxcWn6m˶v=e=d؟}`#=aO{evH";;3; ۷c>swa_W}c;~RG~_fvnٵݶ;vמg_=g d/+o^ {޲{NtʪK4K˲tF9UhI,˃r)ˉr+˯2(2*2)2+(<.OiyVeyU^7m+ˇoX>K|-l~-WSvrUΖs|P.KrRkzQn[vSO@q+Ww t-W-]mS;쎺C;$s/7pC7rc7q?-\=r=s ҽrŹνwܿ>/?}smN3/w֝s]U%w]qW5wpMwV;[mgFrUCo }(nјj5O㳱8Po18lL4&{W#h6_?VGJbristol-0.60.11/bitmaps/buttons/sw4.xpm.gz0000755000175000017500000000025511233572001015274 00000000000000y9Hsw4.xpmRU*.I,LVHH,RR(.7(ȍUURT02U0S0TRRLVKlec0qA\CKq@\0qA\70qU@\g0 zz`h96G2LnCpP5Zk.(-bristol-0.60.11/bitmaps/buttons/touchg.xpm.gz0000755000175000017500000000037611233572001016054 00000000000000y9Htouchg.xpmA 0s?OjbDc2 ;QFA3Jj!ػa LG;Q&Ʌ_`wMtq% ln0jQ CZʨnyEKA5h[I,X6$Qa-LsnƼ@|ҩ/AcQd`Q֠AyeQFeXF()aRqR69kO)bbristol-0.60.11/bitmaps/buttons/sidbon.xpm.gz0000755000175000017500000000266211233572001016041 00000000000000YSK/"E6}%ٔM@D~<OO07dVVՙebzlloS6wOdBvζG$^8>X^r94ҏ$gS `$MƓ1ϓ&rn2M(sWdEe1zxF#u58y$p9.nisΏKm2;OdqK#7&u|k5y;׎d0g2~Da2~LOQc2^ 1~dž?'guZ㾽 w~='*(M_q`=oO{x}II?z?NCKO}9Oz\G&793.X(/Mo &&nXYrJ޿9S61{*.oq|Z59dKyWڲY Os޵YByau>!&f# {_p߃z gl~d`+2 u>>m 9>#kpl+!ej jMo  zoַgf0,~)q|;F&7Qsp`/ȥ M.Lorg͑[3gq`̿4x!37ٙ&0̯gɤ{m;2m=92.Z.eEVeZd}ݓ+-}yŒH*RH)=Y ٔϲ%۲#{{ȡב˷r&}ssW~ȅ7T^Nj?ǶɂP'N][z:c3z_dYtQoDV=T3͵R{u ]Sjd_ojFsYgrSGu_=SsO[?Vc'Nz|CO|}:&WC bristol-0.60.11/bitmaps/buttons/pushinw.xpm.gz0000755000175000017500000000142111233572001016250 00000000000000y9Hpushinw.xpm[kA_1НZI&̛ "!Ƀ1߭Dħ7a2g.NUlWCݞޝ]] _:|ͧwlw4 a5|xr1|qX=ggl L h7;l`RS60w | `lw6}6MS68*K݊uZ}>kgaO}Y)z\et)yId|RI5U*-Kְ92R-~mxj95H!GAʸQRee&7O2u{E .JHo[W@9j.)x Q"OI&n? ^f5hh5zа-TUDT93sK5J\)ܤ(likzE"Pȉ 9%i-i=!S\p`ܩ ajP&r4䱺ibk}$0q%rTpt EWTCT:aM`hj| GZᤪ 砨ÐsVD-(=t^oߚ B8w3L5 Csa'0kLTXC? R)YvӔ'E)YiCnn'dE~D<=ƀivܧh1Q>:DvG4  "A iQp:4rjGgFb=ߟXD<_}ӅA5bristol-0.60.11/bitmaps/buttons/rockerblack.xpm.gz0000755000175000017500000000054211233572001017040 00000000000000y9Hrockerblack.xpmMK@WlUv? !!ݤPPVjLZ[l,a7΄]yV*RݖS7e5~yz" y>%\'n[69qڡrJCDI5fͩtca3.8XKD)@s0@)e_n "eޛj =lF*ґlmF#c >@opbaʶ`)l6e%I$ϥ-LuN\I8Xk}SXʇ)ܡ6{:=4mwasSFjLηzɮbristol-0.60.11/bitmaps/buttons/solinaOn.xpm.gz0000755000175000017500000000041511233572001016337 00000000000000y9HsolinaOn.xpm] 0]]hTJ_AyeCH/1RǛgٴa4Q᎟丏b>7a!\ υ>f0oqxVVkMFhv쭅10Vťj{>Y#T5SUl^Ӭ%;FC$$-=ч âۈg̘Hm$CG F|h_DQCetbristol-0.60.11/bitmaps/buttons/jbwo.xpm.gz0000755000175000017500000000116311233572001015517 00000000000000y9Hjbwo.xpm]kpW$ZcV[V>ϯjI=.|΍M4u?ܸl1ayꦟ?\}u0tM7O\9Oݻ{mׅL߀枵!% AM;ȴAM{4 m0hӴAM+aa+SMk4ĠgAV14!-S>A za`KL;taǠ^M} Z1cЪ]hgŠivCfZŠuS-04Ġk :5mc;SXЙ}`{9AI\;?oJiD*ȑUFk3BV*/KbeM_}YiD?H@" xKh7.I>x>h#I#kw?KkB¿ k q$ldX)`+ Ɖk Ɓk< \5q+E8`k\ƥk Xc!Q`kTX` _5֨ F]5B( X5&lLXN`kƾoƲha'bristol-0.60.11/bitmaps/buttons/slidergreen7_1.xpm.gz0000755000175000017500000000141311233572001017366 00000000000000y9Hslidergreen7_1.xpmKS@˧Pȼ2 B !CyX}3IQEo{;OZmdh ǃU6Q['\i|,z͝0b bIaѓ܉chZ2_ XA (dH0T)Q¸ʡ\c(8[Ȩnm`밎0 ji$9]is:E@4X]y`F<ØFAXUq x]/XH:R0\q8T̔zgRh"n]V`y< WS1SD)]L9RhG\X"jT0M•Py(lG vCO0(}BZ n8YG)kpuC$31w+Rd0v΁Ιfuγ @[=# ss8"Km˘ (YMe -P >f?e( >W4h 'UX*g* WfXF"Sa"oUo+׵jq7Qn7.ݳL{͛TLJ:U<2h8G48%ۊT$!B=5'>G{6g}=!<=Ͻ G-7GW=NW^=J }YmjFK^4c1x~oSb*59󋿞b%޺bOWr~~_W*%;en_|{e~WU/s >Pp?C}$?Ge>%2~IGGY'UJE~l>.ԟˢJp~52Wmq^D)/֓z,G{RQ,|/|DE+~.K$ߙ✱'/;8c)N x|Md/*5zO)g4>ˬ\?_= gNVO{gs%K?friOWr^֊~|}izdp=!!jG|%EYzJV-n_de(_$d%^H@UW(gऒEw*v8|v+v-?c,y}&{>MEVlF.?0#MVpH=Կzߊ?/|.Zz;*_ըy$Y~խbAz|u7/ ;oH;=?vW|{dϋJ+OM_\8ߑച?V\+O~O?~)z􍬾TU_5՗ \#IǵFS3_յ>we ߽ϟPC[u8^R|c.χ؏^d.+!;)y|ʹ󐓝W~$7gϘb7\]_=gxJ,K~fW7V'ηzX#>9$V_lQߊ+o[4(w2ܿb }P1z$s {DBIГV)ۗ|a?$76_ӃM%alSbg.񎨿G=[wbSTK%-<y~|VNi=6'O떾o;y*%Vl? ߆9T5^"rϗ|@h~q7%߮a1O5^OmY+?߇*聯k.@{Rc<-{K_|}o/R߃?z z_J|z_Lz̷<FdZq((T_i\/?̔%Yŵ~:VyFſ(^O|I1ƿs^Q̿4hYV@zi_E& a3/E>Q0ߟr{oUk 5aSş9{z?'y^7_%u/Ϸy՗8 迟(xK|MH> ~*9^_roqBC0i}9~Z0:Z -? 0iߠm~6?p*82<ʢ[uh79rgm*GWpwa> % )?O$W.|s\9a!ge -=0O;D`%#HᄭA Fa ƙe&a a`VXDZsi^,rXbeXlzUj:#:f9S:otNtI!+79ncYU2{#{[DKSB)e(=q8Q&SF \ktȶ'i$934Ks4O HcMez Z>wcdc`xMuKpxE8 [1;XS@sb+j?85wDLs>-Ԏ:wV'u`. FS>Ay$ϺS>㽈ԉUn\gWj zEӻ|<ɱ]2y9 l r 7]؏'\ܤ!4|_[ahQ*jZYtOF>5\gxU2U^{Ă;8 qcEïhj3ՇGx' )~u,FXSNYeG8g;xx確0fwQ5-֙y6 p} ~:Xs#djwqY 5k4!->a Sf>WÔqr||{EAҗ0098?qyM`8&ws>xf ,Wtk 'q qWcwXu"E@FY0`;\p~m}'B Â]GqdHir@oh*YkP5t- QbYpsuGkîp; fҟ9G<g_// 9#lX$bristol-0.60.11/bitmaps/buttons/touchy.xpm.gz0000755000175000017500000000040411233572001016066 00000000000000y9Htouchy.xpmO 0s/.?2`AVt ""$CePD=VE{N1;;06xdŇ~O Gb՛!U""$9^6,cur2Q1Xm.:V*V;jح i+cBHf/s=#?=xc[1R]C 7)1c1|P"U3nݼgN-rxbristol-0.60.11/bitmaps/buttons/rockersmoothBWd.xpm.gz0000755000175000017500000000117111233572001017671 00000000000000y9HrockersmoothBWd.xpm[P`G(2/SMĻN8>4QeVQIyt/gI)·/EK4Ia r4z?^"lRiK\]p HSiC(|^~b\=V B]m6*Bl%B?p vkR=C[u:c @8ʂn6vxm@T@5unh>rmSKQ[ԠZjIjqP u|--RV%rT>Yh@5O4dg>J耝:d1\1h_3mS]P]^B v5#JY I<*5ůU%vsvWC"w)tr'څN{eYg<>vmZtJT5$D9Zv:Ųx)I"IA(o;s^1 ܄G7E3.{Iv{]ަG;;J 5!DHG+]h b?pGG+h7 0?Nl>_, ~4N~񖝰#'ꑟ 93 bristol-0.60.11/bitmaps/buttons/touch.xpm.gz0000755000175000017500000000037511233572001015704 00000000000000y9Htouch.xpmA 0s.DnE "D;QAۗI;mQDwⳏ :II!͒P4[p1D]ˆN |ƽ/'9V+++++Ƹ:X# +*4^#^g ՛;iDM>zmAk12DQ =C 7Ɛ1c1Ƙ/(٨(Q'e#bristol-0.60.11/bitmaps/buttons/rockersmoothBBLd.xpm.gz0000755000175000017500000000117411233572001017763 00000000000000y9HrockersmoothBBLd.xpm]o0ǯP'vlqMTV߾wc㢶#?91$w_>Y_z>Ws˵lpeMݍsZTjQ`ŁIZaj}]l77!clF}1#:KChL'tREJ@e: t1)<.7a:Ђ0fkdnjnF6L="B.,$\afb0Js܈FEf솏THE6 (aY{՗F.dc7B9R(p H%Qd#2 Gr*fRKr`$ĵ(Xs}.IF߂EY9Gj݆RʫΙ4zn'mofؽN缺Z}eVȋBV/ FxI7&Eݗ뎓'qثƤ`f's'8L0N'!#-]f!#mxD 8Eqw>F8n>`,.賎6ޖ\$I4 XG5RӀ`YYNS {b bristol-0.60.11/bitmaps/buttons/slidergrey7_1.xpm.gz0000755000175000017500000000163311233572001017240 00000000000000y9Hslidergrey7_1.xpmYSYS$1YDTD(DH¢l}ߙJYww%Mw'eK.w{Nw;ٝmH|ʑE#C#fm ьZ-88_$<\<*7 #rDp."+_/#<\* .g ?";/\\'Hnk~ ?3}L>.gp$ tK :pqQǺK:7|pFnޕ[tp[[pGU]:O𡎗!|W 9_2c9ODkjYg^rھL#Z_%pCKEJ'GZg1[9<!\ ״n8OSni rrx78^ _gc/e/" W~-7i7r[H/^cpC Fޔ?z赏mFmv*6c6gӉ|tgS6aؤMٰH4죓>[}wνm-m}tggL~jleE>96GbmdDٰvߵ+Zl%+[vϭľbXG|tg;6Fv]I۱}E~:_3;o}tgO.hr%]̞jz]ڕ]n6э^MU5Dپ}3?w|odz_ڲ_ hg} sv@U3nm5 ]w?i~/% ~y{O|ßCoK bristol-0.60.11/bitmaps/buttons/touchnL.xpm.gz0000755000175000017500000000155111233572001016173 00000000000000y9HtouchnL.xpmՖKS@ï #+I/YN)DT9+sI?)nKhuCAWAa8UA5)bWKarlcȖ%m()`#aVUDdWY մab%mx3gbU+Ù Gm A;)[A;] !c)#BZeCW 8ΰSH:kM;C(+h2 f(4)*SYL#ǛD"bX24fe `횰jR4LtuOX"R7 E>R4-X)Zps_8?I3+" Ų} +bņՀM`:Ե5|Ȅ9DK~xk[]k W]wgt碚cT*)))CscϚP+[R RX ҈z1GX>4rsnF#ubS#T:#˙tsQϟ;4gs%ͤ*l=ORci?6[U#.^n{y~ vI/5pb6mV>+G:+lД\ߦ ϝa]emӈ:VMܩghfEʼno|\nܙj=sc3|=Au=X߷k>[Z,r Db5)WS|omj|J65~%ߒƿd4 =n  bristol-0.60.11/bitmaps/buttons/rockersmoothBGR.xpm.gz0000755000175000017500000000104111233572001017623 00000000000000y9HrockersmoothBGR.xpm[@T@."Om>51H6f74[ׇ&(ݤ@If2_0gbOs{>>onOLmvuA0x}'o=f=pxxЗ0 )8 r.|*J cңD$9 ǀ%C9nJ9y P[ |IYLEXUr.Ú+|.+Œ|Lk ApeZ" |)ʡC,c[QN 'Xʘ1c_q8hXVr!?5fj0qƕÁeQq3lqxzdb4CWaGQǐ#ި6AQf܌qntua<WUoќAUFu]E]zѥQP7IWM'-1-4fIĺS1;4:4.5\ȼt4+) bristol-0.60.11/bitmaps/buttons/rockersmoothBGd.xpm.gz0000755000175000017500000000106211233572001017650 00000000000000y9HrockersmoothBGd.xpmQoPWA--@AJIS[f0.괓bYQ'>9O>c2Ļa퇕X.7nN_O>EVBµSoJYu'n@MhohOT6AU:*@/B>RچzNTzFUN4i@--W!O/tD} f<tGx]%ԥQ}UT@}[3j]R_yt: }fCM/Lbba="n3 HS]?%޲ZEjYVz@(V)I8Eq<~ߑtH~i{Ѣő;T(ΎbAU1lE;h/~w!Bv,(u#p7ZU;QT?xo9˒ǃ]qGgA p bristol-0.60.11/bitmaps/bicon.svg0000755000175000017500000001273411233572001013534 00000000000000 bristol-0.60.11/bitmaps/keys/0000755000175000017500000000000011233572002012743 500000000000000bristol-0.60.11/bitmaps/keys/kbghammond.xpm.gz0000755000175000017500000000041211233572002016137 00000000000000eHkbghammond.xpm;KAFkW\6&FB >)H}l"B9S `{> 4[O)l;u_^J~tedyܬkΓy"q FoCc1z:Dt/choFÂMƂ5 R#A#F*jT4h5RiP 5 + + +b28iKbristol-0.60.11/bitmaps/keys/whitedown.xpm.gz0000755000175000017500000000027611233572002016050 00000000000000eHwhitedown.xpmRU*.I,LVHH,RR(,IM/ϋ(ȍUUR24S0P0S0TRRLVKles7qA\'#qU@qUATq@\70 FbS\b*bIL{(ŀX1dCDZs{ugbristol-0.60.11/bitmaps/keys/brevdown.xpm.gz0000755000175000017500000000032611233572002015662 00000000000000eHbrevdown.xpm1 P9yK!1j+0jHäw!8Y \צbF˸<$le_t\iDwM= $׻NyݫSC:H cC r"qH9UCZhSUs/'FY9s[k̙3gΜ9sq\41Ԟ>`^bristol-0.60.11/bitmaps/keys/blackup.xpm.gz0000755000175000017500000000054111233572002015454 00000000000000eHblackup.xpmJ@F).ɴĤ ڝR ɐWBA|w 20mr0Yf3m[o%ɻBjkv[* Rg4=$]Ġ1t%͔BtKIES>cʧzLcC=փ \wX624ϋ~2qN7O~2qNw]r.G^o,r1(r1(r1,~ywwON~}Q, /Ӗ{7(™ _-i`3 s(,QQnQX7FVSTw-:kUZtӢ]Z-KPPPP}kVrSO1bristol-0.60.11/bitmaps/keys/whitelup.xpm.gz0000755000175000017500000000037411233572002015700 00000000000000eHwhitelup.xpmAKQFίb }Jd+Z 2>g!Sr u}[;gsaz̟%E2-^|K"Ŷ^Oax|Eq(>eK-}7g wNTC1w mmt)zһq ]+P?bhwG ػjn =^Ch U U UVη!B -B rs~ bristol-0.60.11/bitmaps/keys/blackmdown.xpm.gz0000755000175000017500000000037211233572002016156 00000000000000eHblackmdown.xpmK @+.N=0!IhW ",(J w 'l81 &`%}?M|VSXܶܔdh0-[[zXDh =paUDQCw:1 KORIaGM'Ja]ɿ%NU w4SvvUpᖆUweEaծvB+: ,$bristol-0.60.11/bitmaps/keys/wrevup.xpm.gz0000755000175000017500000000020611233572002015361 00000000000000eHwrevup.xpmRU*.I,LVHH,RR(/J-+-(ȍUUR24S0P0V0TRRLVKlec0qA\0iQQQQQ* (֡bristol-0.60.11/bitmaps/keys/whiteldown.xpm.gz0000755000175000017500000000075011233572002016221 00000000000000eHwhiteldown.xpmՖ_KAşSq6גTY̬ "‚( ]sfke샿Ù޻vu~3 lq0{-oOWLZs:{1X!k 3ag>f.A}jA@C@q #Q&L5 x9 5CzRxvqiO)%"r/J^*%_^Y^Ӭz.] ӳjg%K$r 礛[9bQ OVݸȥDޯjQs(29"=霍EoV){UrN99b/"{:sd#=霵q܃ʅX{~A9Cֲ<h暎GR*G/ܜ=pybɵ0p,Z-O*?yCGR4 bristol-0.60.11/bitmaps/keys/wrevdown.xpm.gz0000755000175000017500000000021011233572002015677 00000000000000eHwrevdown.xpmRU*.I,LVHH,RR(/J-K/ϋ(ȍUUR24S0P0V0TRRLVKlec0qA\06#(Vk<;Wbristol-0.60.11/bitmaps/keys/blackdown.xpm.gz0000755000175000017500000000055111233572002016000 00000000000000eHblackdown.xpmAK@+-(c:nBAw MP0{xxe[na]L#1%ӈDe=F.69.0=48PJ9}hA1bP:/0=4.9zā&)͠eA+S ʠ AkhŁ6PcЖc#;-&waTs߯F*od0^3wTu"~@8< c>n&ts1q^7Mnr%wz2m(#>#bristol-0.60.11/bitmaps/keys/blackmup.xpm.gz0000755000175000017500000000040011233572002015623 00000000000000eHblackmup.xpmAKP׽_qF#‚k0 4_Z~灡OxQ~Hȧ9O}TfK)8ˈsCG/g7(0/PF& 8E- ̀y5@9#I`K'4N\r&[3ڍ9mk9Nf7Ω^pjЩS#ߜ+Ž∯+ 2۪bristol-0.60.11/bitmaps/keys/whiteup.xpm.gz0000755000175000017500000000022511233572002015517 00000000000000eHwhiteup.xpmRU*.I,LVHH,RR(,I--(ȍUUR24S0P0Q0TRRLVKles7qA\'#q@\70+v@bbbbbCM $_bristol-0.60.11/bitmaps/keys/vkbg.xpm.gz0000755000175000017500000000017111233572002014763 00000000000000eHvkbg.xpmRU*.I,LVHH,RR(NJ(ȍUUR24P05P0V0TRRLVKle0qA\c0(o7ypTkp bristol-0.60.11/bitmaps/keys/brevmdown.xpm.gz0000755000175000017500000000027411233572002016041 00000000000000eHbrevmdown.xpmRU*.I,LVHH,RRH*J-M/ϋ(ȍUUR24S0P0S0TRRLVKlegqA\'q@\WqA\70qU@\'#R1$OL O1(>v qqN37pa/+ 7v?Fn^G3`Yxy ܍84+`o"'6~Cߜo8J؟*^|j?C8DQ8DŽF(pB~ͯ8Ez|Z*mgKM=V 8/o?1oq5˳q|GScnsB|I@~OgA53o6\x_Kܯ+ܯ575I |MM ?j;7`ןV JX4?MR@^ SϜ[~˄?M;Q'|ן WG{(Oz7w!_?6{ S,;gqxqz8>Ŀm ~ 18a}Qm>$kV?v~c'^'À7`ߞ%/#}KaqeKEQzşq~|@1_7EVq뷢 ]5~[a}GAG~+:_EHS /Mj C)7(ȟzUT۸ DY"I*0EE^7EN~l`<>ozpq%?w@輬A.ߏ 7 [|~zU@?a5@@Co9zI#C5"`\I|˼}G8b,Sos9pM?5ce8a~ÇcO W "b{ZBy%!܏mԯO!/* صq7i\ ؇tHZOx'cxh=K8?L|F`}*跤|$1m/fܟ?{]y_w?7$OX$=zkSR}gp lp=Vq=?Wl=z#Z8$g??`no?A>Jo!E~ۀ7qvap`> qG\x_?wO"Sgouޏ.nj5b7S?͓= OXD@lOZRW9_-7Bv~? صz5'w4iG\o;5/߿ٞƇ >/1GIdI://ElC=ۀ{V>)ypDç<â_D'Dh/Q7uxDbHYIxE'HE&\-r]'}q ϡ='Tsq.祸F܊΂^""w&!FĨ`cR+>輦SbZ̘̊9Y bQ,e٦apU%RJG)>$ծ:T5sU*>˩E*>եzTzQ3fS&Eԯˬ.պP[mAui9LDԚzVOSZ2Q|Z[r"PTL]}s6Mj[5ՎU{ECV9)Ձ:TGPuǜ^9{ę:WH\+uJPqbΒQ껺3`r[VY1XU:0]iUQsb.`w_gk+3zmqiraszL>b| 9 <5yQC}1[V9hjftD*WosBB35nF'W5OpeŜjJM3:ԼZPklmZ,%VLWՖ)%ηlNt^9lǜoY1$˲Ov&poY!xr]n-7QV5,'}PFrx,.ouMIJ]%25Vtlʲx]'}Ձ<4M,,#fl N䩼itfGę<R^\³-\~;y/Yyy0OU&|;.rD1gL հIkyi4%'8䬜rDN)\+*L3)#-9/Me=C27q? | u’{q5?i%ݮe^Ti]KſWb{H.y+{%]}KkSWUݦ3Y/::&@IOԆzS{ 9Ր^I{ׁzBNP߉HV!FzeEzw.-j΀TgzI}V=[[!9KԬ1˔Ϩ[VșIsMqs}| 9[1 s^g++[䑨[!߻{r+߻{r+rQMsG=M}?{| 9>ѧL ٻ[VtWWZ[]}Z=/}K+C?芮\[o]1bF~6w gMlNE 7?W=ieؕ}yzFϋYޗ0'^G<*2._;].%~~X[Z8ʑ96+pvtzV~䔝>K?s..is^WGgpnO}lv :CΚx.OC'rb5I.rНW|b[s)1e.bristol-0.60.11/bitmaps/digits/kbd_4.xpm.gz0000755000175000017500000002113511233572001015327 00000000000000yҺIkbd_4.xpmZiW9|Wt&@=۽IξNfp0oSRo6|qpYjTzmz򙵲3V__'G[ ߻ş[w]+3۝N0oP;1wnݮ_a2:2* s^&^I{Tc2WNKuk/u7?wh_1h}i|Ϗ]މ|G= |Kߕ Et|W oZ!w/" e~7D?;$! Ϙiy?D3^ >NeNbI=7ϻ )=}G~P aJ+~8{Od䃾b0Ds$DTBLړa\!_ߥoDP;}$|?H#ry#'g<υn(0K/;¿ȍfdO(>"iKۃ|^;i$}þxO.#mq7",yb/B|/ݨG!K§\7?_../9I!c&q,[CҕO;%N,[۟x?. "IGT# :&|h=7?i> ߣ_n\$/i$n}i(6v/{?8972#_$諈oE|韋>$ {":I(} ?:i!}.Yړ//GuS2K1ki i7ßOJ7/ɗAJ[KHA=0/JG䍳LeRįħ >ʲ AR_wHn)"4‡Ϫqw|N![ * Rt }WP[f_|^V|fH? 8',MkZ92~A%=uYXHE!ݲe=)_I/ro*ѕ ݡ 9䩬7If>wh|NHg4  y?sw>";<|n ]y9~yJ{H"}|—=+ޗ"! ?z[HU{E  D?ȡ (wi>&9ɃZ)C ]Od>N ?>XȌ4O!2 #>3;SOQ zn+5QAH*$Vj>kDJ>oKz[.@MYL55y4Hmߞ?~FDD3z*c_Ic{׾7/𹰿#db=M߈DF2@/U:-ʉD-ڷl˾?ڟjQӒZ-&}ŴSm&=SƚKJևMɞzb LSA^Y*RCxMKk -XJz@K3^ X]ǖ4X{j݈'ˉXRK"⭺c_5'|J@SL4ДPjADCzrH$cݱPRZDSaJ4l&E.>Ѯ" - {L31~cpLKkfb.)$8Ƙ*&T ҷҷOQ.\ kAvy9  s W5+oc^֌_[✲lRQwyV=ke|Z< =҇d`ikLcLCLa ԴWS7=zje*QOjۇ> }NȶY}þ6~}x ?',Dk&_B9C]ShlUgxz68T#5U .G$͹}Ft4X[_JZ(koBC(jY#_c+-ѵb<%ٰ?X OuFeM{ h@~W+ϤF|BW h*iTV7zW8DNUh5³J9Nq xXNZ5A$ـ~٤U&qrQ"訉DΠx1:? ϐpVB[TiV;˔ִnS])~;%[ (|! "Bx. DuC‰Xf1&/Wd2^>q9yxřXKp5Qq5.IFsiF$@6/;oTM; ϤcL1GvhT-[ܪWi?W?qp>]>#>j|֘C'Z5':2 &/+WkSuNqc=mf?Ux]ٴij Zx(7?  K{KZSUu\LZA~hhj㙥:~*<=:^OwipD>&vu=Q,>A6c] Ilm:yYHO:&V9B} q|)Q79EL=:CXI"?UQV`-_h:S]VaWo+PvAjkr?jM0I.;jߟG@c*ZEVÓp5!h{EK F*SC#6i1ڹmԷ9ISUBuDЎOHioD.V ORH N#3,GmbV'TLשBC>\w:O)vܞCR֣g*aٰ>Y>GflWmkGUIvi}S1|&,7g8OM}v>< X\9Y =)2B0zT@8L 7f[f/'G=ꔪڌ'֮ޡO -?֣-uD>t[:hTE>wbAWvR9S#\# QU#e}ZwNid~,B.ԁ~n9{d!*QC >kI9oO=Tnv;㨍}225{k5ft XOaM:䠽?#0kVmowKTyZ=ZW6kg\AGOpnDN'!#ɸ1ioO_-Q3UxLq AL)ٌsy7UT}sGG|S !hYymj#Wtnm/x,8\ƀɐ xkr`CR wOz$u؆j9T~3Rn<Kcsgg7L^lS^$?WˡP ILϞbi<<<4ko__j5x*,{2'k9tqޟamMu!a홁8fjSlI\w? Z/W| :;a55%f" j"l^LGd4+xF-Pl 8ludhYF--?JT&hG+i vm2^jxH4=WToAIį{]ywIoO<̏xV!KAڊH}0gD3dj:kϰ7L"@mW$fLk<3h$OȗxDIr1AXy?G֟b?keT>dZ흊VP?4eTkj^qM~Zs;'uO/h$Kd ⽃S{ׂ^J[ ]WqKAaa@?|DsH ϯ{7kF 1Gsi۱Px<=!'C򭋈Wmy ZyJ ;1W;m)<7afsZ8,&%6o;Öt[Cf#gq#g~yuXfQd H]9][͛t&jH~>86/ckG+ FpDzcĺIDSz˗H `N3bx 7'oG>;cy؛%tW07~C*WDV5Хu-zls9$hޠ6OLt;s!~<]jJt:{W9"+^+]LP5/(V0yhN 㩍+MG'w"p:M-^y DZpϺ{,IL_ 4@9z2D~yu[ouVStAsG>_evhSc<̧&4se{Źo/tg%ͅ^D2 p rĩv˸+V%ZG-"vr$7gy:<~c r+ DޡWU0+=-FVѹr8S 9vڠkO3dE/:]Wh{]كw:1,j&s(Ckxp:@ÈFkuSFVZxngŦXHa/!v o\ +˜5+sU/+rw~Op|ϚƳDqv[c6I.)=tʚ7 ) 9S'Fzt)j#lYwΰ/*7[]39 xOd;h6KG?]:bNw,{)˙̫60۠UtA̽է77MA,tCM{hv g}" .) wXg+B$ulC]},du c ;j7`ۻ<(in$ޱʠS%^qBD8k>ӈ·ۋ"xµNHF!4*Jf?gnZ<1#PTh>E;'R_k3"~o>/Hz$i}C< ^$}B}wq^sEGy_ĸ߯3UTNT᳆y!^cbristol-0.60.11/bitmaps/digits/kbd_da.xpm.gz0000755000175000017500000002210611233572001015547 00000000000000ҺIkbd_da.xpmZkWȲ|W(C-+zI&"'^"^=˯- ?'>m/=}>{}~>baO?xy}bOG$r,r;pOש43y^Wd/=[4\_xx,MK no%_!u r6wPhBka+B<%0KMAe/EBix]V{X彴v!?QyE>Z>U'a,q?kFXw]"ovlxF xE!OoQ-vԊaW#r BEO[,r#ΑxDΣ0F~ZY?gDOwGo^d?J[f "b/}X-~$["v#?+/(L>DǙ_ [?S_"qb<0bB(n >/$zc7c?~> _aoѻq"2$wEn1ojE:I,#D1 $i%HM\A}/KZ1PC M-$HXǓhGcO/qE&r߮{OƾD o[߅IƞHܟ}/W"Ic~_i$[o$a*[Yx܊ĉo'>ߙ@6'xKbE=OvڔS/gg_\'"{e4秱OV {?.gi>K[2_W K}F1ѯ{ 0 T9k?,?Y(|@N̗Dne ox=ϡlY,o6dZ,]-|,}3K2蟋>4ERL)g<䬕E)ndidȯY`=X2}Az߬vωmLڇTG7 <Ȼj?Ey3wsE䞴3r;W"$?oD@҆-H#,C|DTJ0Om>9(b/Z@ǷhrT φ?F cEwx2>Gf|s{~|/bLde_[W.d|~a#-K"?} t&|>!ᤆu=3|#&h sTꫫ&Z BϺ%>g=՜iukH6>uY3k`jWG eDw$O֦c if;3y5kQ9^Wxw]3VFFJWZX1,Hco[{/ lМ<*,7wg/3rZαbDp`%uvcpi|uN4wWp_,|ked7,#<`HɾYY.̢$!p@R9~]bs ==gyOߌO5?5LW_37f%]Q8a>|f2pI( Hř3=p w `ɵ %+~ph{Ɯ,b󞘼W>ifW>"qL BN(L7 Z^؋%Άkw:f\}@Ѭ^ )6YZ!dvdMkޅs0(J0+E\+,?s y6a{! aY 3:%Fkx"=7u6+#5yNVx_u',pW焛#W]-S/vAKpn >#GL| yigN ɒI'p@vwD<Պ̰J̰7S3v9%6*i1\ Q&|8׻dG$Q 7X4҄O|G/Zƥ Aʓ͠ixJ>)y.߀}GfSl"'bBXo>|u|:-Ç 5Tȴ.>=ojC a)gg\vi, '$ ّ¹J>%K_"w%~Muvhelãf#K7Vl j0|ViSm>e*ᳬ|N<9ޤRk2]o${B&e:c >-E"2GTp{t%9Spb\G3*>2;PФYRc?8 >ԽT|#,)!BUKbUsfɥ.|$ W)fL5M+7u|r]sL烼>E.Yӊg+೮|x?rǸKk4ygNZ6;5l29i>'Typ106&|.OGe ;Sݯ1Dc΃{dy='h]wJ6CDO‡aa][oǨFG tL$?X3/r ;>|}B꾩Ϝb,‡Mi=iQYĔۘ+1OodY4 p5:;VP6O a>=LQlxJF\hο8T>a./)88lk)`^wfv,L@6#fӫV>|lTўKO| >KOO3@_9S}xa;<$K>|ꕵ Uz|6-Hq&DR-fOL 9Ca>S3Ϩp n1Jު; 6R]?l;/M]{>8ϟ9g+j\ bu9\΅ny(ѪGUCw'eu>om -|p9t [p͐:ysy R'HZd$:3*|:#ַ ":䙫{&6o0q0|( K j|L}OԣվMTKQV[^rfYWZ ُ]qxua[3b'o* C_xIshT~ $dP\(-oV(BƦG5꽞TY;u?VZ۟?x엵hs|dwwAx737blNgkdXG(2wX@|b@ܶcZ3!28*ۍ?[}-1ClPa_vXπqzo+gPXm[Lyi=s~'[f[Elj_ykFylf~2W^kXʵMƞ ;/WR㬪|۾!Q>6 Z̒El!-N;;3R]qjS3zy6|lq^;laq`dOxz"6oJ>sEk{?2k+mΑ;||~ָ'[M2%d p >u簲ۆ͜#S[>}uOv)U{=ٿ9]Fr ӸFX_ce|-Au3PL^W'"Y2 l6.o2ބǛF8O~;%Z};Gs8p$r;zc{&T'츴39m gSජqucrȰښJ6V>#-d{\3  4jiS>tuU+Vɫ"'8<(~'|gFISvnFmwK5Y=*@injxvh+ۤnKjHmOkGz'R ?]}><iSܢ'3;?S VgkƞVW0?wFWd<?1xUȟF=涛>{Hh5ϥ*YN^ϱ۩u}2F?.T]zA*N:+,mTR sENU5U3%K[ICDsX%U +wݏw{gkG 5DXFD|^Rkk[u"2,^yoa׋;>~; Gb_U8 <Zu4/Zc=*Hꫤ[6xTKϜڪ;g&&AAģq8om?:4;sLHvŲ%?YWI*^Ν`LZI~ݵۖ.h}oS,ᙀvwc?nUS_T=_R<\z ~l!Xuba\k ?+);;X#y <À;~pVZB&im4N67'ܹvc >z)y4B8eLAI|FX6D|!]VEf>U6.4[JX[߶>Xtw!,>D)혎]UKK;UTzҸyzbguE-Es K&]QSƪ.EC OH"!S)ά$\ ҥ().P7ƵV2vfMc.@/5eZqL"[mK6|m^j!se/y̰3Z!]bH)/-=9j:4]e@q[SZ^v 28n7VE%fp0u1oGwD5Йv<#DYLx.RhwA{Dl}O$R(ɧ;h'HF!a,wCx6ߌrD#=q<@מi@tb|:MJu-X?loȯ>B ]g)gQCsh̹{Z'/P"䲯t>yM=]T&Y+U31u~&3%_GBςn/*`_6W D|=ED=8or=,sG;tӲDg"ScQʘ;Qu}RH g.Hf'wryxUbLPsvׄf-EsF1+$.Es`LGeBL跒/|ELnsM_\_xn?"q+AÜ4"g!sPx j/\##h󵀧4 }y[UQMd)gT疻<'N.‘®"iZ<#'cB36I tVEh` $]x9uv n+Na|-K[xZ2HdBևp3N>rs&{Ӓ]-*Z*]JN1@Sԣ= cO#U~5RY5[v1p710^8q5#ߣ)BҪJZ>'Qx/()D;/QlYrg|%kGV2Zw{߫62yREe>rw%*a\^0LEQC0 =DTѥ[ߐfȺNz6{"#AKzQh 0 (hD2HGm#[q!gݨ꠿Azz@/gj ]E6|f|4L+<$:c*%j6ڨ}d5I q #w(rEuIyJ}lϥDy#Oȁ}z"7z|*rĿDO#w)~?}˅>_\}ȏ>}:A]ڻr7h)(oU y$ `;{)F<"7o*rFL(hL*FbMi%rBkkn0 A-߶"$cvX[w{O| 1Eni/?iBϦ?xQ{[!þԏBOqؔrRgKy6"9pgR?o^$M;ʇ4Fy!͋ |)r#wQ ,B"?ko7jQ"I{)D"7F"Q#x4gߤ Jdv~D9'>/~{̏8 /+?Z(*YD痎GσO\ޯ}bg]dC/T{E9jRп%R~bgbX92"(~FW[RHkq]96oG8n':WROOd/B c~J^ܐτ_'oS~L 0bK)H?./H{nfhoh;~RG27RE֌9Lܙ0|i?O7Q{~39?9J1] WO1S3iH[OI(ZO"/[I$%l>`$Q%o)'k&w"GI#AE>x??>?5/ﳾ֥&auRߪ?%Do٨L}Gd7 Ӷ8-5J3[#Ai.3-Axg^(Rɿ!.oE] ooMZgA{^3Rȼs"؈R?hA2JE|g򮑩GoS?f$ 3wO/+*UR"YIղF}sפf]aR4g9x2~u"'T~+w@o&kDN)]/%!_J{}'R~Q'}+czt|Pާ)x\Ky7sɿ9׉=Rȳ}"G_dIEXޗ[oR3g"ss}"Tn̎;>UO~CsFokAZo Z{tSk#v{=GNHK4Wmc[֧ =]^ӿvPl;^l;(Ox9OBEHz1Yec4` ?sc@3t7;.k:/_KWTK_ pOweE59O%V`D!uՖ퐸+6c1 ZWj]H1U+Ljֱ=&H=~R.kBFiTnM=>mJ*iv^:[뭵6Cj=ֈ)zf=0Eu/d5gpNOs Sa | CnÇo[0l}6 U)3`hݨ|S Ng:$S2+1ۧY8/saܒ-oթ9'.a M~>*Vo'xG@5.P[+j-}aڶ!a, u 8w6)pDҹs \Ĭ\(cD$9'0.f>??s%6- lXhѢڇgN.]h}>u}|t!sr0XҨdyzK빢 1sbl`ϟ&3mgd.\ гMeœM!Иٻv.4MsÃInka9lm'_auQg69Ysakܽ]]_@ p }DhcIWdB1qE`KftJqjL;y[GK3g8M]sp٢Q4]輋w1>=>aPpbĔ]Bw .tN}؛(}<4'U6hn`7hߠMz9rW0!L̰hW`tXXH}^MyuS#& JFb~|ז+IU<3jIV 4s>9g^%L#d-8Gbޚ*TDOf26th95'3|F!, [u|؇DcEJ$C5s6yyM{=hφ\a~4p& ,.Qs_ߛXi,dc޳9!皼⅝m دM|NOKPZ)Fx#1G4֏42Fe;GKJTFjˊ]Z9sQ >oi13$(> {[W18)!6n=ا2Ɂ3(B &%:c >q/ϮFy$>;s܀c#ۍ)8}g%d".=8#LV2U>[g >*Oq\YWݍ2̠O>˫x:+aJg-֤jL Ina6OV|%(O]] _>l)Z[-pk);S6|ee:ؓ?.-%>ooS7S6a#%2b ;K>1\_FX䴟{C?c!fO_>v6h9Bi,MR%aO '@ޒ13s{] ֟}/VSs303w=BZ*須qi2U)GӬ U)9!I'`#= 3b ٛw\تWxLΜ|O3~p+͌2{x<~" νں4;*.8sz8tuT`$I.Xed k,P|E#̋һ̘54?Eйtjh4GYSG{Q<4*.,5gZ6*P5G 6|c8 T3kJoⳃ#xAU>oٓѬI:TQ6d!ѯ<ZgQU?=a:Dn]~/E|>mmxgYŠz.nCbu1\3@~Y2$:oO}]Y1$#iʇ>O.|嬨[dp&L)Cd0G)b W;fl ؆I[>UfoSvx]A^En}x~ oezǡ(uB&C0 ai.7}rdߘ\wMQM1>OLv.ƾp '~ܩFjr0i?ll|xpL#D89`:>S0 _xCYLwl,j0ƧܟPg8F%>C/,O }z(!}[؎Ù|IlfUjNt*w{lZ7kzHVj>Ss >=ȒmF%y^v&׶gwΝյ֜*_Kk-LL=@6xqN ll+׿uo&3# Fa,<{vMpB\~/֪5oZ3Ĩk1LTx?agÊ*|ڀi;/-r3߁qzv2PS3og$s˱Y'֖կˆ##G>e40bsJk&&>_3L6,V&T:Wd P_ǘ?%boH >q]35XOkɞ<)ttgg;SY/0^ZYq |X;;p(rJ"ߞ[$0oZ]ݟ299Q>G8INA٨ju$aL[{֞Ӵh*۠Hp9-awϝzK#|@S ڧ\G5͚WP>MD>~¨q_+YU~a|:zJр\Vȹ%NGg+~ 7~~N Yc!=#`l7 |z1}606|d 9SѪY@ #YZ FӖo}s%*Ay^5RL^'"I%3(2`g>t)NJ  kC~>rGdA~|gU"^O_1 5$f +s>gXqOVr]i4Iq5*"B$9o4yzBE+z}cgM4Rl>³=vgF?*S?mE#"gptPQgC8M-Q5N0q,C渧H7hPg6^x$^(Yda_ٴ1rxm̟[੒?ʝyBRaeM׵7,cj9#۟:0C ~AH:' oSxX14O$k QK}Pm@WuqGz =SMhG}fH%^țԶ$w-xx4t G73ARDnI4Rrxn;$w|H^.?(C[uKlOS*ϐd{@WkN[Kͤ04gmH@eVgY4~ uht*t)}֧;H$!3ҬObfxf'\=pgoϴ;~+-ri9o i2r l\|w1YWkK=lA#Hܝ?d]6vez*KH6Sќlj?-=b?Rvx:y>m?qEgtd(˖nǥ<7#⹧̟*O7Qqx=(g[-lt|/Y$H94=xL 󿨌(@7N[ȇwa ̙x/% EJ O>?{1\!\a!;dW_A'fD:}`}DY<q{߼}pm$hAAh}Z-˭]cg;-*xu׬VM_b4lM]N$EdQox!e9FDW|]Ǔ0߼#<6,{Z <Cvu 1ov觼_si}cM?eHWRHokA2:G9%LٞN3x%=4?> @J#ХonZIҽ{'.[ˎZ0\}g[`xZy{w:ϟsa}Krƻz5"IՌ*Wi>iX0|g*[Ih=ϥl(kd]> 5]Oân#.UV qe513=Ī,lb%w-{DGٰ4ѵ%u R>yHIomTs~rHg `IG ϓCE v^ >Z"alcU"h**Y9 <:K4/^2{x+[&x*ÝtIsb0 U<a3NB^Rc <,X-ؼ~}^A'Pҹ7 xkϟTy%;eH!& SMߦm-CG8x MgC.þ۵ b<(yH\Ϟy?q!yΛuAğuZIzcTZy*6OFF(SV:idA}C]h@K+ަ-8{5=x*U)*qB]_ z7~u%d\X ؠ4wRuNSG}]43ay "u)3PQm>n\GKڎYᒫ$Z@kϫU?A>i#7$;X'F$o*9J\U^JKֆكk)Q}ٗ9YfU1 GJ9a^Lv^IĭvI_M{-,ژ U Z|BĚ2 j(YdvÑsIXxZQ~wW?mj 4GG*Y;<8>cVu5:%1;z}Kt4fE#)Ԉah. 2Vk>hN9,t;wrG~/nux iqLN!i$5 v8="vv@zhpeD7ե{gֱ+#FȻ rz;»lv~7+OBxzD]CY!sWU G#W@ۺ i@yTۈJD"M#LrN4ՙg,|=;J)j' 뿏 X]b?-EIq\WIc?1|dYj0u1SNzD*]'OQhDe8E8GiFsZ;(f^(OWH xY{Y%S׈,* 0_|B&i=!*bVW4AX6Px R.宝q<8{-)MBpxU!^MBECrI./w$P+jQ<#<(1C'f45V9Y*40sg$J\Gqxqw[wB,%vV=gc+/OºKPQ׻r7=6as@m%KHWS Di鬫$\#^ JNjCDVqHw!ٳg(/7s yMVT){uk !CrىX!hxɮ"h hz:L2{ Z!ؾAIWg 4JFs4F6i4߃W?rEcbristol-0.60.11/bitmaps/digits/numeral.xpm.gz0000755000175000017500000000023011233572001016000 00000000000000eHnumeral.xpmRU*.I,LVHH,RR+M-J̉(ȍUUR26R"C%.%dT[V6wAW5A5b55xQ5jmmZk.bristol-0.60.11/bitmaps/digits/kbd_2.xpm.gz0000755000175000017500000001725611233572001015336 00000000000000ҺIkbd_2.xpm[yWb,#M$z%x9$!UOuϒ/N=n5;~Z6;{֬muSv{zhgRSs\?[ŒbNRV*W ,|RUyo4d{F"0?kX>qRoԽQ?z»Ї 's <_]?v"iiFs,ϻCD{OKxO%Z"?ZP,>󠿧f>I{- [Dg4?[A]x)@!߲oP aMWF޺}{#WH{T:{'ɽ뽌 q?K{#RWJuo O j'e< h.>랙}xN< /Z f0@G^ o|S2_D3J;J?fW^o8 *)oS?|g+ -"4_ԅOj([aU5yUӓv?tu?0|MW6{GۃGU oMO?g||yjBڿh~B^ǡ-/_~"oF?/t&G?9w=ޓ( o} C#"#Gec᩺ )7jw⟉Џ%DTU+ڞ#|T/F 節'r"i}Fo/yGsშ/t~"Y?"F=| En([K\[M52.xic{q5J"ASya?e=HGZ^kԓnڐ4)rAOj? _Cy>ϙXH|q(}[ĕ)iOHA5ċo=߹/c<bP_רTZ 䙖1$?0N5h|俶NK$_x:52_UګI"S9 ^xx?_k%?2^${?M»i+|gymb؇KUmђs]i _LrpoV JD4=[&:W;jhK L$zB@sA}KhtP CkLkDF%|8Dڇݵ}ӴNmk?Dh̘>7L!hW&7&I˒K+~Qov`UX?dEOMH~hM qMC[>)oj~(>JK"Ҕ)U$kX$1$~Xֆ Y򦗊%9%HmgtiĿ5{>L $3=$(OvmЮGK&LE;D@g^YSjtd Frfo힝d}fZӑo|QBs2ꁾmd3zmM u~׊xl{H:|XoX M; xZ?(&8B/Gsn6#矦Ik/Ǔ^%klEj(c}Pg{"ï=x.wD_#3ngRVw;k^\oYglX!3צHGaXEFm7/Rjٚ%cD=UBT$sb+{JMO[gߥa=$%!ڰEj1MaDYU2٢OUH[pjvJ(ҘUHArnjDD|ՋQ^[V/_3sh-kK9B9z @۷w2SI<22MU %gÞ̾o՘:P֔`= y+x'$]m'G` 'Mxv`* ۙO/xunݱT>Z-sm+Ax >i))OwN|p|o`gJu¸vq>hJp bԭ?x殈'w@B-w+:ꌝ!)#4gYPE1QPP' }No{Ord۱Ckڒ|B{*nZ,gд3<{V'댰TƓ 7Xbg:x3>~f7_XCx|}dQ+J^oSZ*T.d iduգ'< ii">{Z c烮vrTI3.2GϭYӥ^.$[uʸFw|Q$W|GG|Us<SFr=+Mvsm]$4 ,9x),Z8]ߘ,6EX秾fc- 긼`}ݚYu:W3oS'G}v?+T8DhwG1p e)+d5T<};" Oq=Uy 3^V,`P3JM:u]jĵ 'mq jM~7B1l^}o=9'E|`NO>T*ŴD9)#<Ӥcc(-mMLHB7cPI%_K/W&}Bo~?Į*mrQ#{dP&utyrfCmdfVxϦzmi.o{],o}^)2&4&s:nV#> LSi*W<R:3iE>W>}}bGr^*u|犲[E{gp-hsyWIj:>[ գ<^KVGr|:WIKzn,-?sF|"b? b9?&.kˤs6@ }0/:@u0?ߌU.h2C<L<&~2< ۜN! 9Gsu+h5z+6Q>yϑzaI/Vpln;ow_Y΋b((ʊSxrLz <di)ʝuU1ۋ 緮zoc `Ou rr|-ózx.;9댎~;8~鱾pL>(Fq;e\ 1q-gp㈚ 5uln~"}]{?Rg:Yo|f%@`J(|omi9kҊZ%<*ǓOGoStxg;6ۇA\j<g UAT6[l'GkoIxN]Sc K7 T6_~nt xfG0O2si6S_\D.b˵:fv4V9yo=o a U JS]yfXQΉX?/I"~/ '٠^ڟJ3/4h#3x3yBvm5WMfp`,_[ Av =G}]NeǴ@x&n+~_X;f9e"Id@uc?I/Xˊ$>!g^ǭm;d a3ߧIG4Ζ34NF[D+kAq=`T;IpuusY2|hqT|?u`Geo]O6}f@/`⬹n N~>{-cl pr:W%7} =oyo0;<A5z#UcaDq\c !>Y{5 '3^Saϖ@gG'}#yofU'}ٝz%F^Z)qꙮg*w@>}hC:/{m[bX\{<8gWOA<Zzm'&>gls!vQ]$Uw\̸WdӱzU;-l, \ǣv,쾎 IfcLm%μqO8:wbbи`Do06x̹;Ш'k?myB<$6k煤rnS>h 7b߽! Wh:vc ҹ1\p%t˜Zx?7g֟cN|qw{eڨix cgo[4#b%G|NJi{aGg\bîSֲGmY:,Z`CZكZ}[Br2] [jy\ c>3~_#o,0̥\ζ$ɓb#E4+DJHiћ'׀m\qg#K gc{R H5\JX5fGx k܉l̢} [jm"c3BJ$yLDxIO9a9̌X054y6_Ό{s92-xF#Km9%}N}1>n"ƭq j Ym M3&뵝'TP&zED)uSK͞+؆/= ̳Nj|ԕI/kG:lzޥR5}T5IvѬoOzjQ>;"!k[q.%06FUlݯn9wcgҎOrF#NO٢2j}pdu>b%`T;jGd@ter}2v]29TvQJ{Qq6gU {]A ||*hTVhHy5f_X 1rk)3%w IM9Ne35 _I+ 5l>1吣.KD h䜳'g޻}eVNΧ1: #;}T,-jEAͅ4-ݜA!S)WT)3F]E&iF, ZCM_)y痬lS&>G[a;Հ>g-V^*&=[L+ l[?Z/n\pFkte8K?ԶS>׶2Ch5mTn0Q&]v-g%#nS\i|dmhƇq/Jx}ZjfQntBg.8z9=ӹDWH#q?i&6ky# hCqZr]㞵 Ѿ facZ9ŖY5UKZ4g޸ʴWC9yBpuaW@YS{ SFXh)efCcoe >%=I.ϛ!gd4@Boܪ .xNcu04O )PF=vĊ{$G|F\DLiWU&xNC >ſǪx=}?޾oEcbristol-0.60.11/bitmaps/digits/kbd_3.xpm.gz0000755000175000017500000002040611233572001015326 00000000000000ҺIkbd_3.xpmZSI_Ѭ(BI1G}ꊮJ ܷ2k"62F'˻q>zv|vll93߻ß;φ7`F3st;{'x7e]MZ> t"?cv 3O;x{a彾#'=?|~S2?mN,3"wݞz_E>q>q#>y(yċ݀eEnz?d<ț|O/f q/W$܈yOȅ}|d\ Ѓ_ .7QxI@"oxx>ƷGmȷ#A8Y?w|CNj>MwDiO֋B?{߁I8qWܰ#Od LESa7c?=Z< iz!J0>$t#T,? xry /8G̀~|YMOy>buCO]E9AK?"N_>%z)}}ƞ_yϵgq_ak륑䧾쟒|CAy|^`tjdo/wD/NDkVD_"}>/Xߦ7r[ƞm#|M{YB2O]YQ" j4L?~"| ֻc0 }Wwe(=%sF~V$+_KU+{ ޢd$-y様?%YCi𩛹; ,L]w37Va~sFy/țߪd~ ߥg^ _Ȳ EݢzQ=ؿ/xyA>WI y=y~C4GQǁ<)\ >, o^yvd @|naqW_W74'E!|RH|ğd ;/BO/ S {&|HEsE!q'؋ʮOm ԟDC3ʄr):/Z"}t*$n+:қD }&~3ҿo{Co@1 aФ^tFId AKO$?.BeD Rt dtEO(UOͪh謤KQ34g>j9P>Յ!Aډ0j5cDCCkFtMUcPwh=;zM?՗K5ѕspgZQZZףgƬDjB/AOѭy̨9pvyMq2%j6CPjF!hYmuj3ӆV E7&FɸSG&3Jh$9\IY ·T|'4s|q~MXɴ;%J_ ꄈX5UG=W-:!!ލ<2.KGDŽ|(s@Try'z?!鎉.(bz0${cʀ/53 'FY+3z`5zHHˏj)F,RܼwiBU\ ݍQ *MI!bgXS왔|쿟QJ2?@DVZx x[W?s~TG"C!Apcd\RڰKVrhxP50lUyYǿZu::3:I 3-^4Gc$HˊtZ#Ԡx2xXEirV.sGgKo{@ԩq0 " io)d?Ӗ6*ZI<dddۃxXc-li>6,rJ͢zk#(̼jbZ[jñVTQ OM4ɒkzfrA_h|J{RJb}c%}ʏ!<l>qt7:+2CVNsH~WVED\,dŬ=;U#>٤jA/I X)C꤅g^r6o;@?GX\s[)Cg(Mjdޫ@?Vn]-Tߎ#A2&4D.yg5Ek@wv5#Z#XiQLx>sGùՔ?k5P_=ьwm7?"<'I(sHx 4Y{0iģuWq&Y瑳q_ӹ&qj,7(Ý#W  ZR ~ ͦC 38 4_sQ.1}! ])t 8vPf)oe-<3 'x٢~՜j-5r}W_ZhV`o&扫q͙/ 9.r> ē9!1ip63sJԱrJqN"i,SD=/0)UUhP%OK<'g3lv4NS0cUF;7:ljZw&'r~ЩUW=NVYCT&:|@g[@ѵn <5<ͤ, GֹqΤ vP=q~ m'6!Igδ9iP^X{WSS֟I3[/v}m uێ͡R qrb5gn:R~;m_<}aQ=JsI 9Jp~[Cd6<7SL= )k&>Nkو}ӏ6u.iV#{\CT7K|2ӥ:It<ݵePc5 Mx)O Ѝ/RGWGMv;[;,OR"[  ΑSFOe~9!v}] 7kۏ`\>\O(WqvPz7Ozc-Uv,g%nG;sė"ty8lX {Nзos7g\g۲{Fz<+9ωno)r:g9ܞϩx7C,C={+sGx,'3@40x.㒆}v'ێQzdZGI~Սԙ-tJ~8Ux"+}9mVY2oB28gke?sTig[}OuM~L]yD}vxosNi{!ssS]G0;#<&5u6FBN霯+UgkxZxؖ+?rnoyiF Ӳl1ǟnOu':ByH*>u+tC-SM=ϵŅiU5޿.滠-iO4k@]%~ԥlkx;Jz7׍ < Yc hVtޛ^BAlrEya捶y *N%Xe⑜Ж Q;'5>G#_/x?<%y50=9/3 4kUюS '1z==q`=N⽗}_r[PsO)7  i ƺ?}Na{L!kmo'gr39G3)S< c?hߖ8sgy:/̫D:)}t M0{ڈ?fZUx?]Qy{ 5G{3qZJ v;?j)k"5 g[-ttKx_RAlccVbJL5sv%u;/,[nl+;}]y!Ψk7qb.uy`/A+~s4/B/ulouQRKw_׺;Sz[ϯ[ڿHh/Y_A@EGHvDܐ$۷gzL8ԙ<몮GSM̧WSvG`'Mx&nM cx5nEuW_Ý`-ۣ>U<zYͧ9w"'O}ǭ'ϟ9Gg@֍Q u/*: iގh`댼 4?O%}?*趮K4U_'vF@k\Y? ;1!I뷴7kL^$mϐOfU7u 3_;{!VsTomVn0~I'|ɟd9nUIV( G4 9 XpcfF_?=>gF {)zr[ƈJx[,?GUAC䭫o_ʰ& d!W*j.# >G7ҊhH)Vx>re\0+q< 1#%{-#(o$Οj}-2n8C߀e?B&^9 ?پ ;`x$: h-[u#hVO֣{?e#W2+J)%=Ef.}XFTW#r-_XTـ"~7t g%0K:zVTLͧӣ>2͋MW+za@; Wtf^:k -w#}^+&E*tHy)Wh̟8wѲ1˴W&n(kh隖W: ͻs4Ml圾9e8 #C٩:qlok3gLr4ǫ8KVKebZ+m;|W1{vH@mSzn>YP٤oTh:KkMϽ C{!h)`{x,w4bfLKE O5RwJgZiObr\ quҥ^rQzS>k?3ssijN9@t+}g!/gʍK:% {侌#%gEIw%4#gQ} ϼq)͢ 1.޸cGH4!'kL6| 9?2ĕt}g`~7{x8\jf+\M1ꔘ6eS˓h\!k"lȲ։y#FLzpg: Qakyik~7aE)cɿ7GduV&&%.+gorEtɜ(ivbX\46OńxI$?bt2_`~6#2z(d܏8f<8abUcK{8!< yswupuf#i z 9߱Y8DIgigQ#jkrT<dzF~WO oR;_5[p5;g~C#z57o7sho<֏[XO>Ⳉ8e8z? ֻUW߭Gp!4}Z7 p;8=FC>w?>h߀m5~#viFUp q>À&S is9}y@γI_C vԔO18G5c!5cǚ|'M@QSx!O8CMH)B{6gi=}H4{3CFGȇ} M^l!vfh]G&!{*do\!?O}X?Ⱦ#MzK:&{|'߶]Oy@1?#˟ _%'e}7(Ncٞ[ GGrOS}W!īF7sȇ:|hr}Q~Oui·g{)?mFno2,+sqc^SF3ׯ5//=_gCG{#O;$~G4N0~M߸gx^w'\}ִRԿqs[ogh{ `;?= Kհ\|&7KSh =œؽ~gyx9͋|?}&0^`?NO.q/|;/ C^߄9nT^ wh~DFFl/oC_6/ 1Y5yR }n2O b7>7GYOh,od}u+G7Hϳo?cG{\>y~|x~z!>F1Μ 3w=wiHo ˶z1Twn8q|{l/}|8|>!O? /wlHs?Eָ6}!? sB\% 5Zq[~nU9~a|ZMRoƶ~Mo)C<1n}|I>3x~q%?oGENi? 7ⷈ8 ܿ<~笗˸/+]|;篐Og 7\}IzO$#[/>8}~8vN\.13%IH_(^CA%H'~7G$GʯAI7hi38'M#Se}1(/oUkߒ˘Y1ϻ)+7<th_iKߦF}T߻^$7y9@{B!S~v|oS œS_կ3̧:9揫 ˯Kw+g%{}eFC-/TmR>/;^e1&&sĀ=Yhg r՘Tڀp^PCG=UY(-rojD Zo4zPmQ9ԓzT9 ybFԙ\kUBD*i3gN_QErzjSmmu'vԮ"zO3S@#uNԩ̀s۩` 8SB]+unԭȹfyZ3u~_SUL5l,7ESO4ugꝚRG;w5k9{3Fhk(,'СcbԢZR_je]eVW]ًnʑ1^Sjs;gY~3l&Lټ53Ȟ3d̐h];1=݉l3h6̰X5fep|ui6̘Y3guwvy|6 f,/]oĜfŬ滱ݫg\Ω2rAI+丝QsM;g]l_`䰜Tb\Ỵ,\%yCG>jm{սYe٩OA!G帼Wkֶk?G@ X&2]k[9sM%[߀+Ўܕ?ܗkm{8H5O9g\t՟R^ky+D9iWŝ_O:[?[J%'0bristol-0.60.11/bitmaps/digits/kbd_fn.xpm.gz0000755000175000017500000002273211233572001015573 00000000000000ѺIkbd_fn.xpm\iWK<+6Bv^I%?="`6OĽY%9o8-oUS?_S~w`*8=8ݽ=l 3+)+AgW'k#x.r]O\q[b gl |^.T BE/?_ڞB;_)4K-m/qgbPoTM|<^)qU o]q oWJ>q햴SWC>c$\ Vb֫׀WֿkVa;*[[BWslYEgv_ӬoW @>Zl8Vk8^˼^Z+62۫l' ѿu?`|7l|uZzvVb|D[z۪c~J J5\-Z{gUb ۥZU.jgZҟ:3:DhRFS7zVq_37_QfY/ױ 횚5gkԓΟgYo%/uў`U/Ձ%ۅzc;1Wcv}qKucu,=i:kn 6~<7Byb O*_tׯۢ1W 'q%Um<qBݎK \?ע>Ź/Mte"<W+5 5]Q1Glפ{vF?6ynԸ[hy~|1A6i6yfk7sϏwOI3|S\(7o6%_O߈휘_?D;n6 oEy =s7ۉf9)7[Mwy _ Mo/ngݿE~x$&G_M4gǒ@?j V j?o8v7F +?}EvtmFaBڻ[`X'F6c(}yp"΂NP*PTU_u_1fH[l}Ww,*z֑`fWV6Kg4ghTzOphtTW@X6=qlNu#;iȻl7H}k W׳N+8{f`^`9ڈfM{<"iD(VtF?B!՝=h%~&c: |tE?.VuЪl)JhU>rdQz^g|rxN$vt X/b&|Ϋ7K6AHh)5r Ew80^$;#gѫpWh>C+Q3A(C {B Vfwp(V7 Q=bA,p,x?"{@֒E|'yx}ZREЊ\U4!:7/w+`&ϼq}&(K'x:ѹxNi nEy O"ųKy[%-âw[-OlxN Ϧ8D6DۚE -|o%D7Ǧ=3/yD`I{f4 gP"\L`X:޾hj_h 4ķڃkó*xTks"el-FZ3L|zQ Xg>*G;v,*G>4*$1oijE?ovFPmu=# {4> R~G6p6N kП3':)}bȢ|Ct|N-bm+x)z<;OKM-2qG0~G}B0ywgŞM\s\gX(:<ʟ;YNDtGY;cZJܾѹ\cgUcVp $O-v)x/Llܼ`ӹ1{ S8 ilvf+!nwn4^F=AY+05_YE{8 Rֵ9GGd~Enu0p}G"s?'VOtYiY](ƌẒaPvÿócx O tirxc!qI\6m[ w $MM9Ō4jƥ)]s[iVib^Xy'Σz9w3 i-~ .1,4?eGl1ۨsj'E11`$M}$i,#a|0)>z(~( nY |x<ڣmOs#91z9Qy?jxJV0;z\juk$Y-xjKުn.u v Ds#x۬fK7hsQC{Ifay\=T2De=a<Ќ;/"~vd`VTޏmƥz<Ѥ3ܬ'v=EDe1*㚵[}~=ꃒ)t3KӼQjw{e"ѵYӅ=(ّu,bX\dSGJ@!`@H5i0xvug'dqh{U8Xz30w-#*]xg4vKÓ؃Mx'\IxGׄfk7謀u}_Yd *~w>N8G{z;<]rAJnOO,JlEőUܬ?;}euѮ^W-zc%jzU؂u9xJ6_G~=xҹ[gl;ewofg{۠ȟc̟jOx'[[Dވ <|nf]|@D" mmJz~%ghsχ|;:?i fG^(}cDy0]?=Jux||3<%?=׿1mϧgxn,cPzHDy FaЭ_󅾭ܡ/Z'3t AlVqHN0]@/TS<Wɢy/nPC'zH-]4s>Va Q R70D:0m4-C}VʏpzZU5_H룜Gm91I{⁎9XCPy; (s)>=|;f~/p ύlOUl[FY6ɕύC,os , {0(kRx&_( 0Cgf3i'X VLjXGE<9ݛ s3OF7=Ts?-{{wRlc>,GpCZ:2tGwJ4}$rHE{EIg u+#j?[sk*Rz!ۊDF2J~C_jYCnײ|U"]aRz<7 Kb=tffʿ?R+^o;H}˂>9<܂; UOݪ=pxLP;"4T,Y;ct&t>s甯o+xCoUXnp bC`srij\NbOgleZE$>i+ o:H]!ޝ T__H ѱAU1k_83߈F^Z.ƯWM}`ZsߡNEh>B79fCruK#b6] fsݧ#9mtzx[vV Pߩ'MSbx*xKKь7ڙ oobS<\ Ap>^XS%a \;gatTl*Nװ7P(ģw}sӌm&!P2w/ΉR<e3 9/a6g[O$qy^vz=M=D&3oLbևxڂfQd)R{1*TsM?-WLF05ѯLoПu[;#FW[p_ @s(heӟFGr"gĜU#|JK>DnQʵo~d=&T<]Dl37]Ӷ4ͅp%f,G߷FNOZ԰r_!RN\YԖ_A˛IW #A^sBD% FwI }?۵%xwnjF,CHCZCk{͏j|62@См^ yRh:{d@J^kl9wxTE?8'a,y a$cE,oս鐙MߌveoGGM#=kV{QщP#SfUa?N7x}757lO0cbristol-0.60.11/bitmaps/digits/redled8offsource.xpm.gz0000755000175000017500000000105711233572001017610 00000000000000eHredled8offsource.xpm]K@k+M?HNI[!"SdYV\.Ao8#3Mqs})ύ f6~}a==__~ﷻ͟_?i&nI\a|zb5"ԘG\PZ@l%Ę0G;ALRNx") "NI"vOKB>'7%vxG`En$y[P/%F<D|/:oAv߈L+Xb&=;2H? Y7^ҍ}w|MCCͻ~`=ƻ~#= }|ۅBy>t; zy뭙o:^wF]nn2N0Amyua!^=cNj gyԃ<#wz{>a}{a7{0OH@,p?abyxAc1˟a:e&D4LĿyxM18 Cț0qCփe|' b𹙟w"gb BEy0f}y#{󽰈7KAI1|J/h8%9xS%Y?wQb,;w[0k/0!|SW4;E_sW!'"b'Ǵ0E_>.w|{<1syx@K-{U_I؍93|wbH<M)ΗIBFl~I>]g>)˳a37Xm>0hI>aޣ1,c7{1ﱾ$!߾w`9iIOߒaAwޘ|{L&n'%$97&^^OxSC oB ^MWB#c|7G '+/O0$I!2??y7 Y~|n.뭘oƛdy{ux<]/ ^>C]rQw$}Cg䋘$|q?z7ˣc "G|g9m OsmECm) 7/ gǣ- .Y3-z߾W?`}D$StY#^/.y\}9!*F93'91ɡOi OX<21g}3_&z$d }lzn_[~?S&.sIL h>g'[K^_EҟBeI|="i>Z_U@O5^KRߊi&vJ~ا% _NJ1}Jk^"Οm{#_6h֤g/ô`?hqgB| =WҠl]q=c9#)>[N$rպzR3(wN=}b3Ld|>z:'25DHޛ]/[Cx' -=ՃT v׾&߹62bIk|IҘ'4@Ck@Zs5 3$ ;s"}|T$:wCQI H`UM>ѐh4n?=PI1FԷ{@TR GYKUz)v{(Bq)c(-1=s.W*z`D~F$T-}"DzH17oVEuM(<>=h^mDH@@XUs!ek=╝aM4gvA2EA alwC:Q }z*Кi*?|' zdd' Z QזZ.JT;_-LdQ'NFGHwiTM5c%x}\n-%R{>h.?сQl3^v_+2"FMNustnωWeZ[֮)_,n@/W1Y{^T}Ht;}TI?bP^j/Ul${u'uXH+5;͎/!6h[EWV`ܡ^H=6kxݳEgt̝hk$gy]ڰM;%%5rF4D:^$yL.<#JjҼ[B݌iW}٠5e hTԳZ>HnňCc\QN:x-]pao}t߽Qs/mi_]}X.ׁGģVxe~;(u qK_ORdScS6)3+TO۵eQL(Wr֞'<]C7ؑzjQCO(nR~ 4VxtTJ><>u<9EG^wL#[a{Q 4E}OZtmfU> #@\BF%63ءgҽ5cdmUt]#n3oݵ^XPn:ȝn2m =!<<&i37?>gt^}K<|Dٚ;k Ols:![t=گ1*4%t3)n돏l13g|`sK7 wKdG;(Lyܿw?m}sJ5~6qop]#xqy2R}tw3(g΀grWSgM" <*mڤ<4o]ݵAge i &XڷwS vɤ? Y<]3@ȓ} ӢBUm 68~mWwtQR÷9l#-k՚ dwsU4Uϣ<{g.R5lSYmH׷@mμ9u=vC]n2d:.5=x& ){w1伂HM&@F3z"wIly}..:_SsۆњACxN?X%t7xS?y>NLgqٸ.x_!:k6Gǵ{+])1ts@ڰg-0>2s 6kdk_VSuZ{7iKt?C̴/B~| x".ątPwݬu+J?S.;ܻ8eElBOhA;|%W4}}}~g[1m๏s%y.Gq'!%e5jS9-㿿W!ܿ=<8,m\.x%~)=,[)ֹO]پVu(xjxV!oN M=fLg{ZN>"ߴ'Oߙ<#t{I?;~-kԬ:fh܁\LAmLx>IqX7c#M:/|'9r>'=0]O=G/[x_RϺ2uIgv3?m)co3DsցhPOz·"D"w>|n{~dS&bfeJ½V(2Mݟr=4io-[#:~ 95r{)r 2W/󻟺/L[ JWs󌇫x%y8Եe??̂lxx5b埶_OX5 Om9A\%b/MEkc氊E?z.]J@:Ѯ1xBy%,/Vu& m0ڵU@ZRfN?i<'TE ByާZe)-zm{a ʡ$N̙N3^Bos^{E0A,wMO_AuG;pvg* 5io^i.S}zte8C_*| AìX{sj=Hxt xu~}{P,ߐ+Y/`_S\p>ӎQ| ol RǬn&}$~[#T4 Mt^ L?B3Bas8eRt^GԦw19D ka“{Nrҁf}<'>~MBԣM4Pb~\L10ܬ)&ف&κ~F2a>xߢq++ˮbf 47$C@ʑ!HL'n,sf$/Rw<  Xz5`x6ڸXkNН2g@hxn'Q) PQ :TD]Np:<|wOE J3}cFx)ᩣ[f DhmC2zg&*]O=Y:XYJܷըz_3趧3&<#p2U<{iK9L8R$t\{q8J/a40|C3kW3G\Sh?C> N?nѭ#;thX^5^a%t6K's5V=S1=3s(b΍QImb!ᩨvV8;sԌh?mK"CIML^Y=h^:~s EJTM`ysRtYܩ?f>>ۗ}ȀZJPwhPZ4⯁\|r! .䣁u(wd|wZq!e|4Т&~cZ9Z\~Na  h<7Tl1Ms`u>eȬ^; 㣁,4gfMbristol-0.60.11/bitmaps/digits/Down.xpm.gz0000755000175000017500000000047011233572001015252 00000000000000eHDown.xpmAK0W|4wHV$T)EЃ@AMQi=z{˖>$o:t}uAzndž io秛[2!')\>pk1`~x@xsPkh'LU i/w_8I#;[GH{%GVYlB}4ssŷ!GA9}Z3ĐƃpW9KkwM<_j#x p*^%ۀQ臰"طUjwW=ƕ23W{e,!JC'xތ?y]=y]/HKYÜ^/O|8ǣhoU=sLƓX?n} 󿰞|>47gqxq8?ֻEx uu!k78vh~pꭕmyOXn~FI2o`=UܿS/uAb-ڛ?JXaʏA~A q|PS%|Yd\O_e{0_~khSP?8?"iR Qٞ( '-#{Ѿ7ޟ o U~"c|_|/r}! GöO ׫\EsY qյ~F(~ szsˮ>X QE쳽5?57_;'Àc#?~7uGG'П.ȗ_t~fNo~c|\|p7Gc 5_z_@ s)\/s=IC#Znn;nQ}t.׹J_m 7ϲ2Ai%)7(7փz"sp\]P|x:0pePQ=n#vw0ܼv^{hO|ȗgȐ1s;\gΐ/> q6؏xK7؞k*Ͽ7\?4!sOp~U W@oz>$Po5CnpDPb4mؠƣ{(A0ܼ=MwB\N8'_>G|0Ԉ 3;._,c]\Zbq?Uz]J7[u6vIO$)c p=W}g/_.ׅ|/O$7I߿%/%߈窤x~}9:?Q<8%[Zi1kb#b hO.xW,zMqԶ3ObߒuZg}@󼽉ےWd6۽/AK%qY=>Z yG~E=!)sw)^%Ư}S -滋/> Z^ȩ\FH*DjWI~1YKg VOzEX}b@,9(ģE B+WQ$"ĺsSlmG]'?8GX/9ĹJ\/8s[q'EYTD˳?7#c6JqńS◘(|1+ļXݰSs\,,Y;ׄMJ-un6t.+Aأ_^v^.ZE~zEֽS<6>=`ڿxk9~ҏׁ=[%Xu#,gU:Ӟ^zSo7FtmG]˹ܰy>Dڳ\>B_6٥ѷzO{]1gAtEWuMuH!C}1Q/ 8Гzrjsym&Xkp5;PeԮ}ҺC|S k.4)u9k팵gd9֣URģ֋#֛֫Cֻ]o8ld.TLORϯ܎v66 >lSjfifd*Yկ5ߜ:Ԓ9sR-r>[U?ܱ:Ԟn[Nj9ԀZVk೷2xRWT zgQ%qLyj]݈ Tr湔'UԾ:POʼճUW67jV`^tSsfͅiF?[_kscn͝7eTlBNUS3]4T7 s}|\Lm!CEץ!,th{3lI>>˹jKn}> !gU}r>>إΛ蛟OCșOrT){Ϧ!)r_*"xBΏ9?)Y0E6~BΏf9OC9GOeli9̸0f2OCsΘY3g͂Y4KwMCTFHH)[e4mrVi-KGٿkb] ʷ*Ϝ5. CvkPlZdח6毻sY+,X5e씫ONX}[ugq= },w}X+]bz 5V BHD{oo?iI3܈{Euϕ=2?}T#\\]mݵs5η66ӣe57*$RQC6VLt l G5 MQ(p,xp"xp xq!x ,x?#\<@yy]Gĕf))%G\KY)+2D༔xDwW GB *Dĩ[D<>ǩ H_%Q !7ˑ 8cI'f,pϗz3¥q!,!+bNy7ȿe0(&$(UKo!Ea6鏒f浼V]µxOpKy="?f Jz_$3>zoU4Cw5 \5~OYYc~{d_/N[W͵?NI_y%X@Z 9o_o3}?Qy~ L~|4EW<@=-ҹ(50?' 7co`~o?M|v|߃8z ?8)È﨡x8Pp?/Mh?ߓeeB??B磟PI=b 81?+c2> got9ٛd/8GxNgA`<6 kE$r-7J?;ڕz __ۡzD$Dɟ b/ 4s0\lύK5p1W%{_~`{/_o wx+3N9)#3=_ !W̱>&>K|f>WƳ.Y9-ߒ?cH5E7ٯK=[5zRRq WI _q鉿I_,:O#F:CI^"M O~8Y]ߚ1=p}s ܿi"x?8W'~C`H_ >D8j?B/~bW\_?BqLe$bO-Aؓd߈rg5Oߤ:=_m󠙢-?+WXۤϿ>'<# ѿO"x~(X~f8|p?]#ې~'y]ߖ)QW 㬚!o\oo,5Fx/y$+"ڿY~g~]sGO~X'.b A8(cJ|"|F: '_dOIߒ|r}nKH}]~Gi(xhQ}9F\'t)= qA=|KeY5aPkOWX?-sb!'"T%||j)j6H_ʛHp1Q$J|R-S@oVS췏S-g)07_Y]39cP~~ȼ癿>H7';?zA#wIoon-F(F—ݚgż^|0HMqTg QġKoq$O4s.đ?xD^s?w5oUߒ|/Z4}'KeUJK^S=7O?/nW<<_4Gרߋd³*UU^wa5&R}j@uGu_eFTZUoԘZj#sB=_*PeH"w%*UUI27ԦRjG=kϝCuՉ:m+L uԵi#z~;UQUUkjjRMu~JSeO2\մQԬ泚,ҜUͫ'a!'kQ}SLSLZFnczͨA$Lz͸6f >3묝QfZ׀yỵ7fŌ~'wTd.7f," 3WweMY̚JMfrS2kflW4[f]g͢:0Ov ;4G؜SsfΝWeZh.̥2NmEZ1槹3{bfTgKniޚI3Uj9ޙWʹqy q铙5͜bh?Y0aCS ዋ룫00!2'\FaF5 0}}pV~w.:LgjY,0hZhꌋG.̀kdnHικYp*1's 2(C^A B9`2_ Vݘ5X S۰ yc {paU2)d\\ w$sIO Tuh@^Ǟ݊س[i[)x|i'O,??A7\f |yXYf0-q ΦY1Qptnb4ڎ;k}Zukm7ً>lG}vΛt1.n)v3b}c_ps=0feOL'+6e\\Mlj;d}ε̈́cea7mHݵk../d.?7=uT\{vÁ=spd} ±{bS{f?ۅ;Jk̺UscoO{g+j|Q^-rnm6[;ipw:8}oo>qӎʄsNK2[wYp nOvs.lQu2Tͭ R'3q,^H$r*%'sUdyG$X|.xXEvƺuc%Q:***$E&œ}ʤu_ _W;ofۧ~Q|4UhVk?(=nݣ{ZSd¾6\?ױ|&tI >=Ix b%=Tu.Y]QIv[g7y;Znkѝf&} ׫޷7fFMx!C1KAwStY:e=\RNt3;HIu7uo=*sKoto@h_C}O2]=S}u{MNZV{͍?}5-{Q w:l﫾_zԈ۾?||oWIG0bristol-0.60.11/bitmaps/digits/kbd_ld.xpm.gz0000755000175000017500000002142411233572001015564 00000000000000ѺIkbd_ld.xpmZ{WO1,& zk ꪫPBD峿UOUL=?ꄤ5tUWWWgqy3Y>q权[.o76-_-wZO]#3Fn4wo5͜۞4;O 7M lY30?o ۞5 旄/ڞ|+j[!wUNGƿ#a;9i:0?!|)ZMu|ꗊB/E4,"'ao*|F>B^WE߮/dU/j _Dq](BCᓨ#$??WڟQ;O<7, ?τOBx'oK/տ,z|%)Iވ ՟agxGDE*ۈDybt(&?SQ*O EqgF׼? ߎHco $ io~~zK97" }>"{xC혏M{靎Ϣ{{Kv=/J|\؏0oE1{ISnsѯ _'|,L"&i8|x7?̧/|'b ODP'}0^d1!yHۢ_;v\> $xҾrEo;_yρ)?-τf[;i ?M?8Mg]I"DhM㭩$[,bC[Rx>sXR_{"|xTomdž''K/?VK[/J.ko{`x5S{c/E<$q_:?y"|#kIh2_we<<?''OiH1΢ y%|3Kğ7wG-򑕟g)aKS{O7/ C߷:e2^;e<^Z§CQd, I~џ/yC@Yڏx?aE_R(U8E"~E!I "/"($~|Bi V)0@SjxT/; y:Ÿ|3;^"Eڟ=17B[g {4hO=.BoiX|WTk+|*M{6{s}?"IgK>$gS>sY=sJAeN~NK7#-YBM]u<w <4Do+sYW +y ɧ &MwM&A?m;yNcx7%uoϼDMR Lz :!pm6{f`N̗1zz))f}oNhU)3}c&%dBZ0]A&)%,yba9y =0fLIs׼3+fl3h0Zvn{n^[nfэZJM߃PmY6mf;L%F&ioOLV zizL(0;f_Y˜= ~#R+&?OۅbxY;D}G\v٪GՌYsܹ֜ by# ۧK+Y6ڼ%&:"&!" &9@mNN%?sxrĥmU*7meE>wD Oir^`L!IK1}ǟ.kT+{C^-CKFtMxMd&)zGAQ`Y.0JT w$xT8f6v0!L-M@%+y웙ƅU݅}/kN!Hv;fu\vo ŜeDO$`T<'vLWfK :lo{=p:Sck~fD+%kjPy$hx<1A]/cP}tJ%,sBGOh#&M5WGM&Xh'Ƿ8InwSN'$v ƳxzM[J#Cx.Ox$>-,>ŷu4V*1kB sYX,P6hT9ZcOs\羮<7fv V{st^okx6G ryz; O u2gZs3Uk:Ūt $Kyt" <',>e> <ZEԶxl|h}I}={>g&YJ=%$MچCĂ ({ܣ dZӟoWVۯ$,P&Bh& hM}rw5oilc,Se'eVj3=/ZBv#}9*ӨnMxza'}sOVf$q܁>;j<`܌oUkW_Kd#%S2 K'}sV#+HN=iJXynNsy)ň_KTUe258̖23j|8pQ' 6kP~xy|T~w] 4vT^ӊxAx>>"X($iY;%D>7~5{~'!vC? W~:鷨)煗[h_Q5(sCϗN|Gz+3 Qx~qN73pc3DxY7k5DqFW<;9iǘwʮbj^nDhsƪ2ֺVqb)3De~m:IET T$ ѱS:ybkR}VuĪM|'5e~JyFZ5L$CX-EUzOO=3gŹΡӥӰϴ/pYZ᪟Q÷lJ%Ϻ֭WWzcoxNG=䞑tʙq&@4Oknw{͈~{.jEdT'}89B~ؐ0*rc%5_)}ygNyGh>^A6UM_q >ѵoWe|;ugSF4c+|^ >=>zt&Ź }xFm3~>OyAnJ;(7[EķꞧX- ꔌD-{{Jg&^#r,xJ7 n6f-DG#]u<|crj6 gE=A1R<T{H$'SAz+Ȩ+EfcQ[BeanqM㕫ķ+[qxzxA'x䁋z6p Ww_@gtv ŃC3E?ڹs+WԪ+y.C~q'tP9P4ժXj]{ mEsυK h8}ӳ2{;Ռk}Zb|,~ױ<3zw&[eZP,: .D0@j *< |zUFS䍓KƝ>x5xl=>&<O6!{G6e`>,_M=o;mcﱌgkIcONx SeCTG,@Tsc5EoP@m]hwƳYko[-UָoGO l繈oJHE0,ʹd06 l!qK#۳a`oYեqldB^gVӡ<xO|~$x;p>1< Ϫ)ľ 5(?GA '{}Gߩь""&櫳vb^YaDxVyF?{+x&ұwQ 繝>4V]d *az%c̯sI<[Ο獿y7څ|2Q<ɈQ `?CNgC4H+|;+ NV)e=tL {<VuVgڃI?O>A'EFV=pWk['N|'kM4-Es;5{xZ 3zH 7͵ǝk{FWWOd\PeXg2%M @?(̈mb<>Y?RAt1X?M4ho-?w?( Ϭ>YUSi=x%EoO&K8WRNOkkCqodx*K t<э[o?}GΘ"s#ۢG8oWKexVɱҍd0?~\G>*~~4?=K<8(>i/OB˜sj(beoՎʎWR I.y!h?hE&[QTOʯ۳3DUad<'wƁD[hoǓt2VKw(/D[ڱg>EA/œUI?K GcT0ZNwv|V&ו@ܥ7޴:u!xI~ӽg5=8 vf+'*9d|Bc)x$%ԃߛ~ZI6ub͡I/h JgK+֘*GOx)c >_<疕cA wE<6.a_0wQ4A+aWF ?p_kg: D3&2#W~ A`t:h]kQ%iT *OxgvMhPYcW_Mz71=oLhN 9gN"<٭/ o627}xjzV3|piNVeBLFBS` *g|h1cjZҿhss͎S4Ƭb|hASa6cѴ`Y-?'fLt6Y{!fK|P_+oz 9<%gXS759iy~Y ?ϴ;Am ܋ C>[æ`~kW/2Q`7Er'9A ՆFɳ̼B۰=Ԣw+~݈hMME;\ Js#s"^*G&DKsjo;N<c,9 5hR*k/UrBMvp-ZszɵsvqXUX򖻑.Nmj리qvܕgȯq ʱa_Cd[Ρ,_^rIJ,+r&[|}U^K"7|MezDӓb>t9午=p[Zxfgd6)+jc6%Dz;7qd@W_Ҭc"l::m7H GS2v^F8.?~9}tOL?2"jHv޾vܪFf^<]dẍ,f;<DSV/;~9Yѩl"Qj ^TFy(!Z7%r-:n''Ae;b6q޺Q6W={s&p Sc,ۖwmS0 mʺmjeNfy&s1Df¸G8"Bt. h[=%K'F%ӥzqTу՜{?*ZiLQ62WYqrFENiU[;Eb&D]>KW4}u sts";7Ea>yYl){L^"z槱)fwP.Qfg\'?.6tf۬xg*?H;Y{>]p.]]^ߎoz?*zeej|knX/Vn>N*s6T#ecosw*ʊߺ=jF qb&㋮\kӕ){tDD>#'kfq/ :S7O9G->}%s/ou<*g"H>sU_|ϏfV<ߖTL9k"ɶXݹk =Oi#;7}e1o44MA~Ϣ9}P|"_":c?0xZlq Е@UyUyiW,~?EE +':K/y,ŪqJSelxM7ى0 V83E`*nʝhwjb:Mj&ys_Icbristol-0.60.11/bitmaps/digits/display.xpm.gz0000755000175000017500000000050411233572001016006 00000000000000Hdisplay.xpmVM 0 =_m: A<M(ȨP guӋ$ $i:^Y8SAX pl Y*Fi]<G֠@߅fKHm#%zІ28@XKǁ'3Q)Z|(-jhnd#T*g&O@{Se^4B@O=YS0QrA>hQxo*T0M|`Ɂy:(c$~B$`wȁbristol-0.60.11/bitmaps/digits/kbd_d.xpm.gz0000755000175000017500000002306511233572001015413 00000000000000ѺIkbd_d.xpm}|{[Z \Աc腶 vC|f{^DMkHޮs~sw΂ݽ66?Ao~x_HZ6??|Frkϛ8~|:>kd?:eZC'v"zj)ձ|=TGFU~|9_O@>kήj ͸+I x|zsvfN~|#k=7E_ED{/YgxۭF_4;o[׹?mM ڧIyV |-ﴲڷݖ\AOK}ǔ/)vؿhm\6fgϝ_O|ў^- !u[q pD^k F y!iglx: TCS^IyLN& w|{h_ocщ{-ƍ/ߊ{1oi}\o/g7c ?k$/8_w{ "/"_#Cҥ=>,&w&$H yq1|(d1d>|2/~yJIBygy~WG{q~3 "O:w^3I׍7NY(<m n?/O6|O#ʓΓ綠So|i=䋤j|iǷcboPrE_KcK;ijkv>]_4&磽_~mi/\4'iJ:^|-!|& ( ;Óe],?˲F}uqO('gȃ} 8O!ol(~n |![y=&?s$l>Os4fɷ£y< I"y^GMy{׊۫zy=[!/\e\?Bq. } u^^ +9qp2Vi6]TҚ?~6zY wZWcw9) ]B F=Br֥\bi7i*_Av<΃/Bw{|jK%̊ %4-\ r yp,ͨWBњ%'ŭFԊvh%XL+h_v1V&8΃Aߧ@i:7lD(wsi *JpIhAH"=Z1Z͚e#ѩ7Vy^y0 3QIODݖ3nQZiK?Wz@HE<7RDaImmYh>L_/2Ν)ڏY!pl M :,C_ ˡ#a2"w٨/~K DzM2%H ~eC>/b\A~P:)AS b墍i5` ΄Ĥx| x) <_!c~Q^ײ0d[G}3<R+-QRϊ@l E Fnר!jPkzCyxP=)V:{UDDSVKܾwR*}>hOg߇8GaB)m67:UGs0*w+xxq^d=,xoC-V2bŐ@BxSQj&4E>Ȟ5~oh@;CQW[еؙCC| S$^x?#R,gBdPmaj. "+8oǰE ԧMGO@gݴ1ӹ:Q+.>vυަmcO2B_"}CH 9ՁFLST;SF1["Yf푗q'|myf/KЛH D:cDȶY '#[(aQB,H No5 !" Q$m>urϞ5<xdz$6bQfݢ'"3B䪇Q3Z K-!\6BD֗2ڸHE= (I FёƟ_bo+"=#[[hMg|9D 4!ߴ)Z^*w 8X Vp'`;@k(&FuMġ#͌:MzeD՞ratձd><4G h5$m d0+>Eߡ!tsOvVcNnɄ4"~N-k#pbkSO2N?si}Gusςy"=m5_-.(8 nT"j R\ O**(!+xkMgCDwB/!x"AwFYya8Jh[Փ:F3jvשedqօ#맕3,b0!6hz%~uW,~ Ei\Z>CyrơYєxK_G:>*PhDgD?]BCۯPGrxn|]exn޳Lᅴ|z<^?ynTLW~ u,&Tǣư#{o{j"v5?px_@E AcnzlC7.W|dI.C(AvkiAC\A?o+x,$E6wCY%n϶@Cγ5OVc2ZT0zat "K_}&^+*#P=duSVUj?@1צ렦s,= qZς+,x<a0\Z-Y#wgfzrF x *՝_ٶD>[{s rx)KG̔zM_?rv%7kR䡱wb_ChJk}ڌ6nv6064Lm͈-ަ/ެ?Vɀxj2Eny(B ."Y;6&lV6~:XGj{ z~Q_B6GcDzd79GEP<\`Khft ^O\g~UwI:|rnmtQA yۭUwl zÌks&+0{\z~ J_k0z*]D#ιܛ*/-d?6kr3Qg~%1x~E1m}dg6g9,n,*eHTX1{t.xX;P4|,.Wi6qgƬmbvgǼV}P rۤS׏'"ϖ1sc˾l%y"Xn}KVmz팓z{k7Su Y?4ku ?z@K"Qi--igԞ7ĺ딾kOöЂ7G˵OṢ wђ", r`Y לfĢ1*+r]apuWt0F~buᝐVǜZj(3cxó<(xt Ր9W:cxܺƤg6F?m]׹UJœۘ׊Ԏ {x i%# O/|c)ԫ_"_vj*RQ-\CŚNL?ZfPGc1朽9cQyRf2ȕUۀO ;qL[맋&u׆3ofjޭo~~oxn9~e~o0OiU656 aXf"Rf /Qolw~VxzCD6 ģrn $Wx]pэƢQE?w͙=@L<5&E?~"TwBǭ"+ܸ/w3t8P늾9q<Md<86|H?V7|ۭJ sU4 ˅z5V3yV )?cҒ5lj;@㢰ne}Qy8jgDzxPI*xUt}ije4}2:8]K$Ԉ8Gye1 X[]BKՃ7ȍ=7v+ҺyH~Mz Efsё/jKuuoUȵus#c\yU~b[[˨l3[㹾K:Dj:- }:#Tl0*WZUu%llPVY'~TqO2U8vWbjԨ^E<ē h]P)QhFӮA`W\ gɕUōCsc-㦭-o!-ijyaxrﻜŕہ_Wţt5&)ڱSgFe秿|c%?0WTEMoo \=G iqk^\}8{j,qUGQ_*"  ׈8zM< Vw+eIVєɮMjĵ칞BE$V?,MM{O/PWnPE֢/?놇1Dn }WΕS]!j *U3%s ;N7߰ɍJ=qD02#rYQ \zscFIW\ 5++#^L0FX } :C}F4Q}vaX3X~<\%l'ȭޡgi<}a`b,މ|M7@oˆg ´Qb)C3[5(om}˸:x>y5<ܓ0˯/hϼAɮ\Cʧeyj]=AsSX}@nz7@*iy<+| -5ζNjhd ++XSFli`옶}r&aV_nxj tߒǡ-3g6*b{t2"=f[z3 x.*VhfKھ7V ~dYPkO0T&8<|+*a"@6\Q\.~75__RֈryHTxs>ã" 7BjQUPi/zj38J[?_ew?t2^:=A瞚Y3x]ȜH6,YBwG_|m&JǧȯmٚEh[PnL |vUCZ6x oKp䡭ѧ|h*[8 uq%}}X33JU6eV-O\op;<-_P(=[w^zL_5wTo8u@=L/1#yc[ lm6< C)Lrx~g?p 2d=Z .w1 e sjh 4 t H;鷑;]q8*t-yƺ"74 M:F3YAXމVBe8rV QJ~`cDZ#EuI9Ō\ VkΠxz\xOēCR>Jx  GB.!I=7aUl~u'2$o͆(sIM(*͉@n~' 3{\](|㩡%r=/V"k< ӥkyo{K:~/u6,yΖ8 -!V<` *x<r\ZAtR!}"96}m- W=:Ζ̚ QL#'y [%1zr3{NL=Ȑl3gw_ҕ )۵rCԳ>V}Oયٜ3Z[м|J=˝(M*зB/PK(FD*̪_q覆'hƾ-A*v۸уDN& +s\c2zlZg}^KH|[h:1㽓cR292{~]^*2}5$M ٯ>-F o7rAy7ejнo<{/0攚qo`.sb%S,a OaVS++G 5ݺ> }R8Om+:^8/ze#Ӓxxnyg\|guqs(cEɬAo:gWf! }v kE^HG 1k Bk )2+XOCvm?+c{21?EiǿǾ]YLصQu`cvk ãc΁mEgA?h6n`{c|BxK; 'U[gB?׶t{UiS]]s'<0 y99ghӾ{ьЍcD)nL<'Mjzȓ^r7XޣDPW]jIT y$U\sos1lJ7c8coL{פwZ +Yk!}7߾M +?PMH*GK<5p?R>z\ ֗h7+^G]:cbristol-0.60.11/bitmaps/digits/kbd_s.xpm.gz0000755000175000017500000002200711233572001015425 00000000000000ѺIkbd_s.xpmZkWȲ|ϯAǶ$[BOLd2Ifdෟ]ZlNj9PVwzw߯79|qr3no}8?Kr N뗅8yuv'Ih6»%|JRŦo6f*o6៖s/~oFߊ[^)j7=_* ~AkhEΟ#xq3~Jߑo^ IZq-5)G~Qg^' 㹟zE9hq:?omOO\~Ʌo)m-g bv((ܯgk>v`ChHI@4OqY;|ur.v3("F;߾ʟu:A;GP_GuL<+aR(rC^':YBo(UYo<˒C{SQޯ~#Ow#88|q>ŏ7{Q3|*`*F͐N^O#O/kRCzH ?C?:~㟔#/c8 2;P5c!D6E}N+A3Tʷ$=OcE/0UF U[1 ~gsV8(Qzw|;n:V_[V_qK?$Q}=W8U}=y܊)gP 7 K2ǝӟou0nM)O8^*Y}ƈho t8Qʧ`^|'N#/*՞ cGsi,%}J|_ȧAȈW)$VV$CIGǏqX[$c)H?8ʕ;S(Ř\I+i$>'(i^I_Z}'U2Gy3(Mb{X)+$Oo&gZ#zGpW> /vW~߰8GFYKSǗ%$+ 4<^N>_`Ax<縷^%;a>|4H)^i'%t6Rr~'~?|)(yxq]yK4̉牫mV>2;jϧ:e7)O_Ty$fV>ΰ#ONFytQ۫=>xZ*O+oԗi9ӟ%[ >QE뇺H#]Cdz"Q{"Lb|ʷ|(/w߁{E*)hO*n0󷎧OW}NKy҂wf o}>*~W yb={>z%4g^tULK Ox|E_}g=HlGY1+|Q/TPzuSfнt_IIoO+|N휯Y ^@;X{ ɺg蜣4pH)VڡvVr_}^Ew/%}lU)w]H[tIRnAϬBGX1n Gita߶9]9G@oooHߠ/|Uo{ۺ- w}Uhy~7Ӱ)H}W}Z gΊY1s' h4m̉9sVݹ]mzFڮQ*h${c6y $ض)6ÓW然BǴA}K}h|)E^ӯw1GCxRSBYE9A5 :ƺ;UO S*@ )m1381=?G,X664j˗ifu'%qʫ=Wzنf޼q D-?SSt'f@]WCGI3T^aGc>nQn-y=hwC-*MsDڇ=Pi)f,oCS}=Szڨ[OO'^>%iCqH^7!g"4B(8#xLpaR LD1>B1BG}UֹvaQIاgT&}J ܿ;S#<:}NRkReW&ɀ2  ]5e@s7D3(g'wAf&3\*Cxk.X5O)Y7Xq]v?eWhQ}d<f >y|6OHLY%4vl)6[kFKLGib-Yx)Nd]+ ߹q>8ΙP-c}l،,7n?]Tw=e驷WTAn$Fb/na-?,9hY#Ύy3H~MfrF6f)~X󲜛Cd&\#SbVAk'OMhl?o8o:'@ޚ S:9g&[Ј͎RqI?Q9%][|tSgbÊK+w0*P dzCgQ>|g̻ҏJ,,Uٵt2_ %)pvl9uJц#JK?~&1yj(gL*o2 -=k#b\MD|zNDg-*aΞG̬>8MdZE)a@nhtwrW9a^孯;.FxK H{xz+;4AVxi ]Q7۪aտ>wue>[CЌ5:/ w#D/9#r۶3.` Gl&8AA>*;$zU}ӇA߂lx[ɡM(OzQ<{}ވ0 4؍1`g< K|[瘷BCb܋c+>kgwsfþ!;hRېyx;Գ ޣ ^aYgwisqKjut%ӭӦѮr $o|O?jwpH<"7nON'{9W,"kvR{-G]h4M#vyYZUx9a#zqB[ |Y[j |R )pk 9ݢn3y3en o'|oLVm=[ג.ܮG.Ig c0徰@)#hN5TJG8u/y cGxy w [|-mzSFϞj!^p eXd| bGz3ie}~>U<'<Ͻu:| $>o^yϸkoDM1-tFO>gLRA6ĵs4rͿدa_c<#hZoP#? 'J٨N vu|ѷozWl'_7s:"IfsWr޵>巇/ܿ/|S9l[zi'A||ݵoݛ /֯>ʾ_K]L\)AHќsR?o杳l-#Q3&4!A#VlFDhva{rmg:Q?:B$M:'}֢}_xNyVآ@xvNl`:;\5pQ)t@yשgnG#7AdہesE<7}{_OYY_@ 5P0w-,4Gm8%(yHns\g@ޟMp~.V瀈o4䯝+44՟uOS]yFO1$Ӿ~tzO/uh_+V߿d!ި$ъ ZjmTYG@&D۷<.*I8 V/xa ? }H Q=;;HR>?JwqנU"^ Q\͢mEqj+3<.lF9nKAuCYGܙ;Wbf{i0pO7T|}ER&VjdRSiG s𲟋> ϿxNo-Ϡl)VD-jq&A`O+_o6Y&dܩ Q}}j k۸'MFSNui:v,x|yf}.b{Os}F設xn21iC9ѹBx6Ni#CS/ W9* {xoڡGM^|=D{m?W7WCX7IeWf`T hvPVV<~a{Jx47OMJ9Ԓ]LkYcTJ "TA,:#b r<|a _(Esgz6Mg1xs,-HGh7e/3D6LVL+,εL>eS׆lk-9uA4EݚEJ=PbvW- ;s;$IBQBK{!+O%z|u-s/4x>8G4j+pO}>9I꡻Γ!7,Be3T֠Y #>:mZZ5Nތ|zϣ'K.Czj{uMgOPbmyrwKj>pWe:=*܂MmkՔSփu%tõM6𜔗1NKz x#Qt솲}I׶/WsDde»x}[e,C~GY^I EֹMbQ5)I=H<"m'D13uJuWnrF};i;ģ{"YF4z6p<fK׻*&ж԰5sbi/kCxQяtruVXDwAUdh(;L4p !ϑ~an;=c{F6j6%R8͆ :FF[ދP~o9E*vgNOP򻾑Я&I{9yGW9+$^-`ތ]p*C9Scx*CύD=i']}/:q hFseX-.tzn6rbɯT_m=AS1sJ)FrV1 RDݽEUbv ~bFdԊ@^I~S^=QrxQE< yڀ09D'm26lvSi 6cb6kQ~1l!WrACQ_CƿEֆNѦLf2Jh~" _[`W#$v]IBd,1MwS/_M?PxeW^>Dbѵ@-;7%v΃y4ǎ鈆rjDвDtθi, ?ZѪdN<n|4WJYw鶵Gu[zܟayL#w"r=O*[^Tge'xH%лzJ>Iljߥkx!,hY.7Kv/ ck+w>s9zgU"/0lcbristol-0.60.11/bitmaps/digits/kbd_c.xpm.gz0000755000175000017500000002304111233572001015404 00000000000000 ҺIkbd_c.xpm|iWJAD`[d,l&sBC"f0[wuK&w]2v[RwWuuUuӓʧ7`28Y^Wׂ?-T}Ujߩ7vapB'3ՙZryZ"rZ',7,7+83+JZk9R[9jyWI,-oT~Ε*rڬjjy3'P'K,'qˍZe}8~kv8ku7?nתl:ogYf-ϻuj#=gFhkjSe qUC>U^ߩW(ZVwjZMu_xr=kh_u;L7c:*kJ[mS&L1ﱾF=]V=kRF},q}z,'}IR>}J?fȵomVg˝b,7EhQکO=w2e~r}f=`}e9Vy>ߑY5M1뛑/k@,|?qF՗cA};g o%& ]lپkW`1yԷw}kxGCUm Vlg8Up}˭ xR~Kx}-?kVFN+nAo=YyY|I}XNt7Z'rVk},׳j?ŕ e9morg}L\oAm]{;lߝ頾kO:hUzlOiwYH݄x+5<ֺ,7>OX_[Sm)C.?.˥6x'rõ㓱gr7c5]}.ow!媔mӮ_宻_W{IJrԉO荔;%A':EmyɧN}#W[!T8L "sAdX0(S#Z.-PKD8%DcԔVh; zTo~GkA_z/u~> Ri &^{A :z7髍h6 ,lgx$ Tڵ.X6[S03i58|5 >⿖>ul+ SpzgMG/1{̾E8+|!p h*zR.]%Elu-zΙp#e飚{;CtQ::Nﷂ'W}RF=gNtl:@W^WnږPQ<Tӳ0 _  ߳S4~Fgwɼ?rT9MCaC6&~W`-:Ǥ7Y$8 O>qG-Kkg6\O Gzd͘iCD}U=rPFW`t>_oMD߉T+Z3)zv622: ]py@[&MIEJg *b z{ Fʦo㍷bF51茹M7.0i3pjJC$eP~k6| ^?y(QpC/36P m86> \8+/a-@Y=xi)hU>6 T0N tR؄}3Q[@'X]{?;<d2Zӄ37oD? Y>"? S'!viB 1fKh۬W̬|fCh|‡Vl.ut ɏZmg@:dF>c*csS3|7Y (@XGzsX Ko@vqߎWyN/MH1 ea+H LWؘriOK,VA>ªlKOA,6 ) -X&C߷LR{gR]Ffʧ>qŚ)1XLm^z}qc 4LJe{kh֍ٚIa+&,ј<(;aSkƤ#%rX{ ƜLY.p|YI5nq/n7ݔjqP`Z4#?C_'.0r3439[z=@dulquSZ_~'ٵ׷6G#<.;j+ `2ƨ.< eC` O CW =PLw{Dd3,J Mx˪Hc{y<2Q7 9mSF[ύp|*KFLQ܂#>MÙ L-; D{sd L:A۶4qJmABjn,%r6v'3xAϔo?`_ʨVO"3o';k:Fm=QD{ bo r>%Dog2g) `8F)2 ,{[GѬ{ ZtBf3(pz+&Sй/Ly6]],I>j =s>n{2G"LSѧM)5"gM(G^2px0f>\>YbX)#|-I,WR.M>w4/\?s"]3.v(Z@#m^ #ΨB )j٨јyA !1`}Sm?to\ѯHGj<|m;=ђZɃ6af hܭj Q)9|J |?E-s E&>4ܔ6}CSXz[=7}Lz6cMnh4icŧʧipOsϺ-m? %@ZЩ.ϸ<݈،cCF'ͧ?+GdvrdQ>jb30:cSJMgP蛦ROѾe QUk[&5i8F k:>ȼmSpPT)zFt)޿O|~a,ϜaQO|Σtg\4vkMwSY& ^d,֍`$9+l?Anh8[Cjf"ܞY6nh&mzFscfu>ab["]lꚲQ}?dvӾDY1:ĪOu^1.[6ԆQv%؄57dkmsPKlj[ :[гy֯CG0Wh 6h|<켴lG02 6<V!*B43;S|Χ5k}?m{"O5FhF@62e e<х3a {x]:4㹍b|chDl~QΥseKQ6?ſ[g6#8g[rY0b?}FB|llː*u9kC?Y8/mF OKriğ@<>ygC(|a`r]:2~h\>J wF% _3^PFf~3hPU"^=Da4^Ѷ,[] ?C!l bsf8DǸaNƢ9쯈U,+"{hF?VŰN6'=1XK1uqVE.NQ..e]|a +>H r EXHV:zbvS28>/-`V^܁O,OuFt;ԭ/F0~§<:-הfV1ix,ZA,8ʈG.Ӷf:i~ZAh񜮅|)i 7~z‡g`)e4"BTEg2=ylͺ׵ /m*Cgft} xw6?MOn8Ze4"!}/9a9 ~›U6lzgǏۑ3y(>F7G3N!--tܜ:k{I닇#.>ܿagUl 6'x(||>{>V 3fҡ^)quga\q\Hygݲί}? l.CFeڃXzV{t5Ӷ.d9Z܂V UXw|o@;E<swȇ-3_5ʷit OCw`Um!iu,rFSsmջ<[:4Ux[p6n { wb\>omAq>}O3yեH}XLssV|, -ozv!8>OoǞωAEk.%޷uq bpknvua]s۸`A}[|3t вN},x6Œ댱(l*.wQ~ޝInKCzcB*yO,E8~q}{')6=]}D2v~@l\9rr#}Y}s)R*lBI~3m%!1q؇mL6lT/kA1:{~$uqƿjٖlnҎ:sCl% !u?лywWYn ն=a;a԰]wyrZ[iq޼B D6œO>0QFȏ.82KfZu8rbޘsq^Ϧ§X?}@>Itկt0,#6QշؽCϗQf{_9>nξ[qfxVO<"qSyo4?jFGmCĭ|r}K®e Rz(ȌR(h[]? 2|;?|^9|ڍ!1;qc=\n4.׹x'{ȧRX;zb kIsTu"ǭbQg]zlks7'v|.l'#mx֟L"G+Ƕ.A=pطy2r{J#V7WLle|4?c`Yќ,v|w{2d>:cl~PLe> |l&t! _ZWAN=H-x?lCs]mx 9g{EGF SfJ1>gj#/>-ȇNe7:>܃B td3t8"\B2‰<+ڏ!;?:0K]5TGu+ _ K^>;6q;I޿Jj||`^{_|^aTlrJ<xf ?ƣG!?=Q(f=U+2p諞Q3<{7/>_|Hv^x;/(K{ظ.}[/puaAܛO;vf[7>[xm|}|-ؓ-.+X՗ Vr .[ַO׺~WGN@WQ ]x>_m=mKdQf,nkid*YƚE@%Dx)v'~߹+gPӐ|>٪os5v'igxң؁c&ַ1;e s>6^SGĐSGS}z|Dot58©za,w^ 02]ϯ!_ j9s1Pwa D>ð 8H5?yf$E*C>'Էm=|*^d5.86!|ƿbG6cH N|^G{fm'%Ə>wz`ujS$422 65Ȏg yKӺN 흴g|dyil u;?aQW_+~{e?C>Cȳˣ=˓״y?efqv $嗈}qܳ|Na^x[s}NS ~FWT2:'{֗WI=ħx!` B6q+|%as &砲ͧ?.,Ru20ϱo3=1|>@k>>"{2l_ p mZ 2b 6)oy0>=2Z6rʌU~:ߕ>>ʨ/UD琂O f~էqCRf Ltcدx_|ib߹纚'~?ulgv_ رDV\u{4>L>:v8}B++gQ?We} ƶyn(G_:i,ۚkVĞ R-ۺ?^GxUseOSk/MG_l+x|#pOYľ{C ;b$8:nAE!Qۣ G^p, jjz*-G a/;N\>ugNW_38=zM5ەvY|ތa PF2 N9[;8ez3Ɗkg^}\ .E[{s+{>4;os[uFN}}i}RtPh kO6Q|AjsĮU/k}>:wݠ `kuN]ȴWp791e|l!==gW?QZC̰jށmG[XlM2o|#56#=֐/Ȝ|]`9j%#Yy|zt|  &ӕӰ#[yuymhR^l=~q@QD[iEغr Y-w߲q6vc`vs9qw2XmwG8GT:1jWa9/Լ>*7.GVw] ;luzW5ؼ%aC/~ϣ31n@F0rJg`mU>rkߧruPՅTƼWfI/`;M\gsV'wڊe~i"z¸8nGPtGFUy`wgOk9/DgUwVmv]Fmr+_}8WB7TJչxa}ƾӞVЖ,^26V/.uL6#Oaٴ=蝜Eҳ&eh3NnfivF[Kc}U+ +&N{UQ|_BsʛpLp\=6ܡfEV]D΁Ď2(ҝc- APО)KUSGFNrOyɕu<p0f~?cbristol-0.60.11/bitmaps/digits/kbd_down.xpm.gz0000755000175000017500000002301411233572001016131 00000000000000ҺIkbd_down.xpmu\w[} q D\eK<`@bggΙ]$7cWeNٕٙ /o_ 7;`$xo/+)Kq-(m))3[!j)4_%J[YJTT+uW+jKyk+8!oUeUe|E:P)DV'[r=?q]jQ/U3jZNT'N篻kc< v|\+ڛ5郯֫I"ۛN\U~7cAwߪ68Ɲ߮Ώw흸e^Q+V X'xU.^kqW'_KxvܤSWN|*l`{[ځ'jD~|>mwɗOV]'I܊q]w= >oU+S<\+ݿZG:c#Zj ZwZ ;v'5|Vgr=ZJS֠wd0:ԏ&'ho-ߨ &zB|]r?ӬOy8 ɻ֩zKok ߕ/Wk{e_k7^i1*S/qcM!DxoǗ-1[r?K7POx|MOm'4hx~+ΰʹHJZzW~7IlO+fH>r&>ѿE'2Vl$m7lo'W})x{)=M?W$*oPjzqJM>N)'m+My|/@N߮lf[bW~ߔg[<_‘ǿѨ߮_;{Sow~?0ᐼ\=25|-k/RqJ-Amm~nh_^x&[%Fp<~i).f{hS:^]|%;bIGbӨJ#mO.;^&x_Kxlp;koM{*r|>l7pwŵw[k @[:U{j.H}LAW#ߕvo׿޷mɀx]ʭ/j;ۛ7S16^6/_&/ZW'nmȟ>tJs.\6kb"\Z:%iN }mw"_jw6x9;S&orr>&BWќCh??GiQ#ܙ+9|Ĩ +V˫m_]xD#qj w,lGr::͇^J4 h5zQ}|C^Q4uiճߏ L4s=)%T:(p.jDQ%}| #荐 :B۱oHKR 9z=RѭV*u!9,w B|BϢ}i %W|e{]TMgEKդBυy'v <od;H"lt\EQ?FhbUF"\%>Lnm -wq w#X^Wx,W+]04e!мd>&#URh6Wѫ) 焜-z+kt _xS6πpC8jBuyG86Fj>.S6i=U44*@SGAFi>+2|Y MsJfmF}CS0^?MNx/#ёړͧ`!ϡqw=3q6G=A%X^ C*Cl͠M˖ 6}Ʒ,е#f˼\PFk*F*)rhf<ʦFѨ1ޕ O"hrhh7?KVf,ß^aˇn%(l;)qXL/VK4\, *cIԺKDk1м:BߣbegDHꁖd"EGdYd /A|b?pvYxzGmĵGXH@ 1zGVp4A5dKod3͞c9[a9/ 2uӋ"z(S},1"2$ՌmD6fǣizM049/`7G784FuislB$˸ P@t35❂}e:W&#EGD˧k 2~l3YӴ׆dh.U6p+ZelDUz'EFu͡M}6|NnTwEq.yaxZ7/& %Ҭ^@fN0}Ь7m'Z4"B+EcH6D͌aFXGváq)Ms -=/lT,9/; S˗5k\W^TF\]tv/$@ff 2:l MNl3nn-шN3:Kbg]zѼ"lnjyD"3xuAdmf7B{@S*Tb:XVWmKDjy;3Ğ ԩ,ю`bF:hekpMmo*K,zv{+R^qj>|v?̠r5'b9_9BH^Fw|ɦ0^5}Eml#+Z缏{in멺sdS WC#U69' +MD6|m4ݻ V59TMkSo{Ik`XsdlϞ2pϨ@#{Z:jp}v2{4}̡Ci޲mR; " OB֬ftVآ SV .ws#gf6Y6]YtôTN0Z^`,;֬֩baЯ|ʔ[9w+inPաXmd|Sՠ.ODzܡyKCEmhW.A +S~3Aklӳ>} S5OF7:Q9J=LES:94 k1 VV"'7h&Wrtf+C{ТEfYlq42epuOOz[D"C/4'$gz- K2x4mەa)ީBM,#M`}|zuy!A]NFreU=} p5<@h♺p#雦 bpxCŪ4w=m24=Ӵ+&5Ӯ מGӞBOM٬lfCӼgShh7^Ǧc<'Yv)x<  ZiڡEVK9F%sh;QS&J&Z;GUQ>7Zԭ_#64_rSr\vSBG dUj'\_Wzob3盝e'gW ܍gdӳyhW>H> O1qNm=f $Fpau蟾5D8 $hrs4kCs<ٵIǭJĽRoX8McV5yN}lZ)ó,әMFchx1N<+^ΡrDeC9lizshܺfe~RHrz7{D̤+ ,SgrϮC;4ߔPՙG7̢m68y%wfȆ>(@wsl`ײv7oӎl[5i?Vy}Y晷2,54OJlW@g{XȴM7G>>0QJY6h@Oѭ)};m\AJjEtsubޙHmh4 9;ro V:@s ?!C3-^zM5MmQ6sNg._sV}EM֟Lo!*`~ wj !L}slr$ck6j7][1Z('r>,fӚ6c5uz'Sasc@ZXZ;2ֽ~_'Ueyu <5hi{>]a5u}57&=nVEjbyt {|,ߍ?%Ð_l\#"24\WKs衝uC~=1}ac3p2Y2sqNŞ]ҕ]D.ȯdq;n;bs*absL^.Yk;Il}>[s;bԑ;#OAϹDZ;>=͖q=3>:mKۡ9 6O  zo:|}r1w%^vǸr[#߲U~@ϰA|6 wp?f(:E6Jx |K!2/Q7*س{Z|~-m=+_=Ǻkr-Dٱ=ދ΂W-/Q!i)?/ZZC, I84ga:<mM3ҫnGRϼ%*M]i4 г] 5!BܮIP86<% E㢂)f !᱿96}[B3Oi]9C34دjùlAF#A:sr4o slhqlѷo"qį'u(M^mb`=0MbZ/y'842}wMs 2ˑF}#|vr}ylؔ_xE#/}>wR&=C<_1 6 ܫbƢ@s,Qյo{?@Oat;wSWCʹYeNBNN{F6ώLy`R<ǕV}<[7NrmĻ]12%~,kH}[9k%x,D|ĩ [V c߹+d|.1pRAl={4'Ek)f7A>3BzWqJ}dZ 6.+o}HI(X ɜ9sAabristol-0.60.11/bitmaps/digits/kbd_ud.xpm.gz0000755000175000017500000002374111233572001015601 00000000000000ѺIkbd_ud.xpm}}{[J)ִCVnnwk륨TDZZ3 > d2dYY3Is+ޗn~iGΊs~n޶<~P翎ZΧa  ])G~/r=~/k\_ "./BE/r)W|Rn|R E?CwڟB9DHaPWJꃠ ׿P.Qhϣ\_ B{#д .礽((oJ}5˫R_"K9 /'AGR_ R$bP)`}OAA%ܯWQ #)ü(4/FA%Dϰ(FMTx)\> wrѧq@+T~ ~E"໴+B>LKZX,#9Ÿ)aMe ksPUϽ7V"H})L"?U~2Z_,Olo_WK(*]r]P+CϏpR~Ry+E׶C1пr lx(?%T"? (2E250^K9EKTy"H{bR||"r9e|tC/&I}La|OHK9EHJGW}ᅰqU_e7R%#2qw߸^*c*?q,/=r+qq??&e)R_b|KU{^/ kr=V~.yB-I}# ^1 )Gq yy+W&eZ6jRBZ -|O~k}կrXbFC9\M31.K9;)eW!ZRWU\rBYꓤ(O^kT)GI1~/'oќ$(GRi()j/KDe" &~ ;V<`ixP \xkE9N/&o_:JDK-j:>VNo,㑘k_:lH}DGgSzV->;L2V9--zyG(]%"hmz^{TQ?Kƀξ'ZqW\GI}mynBh:^ ފwdCETwoΚtTNz wgߔ^SӺw@Է.iYm 4VG7]mzW^{^ooW)WNU8 Go>D_Yr ϱdj&lx)gM~1j&\y.#DW>z'1u|5}F>p_WIÿ^#sOM$}',OLj z MjI# !IАJc<'X_@|^>sO_-HTCW2WF!q HrnLg^"9#$9 !Kژx.[tyA6H]>St#uh+)6@ !Wbv 5=8RGު <{$e;NyC猼^ݻ{O(܈Jr온ͬR#t׉X3d%GjR93A.I\z,H2蚰4ݱ;!G)qos*T:uD4.&b1x DuzSLCTxG#1'e7jئ̻[^E$kǙ'=:S4~O mun XZ *Ϩg sgS\#m"ֶ MHb-(T $;`,EΎl:1y7@sO+߸@ (KDw)3D(Ƞy,Ѽ˺4!xu5}Ju|bOoBj'DX>B־z"4#thn3@qN@WctZ>¥Ѫ'%).5q6_;'TiT%]&Ϙ|pAE1(~3=[5AJs| q)>EbQ֬4![J`Sܐ7zlGZ3 ٠SDʗV?#o|DhN]V*V!J9Ъ HdZ3F3}V# E8u/H=INzXЎ>Tة"8/ 0",xm[4b| bbD9= dh٠@.-9ۅE7ق3vcfnCZvԛ sV7JSG0hS4Rf4U] +7U÷A#4%M)̢a$m==S>)msi]I;J,ڦR_m@]SG\x<lQt0qN3zgpdsx6`݊3xNԋF 3\zB¼;wz@c<&RWfi?{y#F*qgOb2$A;GONfZx6!q"oƟN@c{X4>W=a?$!o]-DYo))"E<[G9ĺ4Œ[<Ϯr5Oo1_&xsaw쒼5I%eD)Z1x:n6aBbGT#Jlo6w#y{R<wZĕVLW<}3x-:VᕞC1x n͹#v,Wl󑸳`Q9FtHx$n^x|a?&~+.I<*RȲλ%WpI{ԓJi7<Ɵ&!x8g\5˟>V<-9ay;#x#ٸ g۫Px.40I` p`۞'Sۆq&E3-O*oYZi+Ɋݦd.N^ 5<꺋n;$gDt˩@4[O1ħi\ fpLgXYK"sO-IϥJXsG8䂏~U)li:1_[3l.m5<ެOLm#R k㍁CcK֡yTQr6m޿غhN6}9g}ISfߴ32Ƕ34>0xmK}'j`7pyEt 4r:CD6?w@&+ N? g'{FX]U9#lL2S9?lP|XdۭڶMo x>Mx?ح][{vW9v؃.ɚDhīQdlf.ymuuVeisE=&HU[3ѡ~ l1;Dc,K22lgBY<3gsWob$: ^w)y?n ͎Nl)3O5.2mꫧ丼S?l?e y eXq]P ,o h- Y[{FpEvFEXw&3zJ^ь G|}8>a :VL銝og}QcS@:[pɇY-IύPg)AQT )Bg|^yO3)z5rYI؃ε $VIEǍ?|C&rI"%lu dLkCNifcغLkkO3xo|!4vB{ħnڈdj,t3#wuGnDm !GO3Uy} -K!}ط3'OxV ˳FZbQ sO"Hۿ&Ұ8Tؙ0xNwaZ},O̡]pM&Rp6m0<˪ɮa)C|i%,6 chX+[IzMc@,xFɿE#x|v6a=l/E^@&Dv< *PH?Hk@g[;Țo 3Wx){fҝ )z.g-"3ҕ._ف9D4=ۋ+k؟1\ctgv2v39FaΩ;gQm66Htzf>7؃|{o,C{E4ֿxN&xÿE;MP?7xt "^NlrOz}6~ݽ{3}pE\#{Xbs]v%O;%Fdں Bڐ61UBeıM^a>]_|/^k#cŗꑉ[{gkz,,bUw01{pd*nSA 0? lcQlUo9͏xϚݥguޖtjϕ{5Y1=җz9F♺鞗1e9]N׹v9y;d?PwtTژzjG Ald|~4_jIkN7ޤ [?c]N-6?(L oX8JNhJY<㶮6[b"iαs:Gţ beUV6z67p֑Ll_~cp#.Y$B&/o `bS]N`vرͶM41tm-E#=ke|yV:g<,%x6@4Ev'5]b3.Yv\EdGɮ&vAbdn-WG 7CvNoz&r';/1Nθ&SG<4c>e"?dZwS>ef)iqv]|43Q#{zg43xwq=L͡@hjߺ յdv {Yob7΍&"λGD"{ʛjNjz91iړ5f졒,Il&rcp2TkvIhA"Vک+n; Hy)ZǾ9 9Gym{U]f5ʡg.4tRhZG˼#A,_fsƊOxZγv2a}b}#Ϭy:A/C]gp?cFA#)xCA߷=WDe5f)u3Ϋ{!qF0"Fl11\l1 ,ԣ#mK|3:zw8z>:&G[` <-Ϧ"լwV~ҽBW+BUe@,aGY>@+H\ IO#/h-3]xoNK{x2;dtn SF,^D}i[-.'@Q-=|@Bދ#o a$fg4tsƾ~0 ifڋzӁ,);j2u<ᛩ %FC^kSP-T uIDᾊ|2 te$guCѣ<.WjdQuňFxH Wcy#&؁E$yKx'T<59 !+(]'g訞 # mH$:="9ZbTqCmH޽$xud[=qjS<{j< 4п+p,CCj+ Hz/<]G2^\ѢOdwdDVKn-Zل3s;"IprHhRz# 41EO[Z55a_ަ,gP=BS,wDfG'4 a>2ұb2xeiz8o`~W8oxhZ<;sJwmzP܂Fz<9_ jM+ǖ-1o˼A3WW gъD"gm[AџzJצߓ҅t`m|؎~FNjx yu Q䬨/ЌAYlCAm`^a[δ`ct43:/"Ji ׼$-PN}=hFGi$u MC^'曽* {޷a3wgeô {tzME%V⣯#}^,7sO͒{_ZzKa"V^]g =8t p=ɱ~Uz=^YB 7(sWmu)n%[J]B{k2uK{>a3y^cbristol-0.60.11/bitmaps/digits/Up.xpm.gz0000755000175000017500000000045611233572001014733 00000000000000eHUp.xpmJ@E+8PfWq#"R h}6qV̝EF.dGj[< zlfƻQL;5==bj\!N2@ <2Za ,Ex0A98C%hH|:$QZ :͐cY 81s.o1~Ke)Nݺ7']]_S{M뎳Oێz}֮woqJ>ktbristol-0.60.11/bitmaps/digits/redled1.xpm.gz0000755000175000017500000000621611233572001015667 00000000000000eHredled1.xpmXgS+KA;yfI5HƘl `~H&r)W0ݧOڭ 4 Vo! |zpȃ$Џ g?Y` B0S\Kp   _]P`7qP#E~DoOpx@p^x|/zMşD[}~U2FռZGO/ ȏJ|!\q%- (q`{8h"Ybgq"[S˄S?-qծSbOp-C^oEp= B6Vk+ߺ.7Qeً<׶?z_-_F(jS~}@˾m|yy[}6,UO9މөqKƻ|-RuMMsђ?ǽ\(S9_~^J< ;gyY<']|'q z}o~x'8~/-~zoz5_y|z]}",|7!-'͸U7"Ø-Adߌ8q3w돣Zh'oT|`\ DoA|}/K)\ϊ8jFR:<{I633WǿZ?^F[/v 1& $,_n?zX4Wl|cDӆؿַ՟1tcOZ~z~izWE_cTk_l~mj|Ο-ݏmT7_[!߱R-/oĬoq}>տEO}hIqzqH럨~*8j1\RxCS6k|^5i"J"Q@ٿ5YBSnwZ롈f4`JCη9滽?_iSUY[Y/I\/{گ,HZ(MHO2'2n6"YC=gq[{ON8?z"eAk\֋66V&d~?E)36?ηץDO-/|~+;];MqP\(ZFꕮKwniۗ j8ih=F}w_1e\ 42c N4=¸VE[oXxql|WO-s}:f}l{}lWS}o3Ňc$|n6klx7}z vo/aS5|^ DVKzwR딬SzgZ?o[ {߾Z?Z oz2~c,eydgymLfQԊx?oUN>^k,0|~53Qp-G\.qoSz?]Qyv {r>e\?zո/ _NBw(qr2/gK2P}D a?yݘ`}j"~e\?~aο-v7cl>#ɭZevUzG8ͭ'.zzxq0v4r?pK *O92,?\C!DӬ8H!*x_xV``X7H{l6|msy(yoI{;3b} (}|oAЄ+89Gag8ȟr3:^´;+bYΌ9ZX巟}7{X 58˓3;܊}&"̱ {qorNQ|qGqmY!|xK78 /g,"^9)ͻܤ 19+bUp*a5βq7q ݽW`7]}<ֵs/q!g_p?'SWyBnU6i`l48SLbAu):oF~Rc? -c9UEqCQXK >ʷzJktωӣ0SRy iYe캇sN9/|%|o-qpg2 cry;̂\tfЌ_w9M䉣f >3`K3w̥ю\i ̒d*,U=:v%3œ&4sb3Kw%W_]~TgV#1:"jڻaͬa62n 3]ʵ`|5ܘDtgAr.}}H]ͮI1r>oۜK{;߰o[s_L6[k%4l㑙©}M/liN(O Wr>eV񷩙ii5{fLgya^ZT5t3fֹr>)\sy{*c={.ΛW˺r>لn j;3Jq>[po|ͽc=gfߥ=sv\=wOmN?9;k{줯SyFz捹I_S-{`>3-켯){O<ϻ'ͥi_S`>D>y_SȟY] g'}Mk~r>ѽQceF0ocdּwqg}E~1Y_a~l; DyIݺΙ{5X;wΨyʨvۻ۴_ 8*/Fp(bristol-0.60.11/bitmaps/digits/3.xpm.gz0000755000175000017500000000050011233572001014477 00000000000000eH3.xpmՑMK0W6Cj]ju)Y?=wtEHQ)4}HgUgΊj}?nnޞSE+yNnQA?=b'jޣ5]+ajI O( w(,PxD9ve=ON=:!;6Dƺ4쉈iy5UұF?gȎL;_܄#mqeq2svT?N9rrwS)o>y WMgü%dfNMtJ]~p wsbristol-0.60.11/bitmaps/digits/redledoff.xpm.gz0000755000175000017500000000346711233572001016306 00000000000000eHredledoff.xpmkW8?/bҐ0ΕK8 ^^hi@!~4vذ7H)xb O^@._''W߿eepK5'ՁD?JOkM֮,I]|uYtuEtm^Ft^ѓ_b]]d]Pt뙒 ?c+ǫ|`]wnYysEW܊{FS֕1~Tf]3?&$42]֔4М'o3|-xz?hyˠsޢfmW[&oˬG 7:`m?"|6k kk֖2oE߬y(HTkFz>3ZxhGo=Ǽ>{h޷9mct5! Os*(fX"<ӊMAn:lBa6Omn\x%(CPV9ph1t$>gg |ozmIk?s?hmf.h{p } J@]oZh.d1z 4eXUXuЙAyz"jIDx `SjPoF\}ض-sxA?*737(>/Nu Sŷoh'w#E٣17Yע]CfgzĖ/Q.a)kg %)Ds h .PB fKy8g18Cq.f6)94)6HubDs1sOZn >n~&3\".R}̌v1s{fpIfƹyܻK?6#b&J &nq.f6`bzfKPeŎ_4df[p@]?t_cqX-T["z<`59{e2wo0QoklkʯgRwfAB YZw3ֻc]S V6l߱:xˁ 2})1v1}]'22j?3\a^P0 p] % s\a߶P0 p\)fn70JfO3>?3\$3?k0Jf2>?sXa03Jf2þ!_$U홏 %90wloK;wT홋 ӽQ>fV(w~nˆwuF6{5֌;}3[ׄȐyq53[ׄo[ vߺ&|U,L.bristol-0.60.11/bitmaps/digits/7.xpm.gz0000755000175000017500000000044311233572001014511 00000000000000eH7.xpmՒAk0W|h!YWŎFRFzh7c&}?!y%Q'C9lK*6$(yح֔ҏ#(ȿ|)}]hXt X9pc!p<1S<:@/0 8c9Ñ["/ Z193nv5,4:i55k b"t9)rS.[dݚ^Gtk=ZkN+(Ûvkq5ڱ+UzEsbristol-0.60.11/bitmaps/digits/kbd_ret.xpm.gz0000755000175000017500000002314211233572001015756 00000000000000ѺIkbd_ret.xpm|W9+7 iv+{d oUSR7{͹ԱZjբRIv0788~悳ho?X\6'_*g _yW&^dR6Х[c:g ~t)_5|-_Η4 \rf~%˚qmkz |7?WEoyom*T zkzFVhiz󞐖c3-+y|~:X曚gl0])XӍbZ`:_Pk%gq)_F=Zr ?0](蟜-5پU6˕z6G\Ѿ+wپl'~7~UyC> W\e}0x'ԇ?S~ Oo<Ab,ra?B_%"<""jx^2+HBZ*kP4Hw +feת*aZꯂ?Lң߬ aT- ]gnVUӵj yyB{_mWQ>kZ 0P~3ݪUx j*vYf EsG&>~.֊53]ӅZtV%GCye*Ꮝf >e]{U!Wjt 81~+5V_Tz~IS.!}kzګ<77k z֬y#k<:gB K7<X=_ ĵXVkߪ)7|y57(_hwL˗=HיG6d~^y-:ۮ_ukff |K{eȱmˍY5I7+Cv="wۨ,_l/ B~|d \dӈH6<ӥ/HKW7 iT)Qh)O!ҍlԿf/X- JBC\lӹFM0-xh" Gfa~YC{^ϺtO1]2Rii?[{kOykM ̳EI LWy޿tYl@~X7!k?so*LkndB{~VL1(ÞL>1v7X>n&ҭ|vmm]EZRRjwj 5@uO5W[F__jpw7Z/Kk!] ;B=(+*B3h-EFQI"tD+IӃЁ|ٷOB}OO)OzwK)S iI-ڌ> }9r8io\y}MGG4rB+>Z0 .-\Bk_k(s| 5=5{гw ^F{c]+i% ia D4GGoNK%j#8}: 1XzF(|W*AQ(r+y@  :n1hШ EEf>IP7ܵuI9[ȯ@ۻ_7_K^W^,(y 'Ftch>ΌDRѕ*ov^G( ICTp%>U\Fwѭ[ЪվT=2bmNrߝ^Ir|8 O܊=X+{Bi,Ǡ+-oxk;j8Zz-Wz" Uy7΅ߏ9?Sw1ݓM}/_D R]z.adT;ц`DBEDM=GCIFrh̊T|<rH O Xh Jzm"6K;+RKT2Z;PG,@lCs%hFe%m |m 5 M1)jn OfQtN>#5t ϒfL ѯt"O,#EVZ.LFhjrr~2Y&xڒ睴=5iJ~_sF; +&/j2F}r I YARE:r˷;4.ܺNV!#s| 5BQ!\y| mЖGC5|ʋߓ~ .SB9|- OrT'@SJV_4|(CnNס(Z酌'}87Y;hyyrxFMXke [Ę$1öбGh1МK SQ"<{ BGї'XhF/ނ*M~Oy8M|2izcDabI-T¹ pi(LGOi&EGD-QcH犴Z[=wEK8TbR/h5htBʟ@Y0? CKY9ٶSmRʷ1RL{MaT\]' #q :?+^xI>*m'sC?z%OJMLM?5Z1=@ _TgQ:"Y ˂|b+- hu|M~ɒrsC7M,i;F_d"NF@h$v {C(bBbFfFQswF?٘"Fp\}--zD1῁$xei? ^l] ސ`jgZtnFG8{طKib@0&m]\ b˂9;6_PbŜ#lԞ }n@߀a"2wyڃ{S~ޟ&v1YSި;YG:ݎT_۷Xh`#PP[2o!X44gA Y#=s/R455u;a`gtN+}S)y!EeJ4J9o{BLͪwm6Xȟ[Gľu4gAq6\ v{ݨ D-4^mƕəuY;ң,xq*x(ul9C&ϊٷZnl".0','<*0s;_#WVyT_x~QX8Yo;ys <D"bla?A7SӟFiϏ9cs>JMnWQ7s[[rf%s8Ӝ Hǟ2wg.3X7oF>cVaPET<*];֋y/K`ޅ9^cI%8I!"ŤW8{<:!([Y` |ugOd}lP># xm@4œ&S&#O", :&U9ԇ;\v Esx*!N3WbĎ}nE:O.D Q wbcgMd$U z#6v ϥN58[I-Sa*ņXfŊD`J^x<Z349O +q#ϝ}۱HOW5gvzRFw39F} 敆^ Q=bjH}MϢ]؃]9)uxJ6|i#Z7e#i  :AQS4cTx3<:}ۅaxXu(sX%Qs75jYykg+z<mԼbl4Ddcj}gxTu<;&mmwh+3ڀA԰o`R4Qpx1}c詏ʝ c;KM\c֣z1MGg?|~7Мt4[-7O C>b=gN=\4#k~مhl=yj goa,+m92'_6hޯc]AwI /p~Z1<#DuN?BQ*7fԠx3^o(u5$oRZ#ݗQ:{'%Y? 1?[|tFϜtQ/k񪆟 ^7)"z3z>1hQL}/Y%]d{6L"lYӘ1]!rpcvē=9]Ɲu\K N45< w!=V(ޫ'Q8FߏO3XcO`߈YOk5)6휳po9|q)p!g5* h7T|~93k1$;JbTz؁èhO—_#Cq=se[zª"Q[MV~8Dȡ)<A ;bNg??-!@&o0AdZg "W6kg0uI%W~4:2od95 G-'gφsi_ti$5MO =Gi`MEmH{hdDYta7&Mɭ >1[*m5U.s xHWK?pvsQLG u-sqU%x+ g t[396Y]<Ɵ_vbExv ^mJ<=o =ۣOv9gpP%ܺ$BZNٷ{z-GwԺq_՝y_hwj{t˽Iule!Ah:&8<Z{P {޿>7[5E['+ul+ A>]\".3Ulf\Y5[;=x UmwY9+3<6o n'Y<{M=qj׹ozI?HS\`!-aE3FYWR;!^we<v΋FT^Ss/xTkyD\6esY-h|ڎGqd9`w~"a&څ~Vq1myp: {DzX?'?[L؜]ytm>4XJ[ǫj܆SgsǗ踑IHv)?Xm\4 yk@8_P_crw09j=Wuk߀8N}"s NlC<*o%c>5RS S|!^+i=Y;nW39V}4{js(+4xƌEgb>bwHw@ ?J_&=0s!|ƪO%xVqy\=?z<{sU?l`A >0 mM{T&ܧ,3Ov,~)tll>O7l]]+ݻz}y~zFMw- ԷiyX.2Io-l=M~莗ohȈhv:mr:^?:VC{bn z)֬N#J|oȕJqC[3=/vwt?f 5d,S+΀Qƌi #- te_sSfWۺ?x{ݵ:,/qt!o}F ̓ 14+)iJ:ڑbvA*;Mp <%ePƞ;m;?7tOţL5x9z~MņT'̤p{Nxto4Ϟǣ\ߵC{@:Fښ֬`IRo΍K),}nI։GM;`޼e[_gpZ7m͵yԢMDyt';ξ7)/TSV̆h|D&?hW8?_bP&rw[M.̪9>*ʡ/8kom.on8ܾ/Ӿmc ?"R8&Ƭ{¢w3,V1wvf+~7LIHeVkn4u1 f,?cY"p3 O=C׃ޞgc&'>Y;}5[m.vͶS5f?—3!}2ᆝPu[ڰXx;g Ar'1ZkXkpSK{-;ea-8 A6 ][؟;# =-{jVڝ b-q@)PFH~^7~;D۾oQ=Б8 ʂh uoT|-˨iog"#UTr= [yBVHH~i -q^Q"Mھ|RHhXˑ NE?7~o_'K*c<А~"k=B+gzG=7C7kމwzPoM␓Twͮ N8C=/26COi\(SZm杝#s2%83< NyU!%]=g#O'73dںz=vXi݉7 ƭi8Kthz2<n ϮcN/є7Uio bVpj myIgO&%N| mazw0ўOdxͶط^2f]{b#;]Kukq yfqĩBi`A=,{:\u NIHJ:6jhxuƧ ;gƟ^V8>Тkw?ȭ䤤[^׶|lA~[;Cn%epxudxCϻlob*EhdF } =V[إ$ʼnK(8KzFN33*Av_C_ۨjݶ7) I3x鼐,7!U#?2lz(u= Ri59{S^pJGE¡}At3Ô Ђ2̂V^KSKђ3yO y >x?9I{}_i,{,g筸7&KѷTcng^Y-V9Fn{> n&[h:hQwo\I+!HG-j7} KhE)>b!oK A( a|4ЂT{ldbristol-0.60.11/bitmaps/digits/display4.xpm.gz0000755000175000017500000000062411233572001016075 00000000000000eHdisplay4.xpmJ@)̭+i "7 ",(ۃ"ݶ!;Ӊ.7|1+q>ͧ^f\T/e[vZH^eT!x}~q|^9H@^ !n"|218cň_6FyP+22Jkugp7~|#dxp1W oFaEoqT-U3ǸZOWw *Ηɞ#KJ q) 77t7oI?}}=}}/)z$%7?8koX?-SoG(e8Q=e_C)h<joTg+z IdUhg'4; z9a{|5OzN1כqxǯO}c})Ok}K|f'2Ng=ߜGΛz6/x_7@G>,#\5N|5ܷEjJ^ |']=`?m`ETP~-Sq$rnv= _= K8~Q8_5s0H=c^cRO?Xϯ穞}?Htgow%'{lOڿnq"Zd [ z&mc)]l'=]7H;da1}et?äLOS|c hglYu/~ѧK]x taջ[?ߌ8Y@W-kϯi4?K]|kH`|d{S3[ !?$Qj(?BL|i|֤V]J>ﴒVS_DZ$P~~+Kat.y_ +"wϸVSZ_dp)&Oۙz"(1%U pZz \x<W?A9|i#!J)WO|ߏR>痘/zQBCM؞Hy4GPn龻V.;)>ǣ~翯Ec>??|h`${I}hzUL~s>V/~d{KCa>}󼾍?Q+Q?ߌ}}NX釢o|~aJ6Y*}Vz}^PHԟ~^S,c`:_G?I79fٯآXYItڿ_E8٫N'96yՃ'z.$_%/x>"Ryzd*c}I'}_r\Ń}(N# µ}KńU|^'(4e:~+/ND-'Ǧ~" ?bL0o'J]o K{?Zq@8!?P;Ès̸Rzq97#pϋ4//~~y'z]R}H~iV߾jߺkzx7Ծa/\op>M8k܉'DI?%7.p=4>:G w'·[>i_<4fbZMV|M59stOܛeLOi7p`B'§hɛu[Me͎5{f92|3<3\+smn~ÙޚΔMT{3S3u0̰bF(F-|̌ 3i4EQ1_ͬ3 ̘+1YD;׌wM -ygU Eӆ鐕6n>#2@733qz4^xRGx@B;\4P"x/gդP<ltava9=pGp ' N80gppnk[7t?̙~@jPƻ2 ^{9 c00Si0v<,`&X3SfQwKp+-\gbWtK]ݚy7s纻1nөz*5znjn}S9f3FuslCS9fYLZ.ԃؕmt1fgݳÞ3kvZ=s~ty>{f皷fלkޚ=_s~dyk|%=wݞ;}4{\-cw⾹Sdz\\͞g]Kwݍ{k2uݝ+WO\c] n u/8?2p7Zl7:Mvav^p\sjtc.OlwnMc-kܴ[qxkFΰ3;Ihu}03usgw5 ,`N&vѽνy_`piGx?ns˟+>ϊ)',bristol-0.60.11/bitmaps/digits/kbd_7.xpm.gz0000755000175000017500000001737711233572001015347 00000000000000VҺIkbd_7.xpm[iWIίH ^ c:nAلaovq#FqF4͈ULS_>S8l>bt/;VO6룅~譆wꡇMz gDo&Ly;pQ>Nto%wE /g}z3jGwѽv.xIIv|eOIyiHf~~q ֧~IZXYɤ|Aw:a_vi2X?BMi6=NzۖAzzM嘏/:icMB~Q,w0ފ?`f 15'AIY*σـN 1-?~GAvDo~ÖX=ۗr ֻR?ZR~h"瑔7NX'A(qbT 3 sC >ÿ#[c3~ؐ3~ؔKP9M ?6xOG'v> 噌ߦbVx/DO0DҾ0xka$=0?Zֶ7/~o!}~< #?K]iw 槵?tgؖ(srâS!oDh ;RϨ/ P6MK4lLㅈm<m˃=!zHoꑔߕ=iߵY?q>D-r?e2޸//Q'MKy'"ϊތ\Y/jDߢg'fװ'I8jKyӬ˖vs; M/1}ҾQMȕrW4ʿNa ~+YUEI]/_a#6-GL,#]L{GWtr/DG0X=xE?iߑ]4bY?Tߍ?|iCod|/l~ |g&O,5 ??1'5qS23xbßY#:gƋ[1H{Vb!'m/:86m%#oGm+Ic=楜|_{$-zR9M'V'IG%^~xo'Ib z1?I(Z;译1쩡w̍PHytbM32G)m&R%qF}f}K0uSԟ;#Q'4e83MR`CzDoi#R$ >X6tѧl8qYv %)==M)sVv b+щ`SCᣆ^E-9ڷou2gGʃ,RNf&^KP, \YcHy;R_!"yF{扌fߺOWѣ,ɰ>g2i9o^۶>M-iޔvl&Yy.ɕ `*sޓ} 4렰ǣA{v]-i9;CK&X\j2Mƥ:}xccd]dzdεcY:`qޒ,"K::V#yN#oňoo\ v!47xݕ˖1yA%aZ+2a9-D zawyz=6,<=hO/:xrB3Ua<}x^I%ay\^鷼+mt|\e3]XESm 9d| ߪ_緮Sg :k&ngP'x>"w隵'5:1rMS]~;THO:4=w~7Y >h67 _(.S9爵u&{cxAU :Gl_bש?y,NxڸJmg%O~ 645Uv{u<ם:m cC.ْlS {zU{?\l^EisA e_KfXd]X)C g w ڕC=ݞ=gh1SGs`s;ȯ7j/ ܇päȯA05OY4 91gW#~;&EtpT@n߮}^<m=YrM~Biyg YNc]O#ϩKl S2^<Ss}ke~z7߽ݧ\tUPvbMحJ<ǰ>,]YKOYM"o3WXJ~ߢ ͟a;sCNQx$|8Z, _Ǫk#xD[Qseo Ab><Ŋd/ptB9C _9I=;._OZ=2܏rM繛575+.9_ (OBY.vTyۥz^~Q5S{Q3zduQc?Cx䦗R[|Psjy>{lTڦ~xc}DF=.lWNcg8qNc<;zx<0cg7EE>A޾zG83|pIyr9-6Ye~u{?+i/T GRE"wߪ~A] ?X *;܃1&,s"gua!%>gہ&ȢɳwhqdhX|om[?^>Uw 9ް*9-/ĕ6Znv꣭ &m<"5Ug~>?M~;"qV'^907 1Œ>~Vb~FUkCxK=$?x'k=&?W(o_"Fzr~yKWHign^=W۰z;""z?Wlvy?O lS}Jm2A-Ts{s.KxNc.`' p(')mQ}oWu # q'?nN #>S911/~Pu<?U_p^^' oYкm*g{ xo-}'{Y,}*xuxfzV~_UI cüv'*>k3S+V}4(ϖX$Cy8:v ~>H~zADL⇳XpfMr[uz֑?Wz93wSaYWR6%7^_`UMt3晽uy{_pg*m4,x 8g[w`vb}>';\z=HE](B"s3hh*OSx:lq/ž  na={R jn<r0Lom=|7 }A"nb1tḖ=2 kn#Iiv^ X>2ٕÝ(S1's82˯KzA")YφJ\GF0՘o0cKXN5cy/K 6F UX,zDdH?Y0pj5Jwr*maBF7rLRd|J-2?Ӕ39k0ךs-Qۣqf-3qe$>MkSzXC"uo*3?סR>IИM3N 7k}3D#~j>\bvaea]lj\0$`jGU:45-Bƹ:0v|d5QD6-&`42>ݘmZ3_ɦ-h[n;CK+zJ )m/ 6~Pk6胤N@k>XI8t]l<࡞gdwUjFl#r%|֘/.ie4% t2ElunHkBskl,Huþ>"oa:~#|hיH\gZs'y:$ӲڦQ+VMgk:IY?%r--ygjq i㙦S{_''#z:@e|,HktA]S"JBSNVi=?`S캺[U|ߩgkJͣ{]Ǭ+}fS詿RxM]$]Ӻ;wr.[t[<C݇nX}=aD77.v=~,ΑC;OƲ Xa"|ӟ(cbristol-0.60.11/bitmaps/digits/6.xpm.gz0000755000175000017500000000050411233572001014506 00000000000000eH6.xpmՒJ0F).mrqU!TS\ "2Aw7_Zfę$CMsRmX>/^I YzSTYN;=]ٱ-݄E Űseh_nCzhtZ5X)YN\)O}+sbristol-0.60.11/bitmaps/digits/kbd_u.xpm.gz0000755000175000017500000002377211233572001015441 00000000000000ѺIkbd_u.xpm\kWJ|_a޶0 q(ea;I^XB%@~GCY렕c=#ь8-gxm{Ko[]w %? J= ^bTrٗrX/\^rT)\~ab/Q."%R\@4ŤT)V<'B&rQ^rZJ8+~Xb.K}\.pk,YiY8Jo\~rP.r^ʕr*J{AR?{p=^B3崂[r~T+8Ife+wj^lpQi9i-)rC/KBK\r@OxPtUWB)Gz>q ֤WJWA5*Q*I 寒޶GeסRHʍJ +ߑBVjrV 7@OB_^>+q?2?e )@Ghҕ^G{WRN*q_*i2ᩢ \K{QPl{MoETJ=D׵ihQnfN~͞_ﺭ /+A?7rKyK+ho[oR~t|*Q&Ia},'Aa<}RX}/0T~r#, (gjqxª[ڋRWr7(WҰ^0}Z5'L*/PK{)0pW(Wt?˴Ia7'SoW?oj,k}#8E#iH{^gz2R?eKߓ\Wr\_Rg7ߢߤ2eFj=B-ii/L2 /r}D~GUjFE)?H^MeƐGIF*kYoৢU?)עrȷj~K9&hf7_O5rHGE#jH Q,z,(}ljժ߮+gOFQ׷c (Bl9s)t?!8 པ+Q3CQ_\+EA ]q[OkDZ>PskGW-B~_+D[rFoH9Մ*wG7tץ\ކ?5#{BM{?0W\g޿.ڟGi1U/r~\KD?J91rLk]Z=?ß^=.I/uѯr= |wR|FIR}8Ϫq]󅔃8o/W(8qi) lr}d/H}L#Ť^H~Tb*ԧI#-Rփ:&R.k)8nOԣ:7CQl]4hcPåkٺ߽W7m,}KDDSL]в9#hOAnn6M{fD<:3DW~F{q/h`"hC\DN{5PyyO?OfKqɼO44S0wDЬ?K JLNK< Q_<G{k<@ћ$O3yl'"ǂ|ktD|"Ѳ_?/c-sHMyiLM`;~ֽ5*BFVLvg wb9޼F}a}#.'B@!j _|F|\% 5J/ QDz1T(,2~E@miԳnK c".Ɯmfr2Z Q1gBúsץ6gs0سq>|g | B{F*]Gm!YE؁p]g_Z8+F2<^X2-ɢLQ{#uKkTzıC}g9Z{DO9⾝"ިEŒaĈhW|09S' ye򪰇9ai?">aڧRׯ1PW~gG0fR/f$h҂cDH/HHW: :g峥x>Ѹ;7߈awL -О S/%\@rA2W7#]d"dXpEйj3j #8E|ϣia8mBgƨ$6blC-ZWpyCQƏok|KO|?f|Gԓ !)vg{,h[=)o#${"<+xxO.ly<#x Ϟه}Q3<s@tͷ1 MKM\6~x|6OOq¾ NF+nvxHaqxgT#ylXx֡o٦- [sEs S+?_gT0j9 ܡT*EA6u&ggu')؈gCV }3shn =qowз2X˜΀sUیŒsLx ?(Gi9>!mh^gxv0j,YT<mG(.>j1W?/t:N|YYt&-a=6y]WJ V4yt9<6=œ!%|WΥ4d%_*h?= + v~㧑HOif+қrt$#3Fc-옠9/A;c<7Xs9Rc3&a_}CcsVlǪ@$ѸHizOۛ׬ Oq,Y*6hFp)"lNYG~g8_w_t)@:ǜ~~/Z2=8&ě|[c!j+1u]W6;{pBWޣk:FOiNZFضôVC/4[Żaӭm;_|$+-FdW_OZו8mf5&y,3~z#2|iscсu<-ʞ*u޹R4,!+;cV])k4!yl|]6y ̵E#v9OXJvKmݩΩ(xk)[oCY,$ѸG!Jž@ȥpiؙ0V7<~dvq׶<`XˆؖV"~-X:oYImrn-;Z>W?-St2B|b.`;. ;A95M-={3 Bo% sY䯻h+}?jX]eGLUM@Gv(fزD E"5Dcu>1|8/%FQ>YȎ>Ɉ,f!2EלS>ptvU˭hvc?Ìr<)3vux=$>a [#9@mYXeOoS]9Gc`*.vTtugGKe`wEj1ٲVX: jf4=[ja E@dms߂}ĄӖ>A'u'4cxuײx\fKȽܛx\gM\-b>q<V ?CͫVFwt_jhxw?}pA ^{{fA2~mD]'%8Qts@dcꕼ"9Fܚ-ͺ]SnϟgKeqfDn#z?姢H^ xw=z@ԧ7ޫp=J Me]j:XӴitOf Oh>Mx23&4Bhh͓vܻښa%Ӛk}{Nj g/u#]gt;}#mwPSh\ ){$O ,6w Ą߳!3='Nv yGĻz<{+< 07|+1͓Zy3<蜎Nn{~[j 1E´UHJe[¯2o 1( x{m lukVojvsHe~=-h?Y>/u&rmo>mHg'z息GmQ$xh6U#]3/^jĹ"QDƑO{Sxx}S%=yk I? z{=A˻Tĵ( E :y }[>a5ʇTOU?e=ƿ-_SF^1p Un9UH~P!}exoO9h'ANfOx Iחl+AEuDJI3kϼ;CbinU?۸c W 0BQ4 Ϫ~@ƀ1)(Uu@9$fNDfLuюig=g݁7"$J@dSP~Sx sDil1 Շ֝CӘc,ϙ a/١Zw-}Yc2Z\&o$m5'{[bkf{wѝ]nǓ ~+  7EѾoGcbristol-0.60.11/bitmaps/digits/kbd_ar.xpm.gz0000755000175000017500000002215111233572001015565 00000000000000<ҺIkbd_ar.xpmkWJ_S he .` w ?Ud2Za;uUWWwV|Fsemuέ!ps{sq}5a/q-ZAh_?[V +}u[tIݘI]p|;!{Nk#בm7}H #t IXCt#_Iyr<ܢSV X_r[ZB7 y[\n\z"/6h[}k?V偏k{^b 7r TڃEɥ8ޅ/C챢mGOmob4r|?I ڭ1Fv,[s*xM?'z m/ )-ʓD1Y_jO0>'Du*zhϤ~O/ѝI1~R?Os)I!s%iOI=FڣHnվ,_*I*U?J/o$3J}v@qg?-'O:t'3#z guS_KʿJ{e)O+/]4,x/,<~wZ?xAfYkQ?t 4(Ar/RLJOdQ)X99u^,F0R/"'3"^1[7vqI>sL"ͪYTY2&2J2D2j|2llYXVceAS=5dX3VF# }Y~}ƚ,cY2Jmcԧ1Ȁـ$Criv!F$\M"i_`B2"4,C4Ô5e6<ɔh}KUm,*e߬wfbXV^<۰W.gcsQ\Ќ_d6Sgպ~\Zk=~pI;n,:T78"wmY9#fW4ڐs"JIUvKrCr@Kl/[ҭޙ*50|O,)>}9등{%4$?iQ{u{f!#a_I,~5F)ij_ٯ隤u>H)eE{d"XlH>ގ-jWh22fy JC36KL޶O!DrBs0mK%>m\s#߮ Ld {$"Qj|8̑y4SfŒ٢e ;#钰\˿6D^I|Ke.σEGyBջj6Xx{6{?Ӕ/u^"byE+hE3S2h #%4~c8jtmsCGDC ,7wݢl\3nd7^`a=ʡf!]< 9' г7m\`49<oaY֚S5n&V^*_hz4ynyEM\O˔O(?#.4 TbWevCuĚ4q6 &q "Ѫ:GL0MLhV4uvikQ̌ ق%a1D3i+k;),hD.Y* U,#)G3Sjoϑy@6/uf%tp>94Xq4lfMiBjxl~}㜃}tcߙRϕ gMY 0y7 4r&GyBi@c 3r?Th`D3I)53dXwU4? @KQIs9sSy#:1<6,l?{JХquvOziMIxoɿ&/OxfQ?{mР'~퀾6gx #ޚj| 6딯Yƻ6׵e>H-|̟2h2&#wT #v$h.>Zk{P&](ǖ;93BO>wzf6/H-<ړ*OEֳM^w ܙ)݋`nͭ[ƹ3.Ϣpv Bcg 4rvݘ7ۍ}gw6<^D S=d٣>eں_l+p+hތm7NɦpֹCS=mGyEk˵u\@v͹濽~QGH3i['lѽ4j;x|5|n[ˁA\Զ9kzѡff|yZ_d3@S5G=sip:،MZS$J4"kvgzrDcrcf㿭{S[GOq)Q/ ǔI8$YCЊ6ٷVd .3===g.v%>aò^pe~;P{Yi3G=mqgƄ.мg}/4Z/t)_SqX|otD;y$yLbٌЬ$4?yԾ@9yF|-!x54KC=r4/(P9X$L =?JUM Y+^\a@O; u۞r`O@}uԟUiDx:,uEӜ$ЧozoX2 *;@E1iUYwv F98LMjloW#+yzs#x&|DQ1]U 2眳)lTO\]j$Y}zZQJ#ɫ 4*yg4.]qVXffl7צol\J6s MqA'Vӑ+ۄ):ay%8tչ}^ ͖cy:4jMZkg6navRZϘA_7 =7wYJ2g3OYHin_8ͣ}\yOhr&߹tʭ6EMĚ3 F;abGMkeי7]2h_`@ CSh)ZҤ1 ^xfjPԐ:LmeE}N%jzX|G5NhV.p&dOjmT;l6XMkGZgjd+<bjnxt]T}J_Z_mNpq34]tעI2@;/J ""K,COfy9ߋWԭB-# ֛y8ZiP77j{7yzRZ3k^1)иjy P(i3Kzѭ:i"tZ{50JHV<'~jF5P+]>uL>v5aYOs\XX8m}SJ.N˶hơ۪lu^+MS٨nͥfkf`ӰTYZ>W Sg]p'HNi.bG,yfyo[ϑG0䝛vJP͇5%uP![էݰOWnC9FGbi4!styX/qrMi+o޳6xnAM;24 h*2ns$'}Sq0Ny|ܛok|1Шsm.M)Ht|,3eUьX|;Nh=TL5Ge43{y9\ Yn5 ݨ,:Oإ3MȖº֚繜&tgti{opRH k-;41O~fSh~Qsiil#2_Id:oNkkS5Jpc1KiҞ櫵;ӧI/G)WiE"e\0=3 :\Bl<ϕ:sŅRq?7Pb\dO>R_nCUE6L]y%ljbiݔBŠ:Lg\Xϙt]}nLߤ}ꀠ%6$,&9VjޫtkA7Q7vUC;5uV {;wȃ=郄fWhV)*%&@ I_"nyVONuVca$Px5m+isg4TƍӨF-q5k*&gMim - |~nI1I)Мi-ؓx%k;z/=Qq5J~V*_ YPA7#G"TxE1_m  5ڀg;Q uUg~ĞHi˧D{[4d,aը.SĄe7fSAگ١D[Scfߙzw9vqwƨqz/J3!M7MeU)V:'PuǻDgJl VmwAZ j$V i g Y.xfڇu0;Y\JZfZ!#y>2޷vsŻUfY#kѫw7gDZRqj[ީb4M4 Ƴ @Mnvl40"sA+g]f:!F H85W-5"S`0A&v7m̦(3Ú4':{1[_ca#nY_ui39jз{d =ٽ`fîtXaΞAO;o0jj5Z=V8]q eB|>w\(.i}v} O\[PФ=Ah 9r&#<hx¾ʟ,ܧvnc\phܜXS>34ʣoL}c‚*{ȌtaqV=< monϖς^ேpɶ)e=VQ:u-3mFqvϢϦ|s]VWvB4>r<4zf|VHgD8g5wW N<чk^oߥ޵LVཛྷ[!%]wN<*{:o'chTcAQ6IWՓӊh>b| *D_.ǰ5{N4_t)` D2?!O[sZ{ p~v񙅐U=2[VɚIq.sFi7~xaD8)'LwJǵo6{ה$Ǭ;<]s Gh;~(vma)zl )_DO[=sso&s? N~abristol-0.60.11/bitmaps/digits/2.xpm.gz0000755000175000017500000000046211233572001014505 00000000000000eH2.xpmՑKK@W\2ŌQj S)AЅ A3!ڙTF d>̌ -.ɌruPs|!C㛷燫krŘ $.o>൘() Pj(' T h>@f) ,s8sϼ%pکb#Z1Hl#x 9cNɘSΗ9izCG] 6] :Fp2gb=نewOJux.8g;ÊM?sbristol-0.60.11/bitmaps/digits/kbd_6.xpm.gz0000755000175000017500000001761511233572001015341 00000000000000aҺIkbd_6.xpm[k[80Bc; 8u.\Z%@巿3#ہvwL$K:h䝙޿X&g~9>Y=^ַVIkgmcr[Z歋_~ujuK~ê:˯ug(GBO3E.&=QKFZo:7ЇB.E^>ګIaaGak|D>sa ,pgA=p/\^mJQ|˷D ۋzQw:s(g ?`= ko9Na9Tϟ|Fa:^3hì:j?7hR}ӓ cc_=z~ܞF^3G#4~B|oiqK-Bjf/ 0y|a}30] u?̹"|_xzkF-u[.Z{D1jYOi|(ԣfbj3Y 0RnV"_PlϨ8x}u~-x]/=xuߔy7y>GbO";liG*7G2Ch2}z\Rx.7\n/&ƒ8y|։r!xI [61u-y~#/1pЛ^qyNXӂΠop}||f=h9fo63C{⟹W1F <=7}蹛י D?MwLI姦4||P{9&G]^=3&KS o!zCleU[Uko5IBrH$yuY|'#~'_ٱݳIG$߯ үWjr&{"e⢟jLĔzWi_׻9|ӏޱ#b|"||7UQEf Ii@FDt˿I[؋ȞZ*dC%[f|JE _֩CEr W\=UIQ< m^ FU>PZYjT-ZgֹKyOv9&,ߓ+29>]xvJ7 Vf\|dfc:}`_ k`ȅV6hl;4jMީJ}[mU+ t".h4^񷔞5^#5QGGV̪qN2{?LX{KmaD@~%$,V,TshVF{ -Y%/eoK{4z-T%H$FSa;U[POW,hCψ.a~4xbmRl\sJhb!ݼM|EMj%| _%q!& Mx[š XvJn3Cd9W)bC'$m x6 Nse{dG,B1/zbA|rJDzoO-Y?:6:k‹϶*~ f+ext H1ccϙR'Y!Z}x ӡj`&8nT A=B`Ǫ;Xl^ϖD"ᒊKh$gGLuOyx#>`lx {Jy֥ua[5+VKiFx_.<1 #>o9N(D":~ݥhm{ϰf^F-UM/vtyJgpUD:BF؁b{ǃy }h2c>!:'p]OvRJXΡPC=ȶK<u-O!iTՆ#O+[c7wo<,q'gW{gmp |=ZA |N|`!g"#Y4֧"Bw2B5+u+xR_HrXgo vc4j@8loṯuLlk\:~,|#^?lo ~ }>~)CvoRF -7Zv1iEWC@>u-+?wԬxdv5v3*IB-Sc6}3j^CT3F_o5Q3ӫgF.<.yz-|J躚5Q߁gZ)8x4y}Ҋu+Gq]s6+5weu9ϖuG-T|ϾZ"ck"V1J?x<Cbs^o.sL]C5 +£=HgvӂFtԇ5ns'X fmÂ߼{o%xZ5#8ECqϠQIֲ5k=,[<9oߌxzr)3<|:'">xbq^XuV9o=cz{1UOɈ8! LI|=j!"DF߁H[]6E|pƸh's'r0*m?gMg^q>mD;hW[$^y[gH/+bX#sPwȁ-ޅyy8B9uF@y_ 1G9$orPX%A9>x}39#;Kⷵ;{Gsc"Q>LxN1aDm9Q|`k=KneNo"KAd2q`O1S>% \&ѡUo%2xb!kPyV1~(~7dο(p%x֙ngO8_B:]WjrhrvO<tgv3VZg5x7S݃L[jmzӫRE.?}>xFx4_F>Y{xuy4D;jp>qwTeo'|]Z0x8TX>?Trq%G~H'x_zsUG[x<&D~Ϗ} ɗ ~;D%{E<\5+Kx~~T1n${1z8-yZPv/}}~疅 G ͤU=@U٢rW@)x$Yy){e]5m){?,|WN{\ S\LsY0޸G#Yk zg/Ώabc6H冮wتh RӢ}jD]m_ӊ^GMJdށ+T3ۥx >۰e49٧%x)_W 審،emWsu\ςgW?-{Hu&o6\kSSIb\!XE@BBE)R +">$b4sg܈n©3ӷ{"FrvC vKΟ.}b>*o{K&}&7Zdg>D`?u5M+3'Z1#|p7lƝVz,fBĘk̼y}з2ELO9 ixN>")Q>W,j z};a~w#Y|ߥ,:hͼ'y>WϨ৩8&RIfLϒ-Od^$hL,v]A¹d{9oNf86l?zS 5q_9犜ۻL?)d;6h~m&s>2|g|\F}{`7M1s6cZE"JƮ]VDҎ9P sm*mY܋϶|F Zaur52~?ĘWS~!l{i}d3߆XWPtV9Lȣ?rhOSԸ-=-y擝YJ2'f %Z #˽&^3>?ɧcouܰ~ӦsSGY1_3aVfsAヌzZ%jQQ0GglvŸ7x:םQ~ڮ;^ǴC̣d;/eݐ{paq7}w~Ѹ6Dȏqb9yMiskG kɻ^SKZm?ȱz,-2[Ek_J}/]|eMbl)]O@O+%h,\ϘeM-À#$D `*`(y؇3kV}'פMWte9W[nzeɕrۗk?2e4K(+哚Y}ݍ<~L=d+)Ā"#ïbD>;~+/jl':N%Ca4aɴڴA aMo |JsRk5ɦ,lG?+Kx"|)!s|YL}AesNP:*nm.J)+p* 2) ).b2~d||D_6?*lYj+|ҹQ>3T2W@9,eK2>Udl{z-٣ZHGwoSkdO-ʞhuw?oW#ar I[/a:mS@*V׾KkPcl܋B)HpFqz {Fc*C0&G=kmQ_/[R#*Q=Ge|`jY1<'l;ܿ;WK`(?bkخdscv6ǗilƩ*OY*y{jַniEX>Lć$J O(1QhRE l|P|ڴMO92>EisH)7]7:j<#ձCIҩ T*+4)jm#eؓnlXV\<)3GձfB#3o eϵKjL~mm6X;IΔ:FXkdqݙ;kI`yp.G׆ĞwSC>r7k;,\O: g@>oc>;\i5Eȹz[QXt=C mSk';׮۵v_< 5&`T5Fǂ16u+Ս1/>Y9;ĕ/[{>+\ I-맮nvȀ=#3u-<ŧ7{3/{NiðK7}8wůh{=X[w/KW;|Cז 4@q#~?>cbristol-0.60.11/bitmaps/digits/kbd_st.xpm.gz0000755000175000017500000002305311233572001015613 00000000000000ѺIkbd_st.xpm{WMϧ1I2Cn!,@Ip4᳿UU3z^k[+ΜU]]]`e0;{WýN&s@_r_:NZ0]jC IwxǧYn$Z~r\,Z~rXeyV\1.ִj\kyޝ_-,׋I![_*.~\U*kyJPXK^7qPYnrK9)r,eoW]9_~R۳[1_`Y*x}TyQqէ^G,'r<˥Rf))B?E /*JWYn*,W\}rCUb <9O9_~Z;,7\b}Q.WJ-wY.s%UX.~(\)[{r)徯O:a&5wj#α~g֞un w/y~>.p!R οv~7<^/iO,5ݱ+'%o<:> r=߲{^5ʭ2ϯ@-ӟWFJ+h,q%?|jc'[q_c:/eoxr/~Vy>7=Z뿰J㍸N{Uho>wWXSONJX8ȮĨr&-0IPw<.O, ?h@o+9^? }3Y7<ĵ*I6iƸ+q8sr_g"jeAէR=wP.ˢ*^9G(s_JSI*W-p|2۫`<˹jtb]W.W^<\mP3Cj`9kx]_WM^?t*!6ZK1YhkZ]gY^Q^FV3`O 㸾_Z[j%=o'x{^rVW]5˵ZZs뎷N{~l_Kjdž;^7 Ofe{~}Z\\Y:<տnwZNmY^?YH B\X֋/ޡ\/u479xJ,W| yy>7o'ElW>,WM+9U:_Z˼˅z|D9᳎<\7~|^X~OX~sYf{,,MP%r>o[$־ckOy_w<-^_`9;¿ ly27Br?waUwrrTX}࿍')=\Om5U#?2^ L?I}ߐ[>DSkyG_MI  %ϗu]_IPCbpگN{qU[מMܹMݯ~!Eo'D豟e2zoH嵼߂(+K䵔R++d&T}G܌]T3y>їK3#Zֺ: _FS!?pŏ%k)CzbRDbH(ʣa'EvD_mNBK͵`'TO#*⎎&/T~1,e#= H]@XSsaXvoY>ۖjjg hűv~F:JRM^h}Ш݄+GS!R?.eٗgedy/Os hF)#&$~3oY >A7_[,Iެ<+Y ] }js4 f(^G{}QrH=ZC;X4:kyC%5jtSMl, `ك%@ڀOf=I}l+ '$%v1P' n')$4?41hnJ<}?7A MC"/XMhT17݊ M cg4M.ZL7ѧ0ӨZL'K{D<$Syd^@yH nཿHWVlxT7ߢꕶ,V~Htm.05fGSwz+F5{JE^@<ڍԥةf >hD__QJomK.s!EӘ٪F &wdLۈԦ@:^j,zOG'c^E_%f39 )~š%XX|ȝw`^{:ZʷwGeJẏݼ1K_B~d| "AV^``>g!pƢsd.I<ⅈ:":fV&(1A?'!רNL|diaQ4b/ϥWa㫴7"C~?ҼѓLmFfgNƘv=M$'-h`dZi`s-Y1 =euv2K_Ӝ<=`E4zcvf {u4gcmD^'ֳ oK< yu֪em/nVi͹O cFN2\_˽4 {s^\ o0vqhm Lz#EI=$x7?h^[jc-Ƒ11/ /B3[Чuس8]OS(Z7дOSv636kG$?D| 04ak}) >֌k#iV&2μ%$WW<@1`Agb>MY6qg˸tgaf8.N[vV=D)M B>v+#=1` )MKXeg.?Όc5k;yy:[s9wE{#/p-֡Z>ۧb.clxCG3~X#9Ưp,2".9ݐs쿡i` KkYsὀҜ#|ŁP³; $xhhC"gY44}5YFWRݬaNƼ, g| Q/p^Bi߲NI>B@rhL 4ަbd F"kWB2O\FI,*^NMCG]fq3;?r4 с4z̯ac:ۍiG9+:1V0fg> w?fAȯ9K3 x87 #ܓ~yXH8m]@3rkgrm0Q9qVgIiD_ hf`b]IČiB+Ә2s9.aדM\)5Ǒ`jP/XPK@gXa; s(%f[)r&,n99NfЇNFQ/W5pq@I8cKПKŢNyiZ,M[uXBMsX87t=ĭQ^IugϺ0+lJ30lD֨ = gku=wِi Z{3s8{Dz?!]Xs=-g<1~}mhhs /#둥 LGFnbI{h!Ƕ8!U^[ߍM#[vm[׶_Y:G ɃIg5^>4I3Pnٳ {?𔌿86}5tCյsOlBX#kvZ[9G h4 @=d 2#gyviְޑIY\j4cmEm6;EV]J{eg4ucr^5Fs.׈l}m،!XRt6d[7T`%Vwtށ:w?w&X8~nc.ì۸7C>mwcfiڛFrgY{gsDm/ Xy 6[ 3閉Q=Okգ o4'>^n4ɲ9ucF9X ]샄ҷ;E;ȩgijn<>3t N/KGԎA]䗥IW֪Fy0o;c˘.78ը3Xي{Oqn3TC9h.q3 2Ǟ)Ȳ̮-K 7g4Oy5{ F6 ,' 3ę\^>u +k[-#r`aOi#Fы>Hs}H%59\Us537źBy6%}󽌐OK䡏A/f@:87Zzx ^j~mZ9¼[g>b"7ɮ2>Fș[xzXEij7iRz˕ ω{{y5vZ RidDg152PJse4)ϽNkzך03ڍ$n')+kQ,N[ƨ3K{Mpav8JrnkDמq,O0\1G]'hlt ^;nz#jۏCCWٸtXDf.7zdMMJi/1Sk.Hk(r6'ִh\,Mje̞G)F8kk7kf~F}y&f A  wۥΎ{ևO;Us6Z.Iә~8`Pc-l'36\"gg+7Ьͤ.=olW 7,SfEx87}4M }zn,-pLroYvovuò! wH:_}\203S!/1gѥ8= ̽}OAyf&ǭ稣Z6U>hT;nLqBʶQ7Ԏ $[w>hCoeuΔx:r=g.qcd瞹0yv<[#t#s1B;tsogY^`bUDn\?ɥ9?K3M=D6ܷMJrgʭj7;2DB ~4D71|+8-\Lz䮵w12nIϘD6`!V/-s;wA\8|Kʬt\3dw}\N;] |9h.' |&=9T7wlV3K}j07.7nL_n7M/_w;=NFo,2gyKufmMe9aCW GXW^4|fVHF,cI;JwOw!s`*8K Yc?V4Cp\%᩠ `_hF:Z)KYq˶%~C"S`effiؾ-yl+C݊Gv?Ч-C7Fq ߑ%zg{ F9]ZC]73&Tw)"oLL-'lMDy>Ao2m~΅_ctbבX6фK^|p$ʺ[ U\G,|GA' 07#jQ=l [#Ty|F2mRh&N7ʣr,,U)dF+7g5X/7 CDoMix<`ȽD##kIe Ezu #q,n5{ﴔm֖栆NuS0l[رSCwz`8y.:AS;"E ##Lt1-3KAQ|+iP#{I~Ȅm5 {/6ӎCx7gkú!fV s (h6@z3Զ؃Co}E1>shn>G~Wka+EO֞]*~MsuL J2x.yX#F#Fb?mxJI~|ܱy-yNu~ vM%;5|CYzO,k 6G^o2#Y.n^y33q7ddWd <6_7HC6O?k7! DCό<+gXsޙ[u3 fTRi'x_=hhk[\:x;˫ sޔwjzߊϧ5V,+jVnDUi--GUo6c7kw֠߅^k5{7U!F41Ii/h'Rji/l&oMCoZ~3d}Dt:K_oG͌ n-?/Y;nXJyL'mߗ$4|-hNGGG@,gz?ZBo;_i&TK1 tRi)EAyK}*ϷE=wG/Nh}xz$;~ ]v߁V~We~VO'Y_Yk~ F_F{#Eo~ǯǮM‹>|5=y2?-B||D'}=P|>1H{5??U#h1s_H#xz|ϤPH[~&z,z'R?uJ9YCLj7#zT}:?_S=LtB_jho G1<!狼K_P ڟ= !{>0޷:?ACs;!_G3{מ/_'s^DORYV0[tkDOh|7mu~cQYocЃ&~Xwja)'b)m?lP8|MJ8He~Hy6eV`{RC;5Ky> [_HyH޼Ab~7Ku}z"_ګ~!_|!棦 !.g_o| F-Y?{G/ zC׾kT?CoqC@!q(zU#,SωsH+~&Pܵ볧G:_Q;<by>KDERUc~Q,9#3j{S(⪌f?=F?Rފ"s?Pz?Rǁ䎲>޸[ ĞV ^#j8`Y)D"- zNg^O+ٯXMC}e~FET= vzXMhГz&^I0S =0 cgRZ~EǟߓjI#vcKy>Y[f$ho^,ȄoGtޗI_wGi~J!4[OU*EtNM'J^]7k&G:>m}Z4kIy-%K{i01MEoo7XjO4EK~R&/+2$K3o7,&7PƷt:?Y& =#ޖ޶ߎԯn^_(Ui|'O?[8d)ɰ3e+"VކMDV8 >pm9˞x>Y'|O=ޱkxOf>}`F/@Σ 3j!g`}s9?}̉}DR!a,gR`VWoȮtS;G kᄲC_ow:<' )zE:C,V̆7=-m$2cˮ#jiòIjBsxV%YW |Ff28~fI F<Ƴ6xfz2*Wr]QT66ra~Q“.5׺>4hbxdg3U{ף0ɻ=nz|O{ϖGlt{Ox$k%0_JxNs>E}5F3F+7su|^UcyfW:.uQuR|)|͑[?80]5%4 E#uUhE3<>}"v ٠sۧ |\[UT>hodqY frZqDŽ)\ 9S<#,Ml)|Yn?V~Nt۸=W~r>V^39xDI><|>9ш}o=yX?y0>(/cjQ6x*= ]jfqsD& [owBA9rhg?O4;[t`! Dn'a)GAw("maX=k˱XFv$ݸ܂Zh|zϪTOU<%6pW"_+ˌ޳ϛ7^7xqAa˜λ+Y_&G)+>'.ݹ uu  G9mSNn;03Q;-b7|gi8> 0vJ|+F)ǣ3oJY\[oyF۞qAax)N jWm896}^ojwiںrF ȊM:o ݁*zx=*>Y;7`ӳ12<.vAcM>Glk|egMO]1[ao۠'nok❬ax<]ڏ> ţ+Lߊ|"φ YgUn#M;k7(FnXeni0>/{74x|"{s46OgqOx>P&1rDF~;J R:QB&!|{˭xgY#l7.x !۷ܽq`;daAc-ؖlg_^x~ |?ҋ6<[z_x$@vx%#x~%_ߩ+ ۺ)>8VO(E=GxREOV[/a9y'[yaƾShzRؐs)ϯAӏ*9ʽ–۳OxoL ~cv/ׂ{x?wDOߝ Oiq9 ģ~6?Ө5ɻlw{X|=l~pʾ:gJ7O`Mqwo$}b+x*`ivw%[ޅ巕7@ rH5NӴ"ӱkwޔ`-xƣȅ%@SpBkAs+>J99_,z'(/SN-tPE<:0=}3t9gCm"O1>^_)g=lit_?o*gb_߸,AEmCT=r>d|JMQaXo?>o' WP ^h#x>WF+m3͑&َyso-bS}d}>Yqsף:#z붡i+%ųc#OojI律= \CS:{KewC\x.8TE %}LWud!Kϛ===~oߔ]Hr~sᳯ6pez>o__>w㜚|na~o>Xg83>?G|ms ]m?6ƸSg5Q#o*oQ$ӯa{9y_A-܂q#ۿkbf3F =Up| 3^gRLz{av`O,,C"wQxk¾_O{ ]96OCiX7Q<u+6b"HxIC3[ۼ.PaW2ݓ˛Br Zx> R?+rҘMƔ1fD/x]W> u-, Urm`l1ܳtfkS֎3z$Nz RᇱZv-JyY2"s+'YHuL`h$V 4Z?C]7Ї >㣳:kϯ~ܻ`17Qoe}kɿK%רy@Б_Y]mύjp/XS[-054_HCwWؒ|. ~ƽd9+J~릖ETHuP,.'/i.Pm0$!K3arP>.eܗd1\/K{;pV&JF ugY[sFZW/vRl.Z_zDe2\3)VZgPmRHGwS`}۬1Q yÎ%+SZgS? 9:r^..g>ZW{"SWO}H`")yӨ1%,kdMVSYI2e}JZӍrya[#}\ziɁQiFvV!LMC¥)Z%EiP>-Gn5>9%bj(f|<>G:?FF4Ş+Y=GOX|0?|0 /qEZahk2|2'#ǂ| >oATג>wI+)͓_M{{Tg hqʘ[)^:RbN !o9kjڋ6-+#?ol?䕌ihSNSmT kg:*RE5{f|I-e>}=IwT{|fª_ j7P;6BFwY˃ Q.^szvrJm \M"Ke|. m;u@rO{A 0!jm0q#`v<ZX?ђ<{ lS]I4q`o)aGZ[I96͠żnKNF ޶=q#osW>o h9(6ݑ\J[ۘ|^ ӛ70lk;?:&o>d|_8rܡHF u5Ek@x34.&p1|0/SŮvc'>R>q;]WƓcY؅]|u |6bWb]c;obGpd;%g|Wۨ|mefq?cbristol-0.60.11/bitmaps/digits/kbd_r.xpm.gz0000755000175000017500000002367311233572001015436 00000000000000ѺIkbd_r.xpm\iW<|_a^Ļ名t_8@@a w晑(e=l|Yxˣ=},8ǝֶ¹jw-Oy78DžJ\ik\vW˫(WVioհq%rI~Y򂹾^MBʁVAyQʉ_b./Yhoe})YrA k2~a=AHf!ڏ?~q~"Q1^F=B9zB\Sѿʯ(џٵׇ~O_/k>b{y(qX'YLpcח BD? S( 1~'|R>!=޹( ܿ%_J}5jߕ/qmD)'QOϭ_ugu)Q#]kGQ-)WVvJޚ;NBR0?pk)jYWyS)TnH92_JH|3/ПMScA?K\(7f$YQ/R_d>|o~+ihH~(-)5D&w<.' c\yŸFNު ROK},KIʭ$LY)W4OrT2|:[i 4LoOC,gi%Av祽j|LIGi2&w[73ﹽ紿i5Ev z*[ƯEr}\Mu>=H{~K};MezooHEK9~h["zu\I ,y\o,p5ލԷ3#dm ;m_]CKI MKߒzx KGrfuSe2φ\"VY|iMC7M&6bQ&Pc?k2_|B'j &V#ߥQ=뇔$oZ#/i?hT^@=WEKMz~3>k oFdd|JRagP z3hb_܌&-Jo9]z&}&y2o)s ZzvJӲw nZD^;;Dy;ÿ諶ι&VKs{$$ڠ\y#|zbשOНsD]s鼡?k7/P3~[zf~8?iy$zMǴڝ]vs\]9+W.ߊ%wٰĽ{$!橯EBLɉ {"Fhƛ]o/qLf]_Dks./R+>ZV}=e!}&rGv 4&Zy%|`-"YeFA<% h*@ ˲s t{"9;~>mZHXGGOҺR5Qh@skL 90R}J@3x'pgChRB8 !I H^iWE]#j(5{Fw87OGR QmBX xxWg(y^þ"dLGM/ΐHR`;:>0K;7Tgj3 "4'QOD E#$3H4ACe7֑?syn#4u? 5w@u Jo4_JtIƄ("Nf-P!$ Pz.Rאx ~Νj7X^kBsIT%@䚳fG# Tء^ zΗE@G,#wHz:t 7ۄN(E̟up <-:\s͉5Pg*{@a&cٶ f>˄ ]h@xEZI6?,ogߢitd %aYvz"m|ǧ9g,̟"YhخY.Ty _lB5*iM@uK|@xDy/>A8DK >5ц5 Z ~ *Yg>M}^IcI3x؇;&}Y쫼msK8]4s&y8F_:ΒXuRL==wGYSS)Q/j<-X bGއm< |zm̟'?+.r-ԁ  !9OoB#Y}N'mça/ll#L<SHJfl,z/zṰ|UAYg_DE곲Y-{ ӰOm9AL:H.GᏊ=s;a}NAd Q;{Mj 4AMSx؁LJЉlQOԞOD}xH:9;h4d M}oG,̔{ .{!_kƛWk IΡ%Sg`-ągt$em+ͣI -Di~:qaz<{#69 M% I{GgвA$jU&`1Mw~!a;DS6wsnH{jWWW6Dրuus!s5-hN#䍳Sƴpx=C /5DMo"o)3hJPE{&|c 9wJWsJ"~u4>ncmb^!WN+s ;ts=PDvAs/k`J؟9js\ɩ_ܿZz֭;=^߹g_iy y[gu v3gȊ\^;umY>Vi7?grI2=x@S/Ǿy<^Qx7duQ𰮾<~K icȌHͺ霍%P*Y!x8X>Qكmۗd5_gSӀ]{m%sx <1HSM`ej&k@ ?>;Bd ۣ3uRϼYG@S1kFnt=CΞI:GRi3i;~e>}t_}mY:]yӮ <,2p!K9qfLV{c蚉Ж>!48+XdNgYo>UyU0ŠVo eM]پ <͂(1d0XK ϖl_5 7CB_3ߑU]'_odgS׳xM%~:| 7YO펝I<ݖ:JNs$ߋpy$9_xۢ"; o߷;M]~Y}z/ϕ9е^[aO)\eTpY<[$ڮ<6؜ ~/4:9ci֮ߑZp]I y3{n9T̼?aFyP#D=ltgV~9۲ ϵD̵3Kƞvr$þ||7fUqW,{sc$F nPUzIgCw_}{wn4_$b<Ƨ.݉&SZTRi-IvO:Y^"hn<7*cq`Lq/HE2bKmx򨳨sG4D "s{XWDǧbA:->0(=L;D w=;vC;Idɒ"o:Î48 ;U;b_K1#7z sIYލ='${iO!҂_mb{K jaob` ɎM,}U[~3c*ބ_jڡRmMkcaj%N8:9Zr̙>n3,=̣*}=]8>Yocy$kWyؓLWު^.nNm]b)݁w;ala]h>3 SsD3'Dr}OJX35}"z#~Y/Cu {>cB O{y&VjLtMPkjx.;&;ϳߏ%}< }?c}'?b< !Og<>zX̠XMڹ]jw“f/XT %I<Fw>;iWr؃fbfy O(Vye6 l\)d9-xQ"(B c>k9z։U{G΀ HiCi7E#<{y濋ٲ\aH~ڷ'?Ky Tgg-g>f<{3 Ô}adı5!z<{o໼!Qm`Wy߿}BBt5[%o0ceҾ:8ѝ},Ld8tdus I~3̜S gF|qgxsa:)dIb)L-%*|GmƧ1 l>Fw,A;8duZU/=~5op?x +$cFϙ{uk}dԾo<{ũV e븜]2CsHQ?@vI! x x>8e: ][.v Tgϴr d(<DekNlj m?緧0 sH9};]D4)\kڜǭ+ cO%u3ˤ gNRaH_iax{'$NI H|Eʣ"Ρr^! -t&Pۆ~ ޯDcKOigm= bv{8@ѩsTUN:]4[)G,scYv;DO7iTm,xyLǜ'"6X1޴wC&8iFڹ*ᷩLy/SwdLx:X*<i{9viSS;C01~Qb}S\O ִUUNjS uZS s| >t۾#Ho2:ǯ]y\rɛ Dy-){hgKI6.PWGx}{9P]w=I VmzE[~Gr 1޸PwJx<o픝hYqvvv q 郛s jx42od(*qkFAxsln?Yy'?;2x~3w.|PD1.}ᔜBZZ/KxC=gԫYg(mL/2W,=b2w^ ƍ;LnϽӌ.T"b98c gd[@?%-? 8sYjA㻉ώ%/;3vyIdZ~1ї%s/=yo$0'%<z>-Ӽ=Nx]ų':g%I}Ҍ rы i4r"&O!>Y'#MgY wD{'Ik6=\Bcbristol-0.60.11/bitmaps/digits/redled9.xpm.gz0000755000175000017500000001021411233572001015670 00000000000000eHredled9.xpmXgSίWdHdcL&۟zpޛ.K[-g&Ew?bso\t|hyE y"D%"O?6v t d+JlG%`?e܊x(d܎8f܍8a~!v.xoLjpx(7>7;ly0w 8p`ύ#_=C q>K YS=O|+~|SC3_'Nq.5뷦y|+pv4{wPr[z|.(|~_78~?rw! cOO}C/|q$q@gE|S!43_e"̟d9"hXOԫop}Wߋ KmzC<)ςj wW=wwz#up- ӦȞ(v!#{zѾoarQT/VPA#M pѰ"z ?\'+~|} 5E~Iz0w_F{?|\q+:Ⱦ@yC*:ohHĀc׿$)+9_GMQh/v.^8ٿIؾ}}CEu=U^ ?Kܟ_ -i"}&u)5m`}1߃ o#T|Ut07zσq䯰>LȾIпO+:g:,c~97|+p~ U3ӟ>7l?NjqK~ogEap,E;EV 6p6yp=2߆i ?p~0{p}CF pkA\Aﱽt#vߗx?hq(ؖ#sL ]SO Sz8G{3T?\o\׸^Z^Ai5}U8y=GףUc~ Sʏ7t?>7ۆ؞q\Mc$GɴcǝW8;?B͘y_S>,8)޿~k|^ S֣;Ike>:O$O W2ltlﻤ?q ?05"Ĺ^9Q Wϼ/oI)?8`}\KY:gup~I%7߀Nߟq]!/X/"'Lj]$#y})GG|XGs>omaŋ(|c~Ň60j\#4sq\?'%4_9՛)ZEhMv ^1 9{D-Y<Ok_ O8œxD("DID*2 OO97Ŗ;bW}qoGCq$ʼn8L q)ĵdw^TDULD]4ĈcMv?&q1!&mSbZ̈Yby~b^,E rKZkenIFKݪt^={zXݥ[N=%g@};}uWӝzM3ǹl=2~ԾٿjY/ucTg:_|osn ЛzKoᦜb)>>GI4| g8'T3}/E3f1瀾WZo1m,lB*.쿌bqo׹u_|rXM8~99]W?fٸ쨍n,췹U ;:G_ǜBR37=nG'8?ŜzZY;]^ӈy/%&VׄYK(ZU[ YܜY̩UPêGu.բif!xVjE>թTT_Qg?ՓzT T"D[_JUru6Ֆ/um}v՞W=5F#uNԩ:S\aqυTWY\ىg歺SJZ5ٰ)QQ>75&ԤR-瀞V3jV}WsA6Sͫj[ΊoΛFco-h5mtѦ{Đ5f8{teZ̳(=jmlm9Յz}fǭyOY3 ]lg^+e4x4|Љ:R&T Md,jkݓMbRU|d/.39ԞY7flm,^s]ǵ94G؜SsfXs0˜zE}mnč5/˺;so*j9W8KY}QךfaF,SzɞcYЬȹ̈́4Ss=w9kOi%1滙w {Nrrsu$S 3nU{Q=b9XsrXM͔}~sΗ@tȹvmߙ4?ّ5O3oMWNLYs,_f4?15f8?X_8,җ{FMێ5_4RV&e/K.WTkWa#;d|XU"\Ovmyd붆T~P JOLؾaY>'4Rw~+gwq_.kRu{nt;ަW2lvfs"L嚙e_iī]&u.=lrCn-m{\;rW}y  Ȟ1s1bristol-0.60.11/bitmaps/digits/redled8.xpm.gz0000755000175000017500000000763611233572001015705 00000000000000eHredled8.xpmXV}+Y :X Ƙ`9g&|UWp<0|_H*vU@XYuy~)6/D:VoώŰI$ }-6vtd+ lG%`?e܎x(d܉8f܋8a8˽Ѓ>.7K |{xqxq)p7Z^E: y~G<8|ܯg>W C O#aG>fDppNi}P j{~_Vgz2ۻwo2{~'W*\B??J طWjWW}ƕ20O{e<=F֟Cxޜ?y]>\y}_y3둴Wx^Z sa2-gigQ=y*[C]> Ae EUm:1'k>w !D{C}|Ny)i_0ߜ^`>U|r|8e<8||ٞ/.?#v]k#4E#vǎ|ow8q;.;y00w 8ps#0ޥ~܃8s q)Ȟ{M'e1 ׍|o$򽑡~#Z`oI輞&^G0 a +[P5MZ[_\QqO}Ѥ.Əˏ=?>8p?w@h^C3_İ7˯kܯ /.~jJrB~e/*'u_#󏲿xHC8ާ>!_W} \$qDg YQ}gF{h޿m`}1ރ}70|~1E>߄9>|_f}}ߛB:<RA'3_z߬~~#U29}Q#BvO#h_@`|\f>]y|Y7(X(89}gEY/ }靖8}088qoqK_~IzA$[?_xl͡=+?I?דO4k̷9;}FUoOW9`ߣJ>c~ >o$ap%h_)%83?0?g(=/jG7o)sA>'w'UO0jϮ~ ƫ' IoO? z!Eia/JbĭOt&ĽX+o> n*ŐXzsD<@"OdD"ĺxsSlm#vŞo֏5gUϜ=D3} %VV1gI_kSoe[lzfqetYl9/ϭ{m/}*쳚ziqnrfs{Z1 9 RD3uąSjynd+T2=ͼ-={lW#8Ċ0k۬5hLE%hԃͮ ̢eyZ&1LnzLHԅ3Z7f-+fk̾90#JrՑ9v_Ssfͅ4W|r^ܘgj4j_5W;sM52 |rZ2[_m|krVŔ{vtoB΢ӣva=BN"D= 9\zg?{>sRMj{޳*䬙iQ3f'Uh&̤l̴b>{ 9gW3k93o>3f*]V͝a֌CU~HiI7(iZRgMN!e<޲'l+׎].OOްuSaM|$G䣙ōD^w'mUmO^.O}\rU!$[ A2]k_rF2Le&_ru!7Z̹!Ŗܖ;rWF~)N'{;5з_R VXk+/bristol-0.60.11/bitmaps/digits/9.xpm.gz0000755000175000017500000000050111233572001014506 00000000000000eH9.xpm͓MK0W M&ĺ*k) UV<.,"KAM)MO;sC[)`3 7sl{weǝme8eMp>?]cqncF+8I? *sbristol-0.60.11/bitmaps/digits/kbd_b.xpm.gz0000755000175000017500000002273711233572001015416 00000000000000*ҺIkbd_b.xpm\iWʲ!m!d۲IBs2Em 6!鷿]խ6wReI]5uKz˫_v.=wyqwo{}q{w%zƉW;?303[MY5a^˫9Z3> *σUVg~AHe(f̯+WQe6k0ʣ~~1TJD8U_0Ic\ǵ`V> j1CίY\8ո߮WO*Igf=ZD~[$ /WD'|3I"Wͤ5yŐOMx$ &G"Ei%"fL'/77PzҒuj OO G'|ԥ}}w_哒J2KCiPo'yo0~GWӚ,7@~?j矙j).ǓBrrH, ~c"pi_o++4FzD)ݑs*U㭴CrS:oSo }߷yYmO3OesiHGY)i!e>~dEE}U1YMڛ dBkNGY,4b/eߺf _%ׯ ߤ<^_CӒxSᗄoq ~Fq}{Noi֖;Ss]Xs:u|FG9!K9xZNM~+Cwr~rȳbO& [Ws1rc|#᛹{,Ox~q^d§y3\>4ϥ9AOWiߞ3чի޾'&V=qCz&]t _u9mYϥL_!ʣސیg&6E&77ύ.[6Hk*oKCZxm^9*x_ 6莰*F*Z7OgWb x {Nͪ'(YmM/[V}P}jalb? j4-)k@2^YC&4|@=QSEXG_o'8>)‡EZ>oe|~դ+rZ@kߢ!|F1_ _'§vǗahAmfEҒ[J!|UmbB p]9?.?V>7|XH-GEK^תxv6 OUoS05fEjh?ڢ_`O[ʴ=1^0I{s>ߊ ߞ_Uryc5G/iuь^׉GwQ WBQ@ \{^C q`w_}A_k-вkYiYǖ1#%$3~׏?'5h"I7Fމ%ʉbS"޳=t+ IbɒH&:Ղ50=k%h{$h=KQHNW<߃We,Xւ"<#B3qkMJ{=ҳuGB9Q(QꠕE KMIf=DY2CzWa4kAIa:& Mk@3$kL[O4ٟ8[7,]* 3k閰04.<:ԣS$<ѻ]luU}T@5 sC;ψ:bI?~?a.G8}F$ցI#ldkv F"6d_G!߯soߗ/U䂾1+2(= cɱ<  %t\XBo;Gc#$$3yAY^p{ @;RH,E$rܡ 16jDtOXۊh"Zv\7sf\]g[9xOJi+"’`7L|?ӇpC| +[tyBsP } >X ~tt)IK~S,o@7# + oC%O?U( qcP aD,@41N6\Yq.0]]D}kRR"Gnu6:vٹ5CxH3mYP;}K=]xҺ[AT!<n+;j%wHЇce]x$s83K}~z y>|_JY6x~nܐ]xK[xN4^56;Nm:xMiqkH{G;ώ$JJTvBjS9[`ZǾ=CDSڷ3"D ! y뽦8#[ $_6"A>r1R9f)}zqi>5RJ畕OHNmD \B>?o#X]xֳ9χ ) I;_א6H5_͔_>J{@j4ڛrl6Htw7h=3_h)x _D%= PiA 6xR>-ڐϾ7|CΩ֛ ʔ]K'4[2n:wnȮItPw-!&Z,M& G6y5IN-=1#ʱ<L@DbOO vdGk ֧clR_3d0&xcˈμ DCe|D&u.2!O 2\ѹWe{ScĪ"ZN֨MD9;֫T9y\)vft}#l?Υj}M:tv|dRYʀAH?#<=HǠ)Snh̟sg2phtN%?.k]_Z/6x]+߬YS<#{k%ktI@aUݯΏ ՚POXQQe}կD:wz#k=TQCzÄn,(L[ #k ,Cu| "+-AQIM[ElĊsWVF(QSwuXjzg>uX_(#x5Y6OqNjm]nGJeE-9kģg'B0r8 L=^v|wzȍS%+i7eKi߮ i>iL(YG*?I7cn4T4LyDY7mߺ 5-Akf7p _8ĈtM[Bxs!d-u;ќ[&[-e‰SlT{zx}8 iin*Y2=KPdX$;+wEgV3юj -_#2El%QNxX)48Hd#dn'xsԱ۱zroIj|X7# VPȍ4z2e|dW?PyՁGMJibL\w$])1qBi8'"UX5E}!2Ջ?=`O%!+t[eLe k԰tOs쩓 iL-yk=;OlY!nc䷕Xiރ3bG>JύyAMrH+#!z*נ[E3ϡCB׻FV2zvOh)n\Jz.Qekkgq|=$D|d?g Z7Fe/B]+vT4jdiS`vXq忬wT>ڮ΍t陋5|{kF6g'"xd :F֦6z klfl#,g`E7SO uOṀ]OB̌znȷQjpbG>Z!SM@VM$ze]( 2hx?Aw#<8I>ֳ|NѵVx&Qx6Tdo;#>`kt˵ӕ9S$nm*)|ԬN8O~'e yҏ{a7t??/hL QhTk;s;Oh~8Y[䦫v;?η;yBBb/43S+e\j1tgT~O}aOt`?}Di^9ٰt<SFJPK;≰6G)i%s'X>T41&7~H'T}>[|l*!{tbOڭ"5wq8%zJ';/cevm䭇XG_Wb BXcMDIy^3RZ8x1)i͒8]/|:urc鷺#}5s\o\Ybێ|x-“S(yԁzKKZ93*U{<ǜa95":ÓlzkcxLl>5hhkActv7CQ\k0#29w=}X ϥjKs;yNEقAV>{2|d:vtlDrnmrTw'LȨHf;9|myy w>bj#D.'"qo[>=yA38FZ%1KS>@4Dٽc {X{xRWexJDU4ZofdDNwxwɢ&>#Ƈx+6e3{MVq;:±$=Ȱh[W:UDB{zh ߙ^i5>Dt Qx>`O{siZ>tU+mJ$Ugz[ =b=y˺*0-Kl؛Sx?|}]4!%qJy,iGSs33jh@ЛS˹mI4[ )[}w|~d8J[4FߎzzXrv7tqU:V^מJtJ=^+YOO ?< +AmhHu3R} QWmX+*c 8mOɱ7Vʾ/Dޫ=*,¦3to5s1oe`h9DFE\.DyHVEDw==/#hc{={oWrG_YɌLx~ٶ^yJ"ى`W7,L.ϝwqH1z,-/P>}0-gY cH7>1-N63N~:Q<1ǽ>-=x /{J^xh?CC[osK8AmfTuzn?<~3{1[;Q \:ozL/@+iݳѧ޲\{1?)ψ_^ӹ.\U4m.k˶}s'sm3 n$"{_{ eP/Fcbristol-0.60.11/bitmaps/digits/0.xpm.gz0000755000175000017500000000046511233572001014506 00000000000000eH0.xpmՓMK@W v5FexDA~=w)4vLCv'22ts}If}g;:|{#O_Y^Q|?iחZ;$ k tH`<2j 4 XJ@<" pZ!?b .6vU0kSN0Lneq.̨%ss6,xhA7CGRSS,F(C6 s֨*10lvf#7:E8е)'|R?/M8i.Qsbristol-0.60.11/bitmaps/digits/redled6.xpm.gz0000755000175000017500000001020411233572001015664 00000000000000eHredled6.xpmXgS|ϯGɁTڈL49cr4`zNǒZXonv֕(ݓdOy"De"ώ:?+. W`؃_ ∱짌[;njKÈ}}:Aϭ>^n qqr/冗xIWb/!N3ν>FY (?Cho*;|JpD)p8njOQV >Op^f}mٿe6~w'W*\B?}?J wWjWW#ƕ2;fl`A)qVB8 9:.^WWh5ڛYA{3>-ǵ9߳YqT @4 \58*hO?5S u'UP>YcWq^/p~C+zU7Sooӈg_b=UzrqS|\ ߿p9-#v|[+ȇ߿8e>zS3#vp;;:lgFև_Ngp^z_EХɿ?=o/=O_G_SDW|Иk8!>C; ~V5?gM_|M)@PS=RPM>YZKMȐQ-BF2?\=6W?v(?vy}{>+ 9@\PeDǕԇwP,: ꛱UԷCW#ou7|E}C/X?P8C݇&X_CL"v`yTIX\ 8r=}xc(?t)F cܟ7D9~uCyyeytz%>x?P߈?Dy#=X؆H`~>E}s?q7r^b~5l{^qr[*֫'q[?]=8}g\e)WQ/n)DŽo`|Q<>_П_!v48>zcI)E|7o}3d?7K38zSğt~7> />n} q[o|&5/ C>߄9!{x|0(;\O%Wmy ᬒMye}) Ňcn|7O(Ϗ}Y>뤏}zuKW 3o|b#yp) zP>O{^O+6 p3gWzep'w'nNswÇ,?2?Q_gS:C5GS.KCOPO׀O,ߡ|~oߙ;y2&>^YKH~MIG$}]:>%o ~w*;~{uẻPRS~Gl/;fL%?O2߳rOx?-!o:]ku<@Cԯ|{Rl{|ꁾ'3r8s$'Ckp=ސ~it^aGpOEA~<=?^9H2y~|1|uz q$O!vӀ}'_e)EON >1(F?e.#ċxkbg ~-6ĀE B'O"R\xbKl(sG=/ġ8~L UL(%{[Li1#f5D(͉y ŒVֲ.VĦ TFKݮgD%ZúOݫtN6=%M'fe^،^RG^\zC!uzV}\}?2"ԑuS\_([z[]wma{z_C}kH 2x'Ts+)q/GF;gUA?2{DEWuMnQ=rzB6=zozNwe zQ/e+?dlܴ8U,ԦE+s#62JiZfZ-gSV붖d>Vex^:SG֛5ՊnM斕9a=:f=JfvgݮŵЭ찑)`GXNU2UӯsjD،6d٫T٦^ԓW2ԺWl9Ն2ԪzVkzyf&FR TDbTZ{!2YfIg*WRb[](WoLՁ:TGXP'TR% M2Wř:WR]kun՝j=E3{璸W?ՃzTeUQU+E#˿Yϲd :U_ԘW^T:SYp7zJN=ՋQ꣎=SjA EߧĒZVՊTuۆi1Fv^sm6a:M >4#t̵2Wty1Ofخ>nM0%̵2̐Y5|f{$/M6Glv̩|5lWKS6{n{dy,UԻP濙=ߟXQ濙=ߟXĊ2Ċ2GYܾhZ=qb}\2Y1FH-[= S(FJ.;dle,&NEQòO+[eE))tl/Iu9d9ߩ~n{jC.hI&5aCrLݛU[ Yn{KD]l~ d(#\3'bT_jZ]٦do2\z>&ܑrOro@#y,gy*乼rkJ^y+?_)kܶoYVdUd\5 9*H/|{ FiRN!f#vuHΖ_:yg71bristol-0.60.11/bitmaps/digits/kbd_9.xpm.gz0000755000175000017500000002121711233572001015335 00000000000000EҺIkbd_9.xpmZgw8|W)aR";g Td)qߙglR晆ȥOKony[6Noջv y=;:a0siZ}}[|?Zw\{ UBwSZm8$̯* ?>vB/y'b䭘Ҟu3໭ @?섐FAE?GkK2~݀{*Ot2? q_A+N ҮN/ϥޘt9V TU?S̿ڣ}(Q֑7hAxwEpI}a/,7#OihzwGp&/A> 0}dA `{YAO }'~gAxY2ȷ[iϲp{,{gACo,]H!QN""K%w_X䍤=ɲ y[k$2wR l[(^{}Q)|y*2_;ߥMA{"JDo|*/ݏ>>&?,@9<~gy&x]x.|jKi+/Ck ]Fϥ=zYyS;Nށt̗KJkD/g^z]flu3GOD6&)h><KGgTY|5ZSz}vi]gHNO_'_JW-XOM:~#&7B4kgW7 d8ie4GHF4C7fdÂr3 ["wĿGB)sC_.ѵբycV}WR~c+襎A&gy{މc/#?=̎9׈U.X{QKF?-4F;2'W0}%RXd(674/6"m": ؗ,Y:jА>~ۦhfϼ#Eƈ&XGHm,fX+$y)#9dSĜ(eDI!rxH UF$L>Oy)#};+~'x2rSdx/u hYԼ#<5R4ς*y)Z\Z=~oI܋3 i24ψV)鬥},vϼb1ݷE&?H[4f$qACH]5+VZBD؄f{AX|sUcKߚf OsL!K%P!|_cͳcDET"Uꅂ2i)-sK6x=6%׆(v~kVqx)G?6/f4 πTIT^V#vM4l> z#͉Ҟ9S^',R&I~YhJZ˰4{"JL;ޑ,1U" 놳"yݪFoOØ϶mЈϝku0g-M,Նޥ63Z$$9| F 8~"2cHf_.BtʹhDЌ!!H J@$*U1NJs?>ki0S{*˹Œ+L"CxH}(0wxFgUXѴ0)k=3]ʌ~MS3dd,&"ڢbD7gzQq5DėxFE;;. UY:M;kx"uq#<RݲBh"QCs* w陶(ո" U}GǨy81I<{ksxz `(L0{߉f~H0 <|RVcmDyXS/̮ks!r!})U8J4_/̮>|zY wkܨW;UW?O88DD/AOOS&wG#L'DiOvțxwyi>,6Og%nuxV@늇?E+}0q>-kZ*qGﭒ.9)^$UVk!]Dkӈ rNRrEʵG mf*1޺gz4+$uwr#ځ3I7XB,?F6&<\q1lbktaFym_yoVTW*V+ CmZ~;`hNxjߟZ  <?e./$:bVAl)o@Y],z'L[jTɚbaWn77m1ߧԣMkFUIvuxF3( J%|>'4gw EOHw4~zTDwagL#k-7Y:{wH7/]>U;SRrWkɜ`1 eGMR!8OQ٪e4Q] urzADqOש !mR/ןך9E=:oziO*[x*}QzթQE4g'>{~fb==I7>cEۨGK͑MZӬGYJVNc<+7>#Aϙ?Ahԣ)j ]oEg:OxbustZogPbqx"-v?C=s\O{-13_sҚfQY 01R֑CB(@?5wx%X~maO<;zZGU zTUgYez]ןE} |핢9~OxVd;-);4j~\Z2@iѼ,''"ڣ+8Erun)?!bpfMՈ U5jo7; o"Us-Dp P_˓[{>b_wrFe-ۺ+??a#ĻFN'h;<+'{%U3}R:$nZoɏ <|nyrJ>׵.mǭS?L͌:?w+Ќ>G|~W>xb@TӰL\#o̚?s1"zpjx}'MO׆wh<$A mCϯekFVw2-֚w9ŧUwT_~;Ľ!"σ_yϑr0T,1~حyQc)QoєYzMS/E#o- ε8SC=!^0<Oeyo3Ed rBg[/H7[`>h8^=bp|{pG>r`)TQ72L:E.Z<-Y?"KU 4gBJ7FZ4IdwخL+'jdR3yBxx%0g1z}=zxָ*+Yv7<ų΁)/Ilu0\ύK&?FY&5dSuU(.XeTsJ%(k=+x8Z%:{BeX?G7ԏLޚ3XuN $o @W?5?=}p5'y=iOl={xNhFnhțQbiWa"S'WAv1[??^jx>%6; 1 -X5:#:F/FoϏ쳰qIJ`~K?9*; su۴?' "*?[C|=aA#iy>ID*<=1%=}-{cGwzt_LV3|ػ0f!==/?Y"VM(zU/xC[=G{zL>]bQSB{ܒex?].<V/Q{jf 1g}9O,D<)L-|U45ApY[(Y'PY'Iş;'i2_iUhZ6ϡ?ɼl[Nޒ>ݼ527yhfQv;B}:&s&>+w5o!Yw(ʂY&\X!R(~*=ZKo?5_b5T(iE7 'keG6;cyzZeK=Xp\SX򍆧j']@[v)zlk5sTjǨLSݎo\ z5%sy"^o.ׄ{jwB#vO;I:9c_X7-w"p:8]GDGVEI^&*߹Aȝ(C1臦Z[z5~>h^D/^;Ӧay#9S 4kkbnqhEt -fhϠ׭aڳ}D hMIM)dxD oBy42vJ^Q>/ l0">|#Wao[4{KS#eǟxsOFIT*n'+A-mU߱$ 'UI◰oyL瑜tj9̚w5wvtVd륹]VϔXL3'ʺʑ&h>qDde.ZoCW i pD=g/N \__}Fd>.'!Ou辮p&16Fk+¶L$#^OBgN*iWvp:ŕ淅O.`?M4e$z8k}ȎR+83y"х۠}*\[xx.ɏF}/kKY:؝@ ;N?lcrRԎ~q"<֧ َwG,~:p t[C^ fJx">T WK:_ca uV{ߦG$l,biݭN4.T[=uD] oAko;YKT2@ #hx*<8#ql:e˥HO=,"+p-*EP |6@1iX[~ɢ xloMrP%$Dm}'SwU7jvtq]CT2g\^j07!/e]b#XwXPXҔmAd5)g'*þP_xwZ5T C7s{Q8|{Rw< Dc#"54ޡFKWw|.p5/ *'~R>O ƄetWxcZq7D+tӘ18D;oѧO|Nh>_Ol8G5S*i\vv)g,ͤ|LO0qC/Tt\q>s:C|v=C^q\QPՏvN<$YJ{sX_yQWu"*{)Kvg'r³},[<ޮ?zw<cbristol-0.60.11/bitmaps/digits/kbd_0.xpm.gz0000755000175000017500000002147011233572001015325 00000000000000ҺIkbd_0.xpmZiWί( (IkP+㮃pA߈'"^5љOƞ9O|;69oosc5oѻ^z/z GfAav_> ڠ )|/z)t< d9ᓰ[xyWQq/zw}qamO{Axa3/M^?]Xe*gUg#1ֻ'qؿ㪟x}?K$Q?_? %d>L>G^}o&Ix"|T"I3ȟu$$) _ ia_M]?O>o4MȻ Ч (| Q}U> i>ߵ0~5@,mSH2R(|E)HǴEƃ3,MKD"SʟTWLe"RM{Y}cy>#yw"B_RIfx-( , [y>1ME2%y>fmVUD,{z}%9_)UmX}yߦE-9h|!GQb?.U_;2ߏXW- }y"_{jeTe<-*n?oCCm9ReX}_,=BDU%j>9U(&ES@?'hK*syax [J4~[ykV*VWqٔꯪ+C ++Dz~U{2%~AX/*y&់)`П_uRb?|%=_A_2zxAM& oRG⛓-|U'5w^. V.O./JVyPS*55yB7R 4In+e4F}>k%~mSAyz[+[Kߦ?CO4,[c~_֣Me?R7<)~|n_5/Gڼm"O e{>lsOv+y۰D?{Eؗ=P|~;CCY/"ydĿx-X*WЊw+xJV}oGX.v? +_&+"~e?;Z3˯>͊9#FthC9OˠUo٬x+ޒ15stId*S~g]-{hnTUn~t蹑x5ю7/z$]ER16Ou";f#sDoyj&ة㛷w/of+?[EIw Khν-oh9xn)s? J'wACߤߣ]wAv \ӚCj6..:Z$KX*ux|B%4{ސ4zm }_ ҮL4@vC Ɩ/s$xRDD2336f$5uݺ]wuEhC'gJ!4A#zR O_ў0^*($ H'Q+X"%hb-2.AcSu0WfhޑkKnH2}Ђ;C? $,CIcN&x,y :XB"Ftje&o{P Vva]#edD#~4v6I B&L)}f-6֘2,EK+#"1 bcby-lj+y46 <GYLE4 S1C@oǟ 9%t7SakE ۯRq%"Ԑ_g}G%mӶ~jdL;&}%4cMGm'8/Xz!]`:V)?Ko%5j4xSKj'VD{O.-WB%t4LGRf ۊbkTbAĶxL4T EODKLX; iSϩ'|Mv<S42hܞЩS)ZA"j !"Н c~Fڂ`Ih ρ O@8^z\K%k3qx5Wp|rĈڎvjyQAFk"O-ʧ\Sn(gVG'!kQϖYկxgoXy|eEPY=5L4P)&k4E֑X!C5cocsARLi⯚fzO>kБpNN'PF}Y'Dx=0sYwZxZ񰭏s7FB8;DGOh@":]w5EtʏxLNJ;W{;Q& 1{ۀXDZY59ts}[[S; C)v;avjLV5NmG: "G|$<Lj9uӮԆxӢyǂ}=X5YDciJ`jJN d7x \<-m?h؛wx6Hߩ!K'~26g6\>-]|'t=ɑ`\|%Zv*Tɱ Pf}jW`ju['қrL!>93@t*a6i~vw*G (חCų_^mgw#2LmsKn!#d;ګ!-YGJ95X"Q LzT8XwLOu_%XڹOZ[ܝ8E1xl-:VBهpLQ{VeiwϮ=[Kϡ'xf#n/[XZz4s+x^"{mc X'}.U<ߖ^yuܝF>D\6Z­ j}?R\= /p5*xVn;uxV:Z.k{W1N.6ۛc|3g(9O<5?v[ՏgYZ%(\y]?IJ6އ8;V36!{>'SVH?g{<_Nػ6_nGWW/:#8 :u]I Í mHtL 5,"# a̓_ }Lc?\mS~Pl0SNYK0*^*H+1aŨ`~O?9gXov?BFf3ݧN1^հB6ӇMzX[4KC[P̣-?xauA4.xo&lO@X܉:<߀gmh)oQ?UTX=`J6tZ%-z4紧g4SYZ7-V.^oˬYs( VB{)K .XcLs(b?RfTF$0jO_`izVqAgNǟ#g/ bUZYg= 6HyMgv>9:<6Q#'/OlBeB,qBmqgf Qq5wd!uo$۰h9/\,G˸OXӏPfQi[! R >+x2^XAwݾkldxzyӊ:]#ЄZ_߶7)0W%;W/ыcu mZ#"xJQFq?W0c9:TѡL1 vx-KT_[g~X_l=xA!}QJ՘Ýϙ[HlEYǪUx9DYVb'q)kEޒr̼-I;l-3Š~GP2"Ⱦi,\Z/|?Lef{5VØtm-h-z9@qMp|!gaOksouy oH< :ywI H39QO3?F[V%EGkb6 x=}}HP#:s{3`e5J͏Nǡtk߁ң\N<9{ۈ@fI+ @A)q*uhNTO^'|x?&˱MDwkma KkXT=5tB "Ӆ^=l[b&gEkyIYʾC%|1Dw^hc|͸eSt/<&s1϶3=wCBu%zr<־}l,A.iM&v)y4$:hɼmys:/uC Y@ɲ[bu}/ K~t{«Tҟ+v;gc"!@wV%G8Afhb@mjpd1H6+Qm%E|3d+Vm VD(ݍ?u}~OD]pt< v^xۡ]šv]U$ڴja,"*^J=x^c Ȝewmxx]S}]|KBR.LmyVe,# x$Tz~'N%à8:[Gʳäa1pA7P;|:N][~t-rf4';Cϵ?w4u?r}h`Gj 9=loE4,c&YkYbݏ]I^eA * .,hl#]َL^Vɾ%8UצE0q4fsGuM7K \9qr^C+qj?GKmUa=4,~qD%O*n|%{'kVlx^6裣CTuo5=.>9zW5dQ_Iٷ?dw)4[ț#LEmAu^ EGIHr|Ixφk캢?/羢:G+)9-(z/!J33dccA^sll w9П8z%JgXDX fueTvT\7/^4QCZУ]1I>CXAj“}e/KRᰍ%$Uc.7h;R5#P3 d-6֗uF~k(NrD˩im|ٷ_{]Ǡjz@Յ`[`cbristol-0.60.11/bitmaps/digits/kbd_5.xpm.gz0000755000175000017500000002144011233572001015327 00000000000000nҺIkbd_5.xpmZi[_Q^ҢkSVFg0Ⱦ lo#Ήƹ!:d왽}O'k'ڱXVLJW%_BO(׿=ֽF7 >P7Fm\ca7eƇI~CaXxcհ gGi/Up<$G K忑φ_/M|JEA9&U"ɗD=M|+׫x7)MS?a;?8>5$Yy#W&y 1{I'$b| cIcz,$$Δ`xCqGxߟQ~ %'M<{ߤO4;$?봟@?#>_97x0Mb;*Up~F)~ilf9@{8'_) 7^PK_3ٟ_B|OW̯'!_Q؟v>㢿%j03-O/ҒjSTͽ_4ȧ^d=qfx^P$ 3KΗA kۯl@zkwi!3'//|x@>,>Ḹ[gY73Sr?p\,y  \/~/yPx?,rc?EI >,:~m= X؟[\j7'78aW]x9K}Gzg)|U &ss~Gp ^ߐ<)oL|}IXx>q|>u2GG>zk2ִu'oc7~M7[\/S6yUcV>o{od۷-z灭WDNi>r~Z׏> 1䫼ΡO&O1ȱ'"a<8uŠ=>?7}qaQ$t reد_9ycOM^F oL& OWpS^F>,nb6_~:|q<.c- A.3EAe8}T! ^H:w?) M5>=/mJJoU% A+یW%̫Y,yIW%g|,<_ |%s~-x-Jyo󓪨0~ |H|٘}]}^wŧ4b\_%oIد9eT؏U5|Z7 yq߻7:!q>7"/9? /3$ijobvU7!5}KM|%<{|_9F~(ofle}Li"G;x%)i'fߩ>>s\փ s~\>d|TěR>_p~!{2 'gBB=j%  hI}uh]^}EϋKoEbc$t!ʾBˆ粥 XcT]A26z [5'ZiD#Ȱ(}::<~#{-kbk ohqƂ΅@Ot2jXhNy mzwXKApb!:A4[ER>(s ṏZjţSMih.ތ\G7w4Ck^'hGoIhm,N=go`?)ߧU'vp;49ߡZu$v%LGKG?wߘ~/vs_a!Y^<ֽ{ ^};$n'b3Qәxix~z@364?EgFRM]O`3 ]Ap˿ >Ǒ S&>uw[hB+"X\֦#>|z< ՅEuYs*;V;{;y)k=*U UØ9 >Z9xpaMhI𨭝W3QV[an bosӠ1zwn9o-Q+κyOfG0|S"L FYo m9.d̞ŻImQo}t 1V 4x(nhNTN~[qSwķiַ /w[uGwYG !? `WЬJ\ce,x~FXj5t3(V]@ьFw}p`xbd X Oѝg e%L;gzےZy;nuV}f{{ēX44gY,ͩQ 5n*NOӶ>xjv?JmթvmfijYL0/tӐ/?'˧'~bĖh6 -^TY;E-^l={Ӿs<-V_wLVmStzCP}B ?RX{m4|xV۸_x>Yӿ盝kp;ݳcoi؛ N?3H}i}h:u 2ķ~^ISL{ɟ2N< nGVCu9ɦ#8;)aei7G7J#;a}?Yt^<Iilv jvs} .kjE;Aao1Ab@%ãIz:zƳҬQ]+"Zݖ|Iݣ*xX\libh5(,;=?3D"bJ/:Tg6 %[=]w';goOf{,~|N|Cd֢< 𬠎[l~휿iuAзf OӃjgJ9Χ'vijgoz xV3Dv.)Rj7-g|[@>};YrtHi487[i;:x>ZFeՁ'n{g%`Y?yn{~"'󎑻qO{sB {cJty}wc#UnV6lOs<Z4ENGswGAk[)ǝ/._3۹զ'w}]pjGlwXzTKDW5fSGyX"LΡO'2&Rщ7SPm9eFvGre{]X}/3řAm6I.:|foSw;mot=gޜO=v{"X΃B|s̴ûحzn+yg:&i>ԇmͧ5ckoM< a?޸coѐ=Wq\v𽎲NΉĺ.Z4R7_po8oh]v`j{nǛ{gbYeS,T?ڵ+Mgţ3D}0['l%,Zr7}\ltlYu 妽c_jC|C:4]: C"-7eRk4e˺s%de⣖?}!F&YH9,:c?LJ[1Qy'W|S32ܛVҠ=xK֋UOg q8ԟ[G6kRH% *Kn3flc\>lŎO1cA$zh3:gΡ~O":D}zMwl/ K+^zhz>׊F+׿aջ|vOYWH=lt3nxHnFx <-e^zVV?c>R$3>'H?)I kgg4 7ӧQ@*Z/)Q}asȂͥzb1:xhY ¯g;=t}zy q>;UGf<=3uYwC!IԪUeDzGJYyR`fK)ZD6AUuϟ`|;F?j[o8hzjX߫x Ǻ:}#jηRgۣ2 -CRSe@{n]ڃ<8;YAe#oiͣڣœ K41[<Xpڣ%V\=vҎ&UeH~̧sTVZ-3Sbr.dKn{ԛ155c_>6q[?.I*sf5Y\ VޞgH[fvh2"":Mп~2AGf}n79ZsgDƥj܆9K'^Kf}_12cH&9l'cgZj?\s?xeğ>ԡ\UU (k)*G'}"[ح#oV@Q4sxτ5}u]dos_i9B֜jD-^0Ğ7%?P2M:5d{OxʬLMJEWjDh;F:S/{C#ݘ=}fN{j/ Bŧ\r@Am̴ Ipyې6X#NO}0'q#c?٠#VoS{|7#^`/sw$}۲jZMRxdmz&7Ԧ0뺉J&g^xtYIF^wO#,eԟ1V~9cR,[` )c߿gKG5kvv|uXgPӴvAo"VHZ?w$>OeP kdʳ,9IPH R(>i #ɎG;pIk(f7Jzl⯠YSJU/9};J̀E1hF}br3@)#]Dl9/2goU6g96.W(AC7>qMKy01=*WG^'ݐw"B$U'Ttэ +DhcgWpQL"¿q{q ؕMc8K<2.͜k䃇^,u۝~͗ 91ƕ031H0mZKWG<&*MdȯO=A.o(>Lo(=(ԿmӖ5;Hn&^3Osy$)5ydy$WUHKSAlL"q$꧝ ޻v(jɉP2GȔsc1Uz~2eJFA woj+Ƚg} F2xw6~!E2cV͌:GHZckOgQ=oيUG TnV!zbND]O-/kRDy|>o;ԫ]h.+܉}jVհ:.hxn+"2Cxv߆Q{)dFwnƀ&xq׻S#;"8 KM`;k.LmyW%IzGvqT~'vɽGdGǿv0~(laa1<"[XKki^ ,4>EI6mZx]qHdڜg۩aRDxڰFjUEa]4~w!joG4lccGKd?0 `\+Id﫰"`z'4іHSґz=}׎0t02 ئ%=wN 23ZJ__%l$nfGElXƴD7#ߩS cVYjS"s~rQ=MGeW!ZNg!:IV|[MrX f^,ӽmE8ut]c hҲ@GNq iOSJ~pN+7e)=ߝ|sOy£T"?/A]2YMkbw fR?YYfez\_*Kcx\$j 3ɫ՞׏s%~Oc5TFav/V\lzdaZD鳜+yOy7IJ/~,ۥOoGs_1 cbristol-0.60.11/bitmaps/digits/redled4.xpm.gz0000755000175000017500000000734411233572001015675 00000000000000eHredled4.xpmYgS|ϯg` gIM0 &d~뽫:U~VQϜ.8=zܸR[{KllG뷧G+jP=oTTI’Wlɓx!rcKN"m#±.Z?&G٢pަŨ=e A5{b#ޗxOHߑğXΓ9Ԋ.BFyQ] $\|EqwS;®i2*=F|U~#aW|~Dx|# w} ⫉?ϔc_^?#+,RN9ĕ ~Zyуoޝ"o{濓?.?AcW"GNK!~g5wF׹a&X=J"̇+~߲,g>[ɏF [- ʔ/%ѻ $Gp)f8_' P{qI 5A1O2jp?U Ǔd/B?roςJ=KbȞy>Z u E8$盕e~߲1Hiĵoi/xoOoC\m~ O${~$sF49o7W53{I b/O4q*gp&K8{iq( {[a>>e{b'{NġoY/~g{I|L)>N2sz\""zڐ~߷M|o{ڥsA| Ӭ\|^__Yߏ3߱g{'9p:#]~| |}!5GX7ƷY@f,Tf> />Tey~~n~Wa~~%լ_2{qVP??rI)7E(p3̟2,σ"q"ţ$'? o9/pzS'ү5ȝo=ę1\Gr>s,Ǘq@|1_b#\2D&qӲ^XSO?]2/zy~|N ^e ^Ϋ*m~BoĵD_F?X}.K=2fF5d?%ժ_q}ކzop^QMVߊ~Bfwɟ???4`)o'KW=hPe@{YϟR3)ėu!>y)|p~EmY/nO[c#9<_ |+[05|^uOj=W_23BQjE3&R+?_T{/>, 3~S>՗%Hc%ߨa-. >C"GI;d(/b7տF\s,.!{wl qqc=' #^#!w?N=8ޝyX,M}Z#KwחߨAհS F?ץ_sQjHuF7NբNV՚Uj]F~)|3PT샑* ~ԶQMpS'MCu{lD3؛}Ӫs8 uԵQxѭ߫2 UUU5UW 5F j 3 *_ԸPjJMÿf:s_լSjA}Sj)qD>~eRmLRmF8UtAc͐6ff_UϜ-Ӵ'`V͚5ηV M0+2 `0J8/Th"Ĥ&3%S4mMpsl-mv̮aLEƽ*\U90`si4[%g\KsunΚ|{pcoV?e|oqZ=.ei6ŧ"\7pn09F&lUyscnaCέ ηWgTLfknE}*QfČb5o"s5a&͔1_ͬ3r8ռY0̢Y2;$|9@tn=aΛ|{q..={tݺ]w݌ҽJy^kWwujǸ࿟.ݧ~Կ'6yPu@lH:ѩtqnzCo-wT'w ;>ЇGXS=d{8i\s}/7q.늮n}9WU]7ѣ:L~p[/z\OIZk_szF?8GW=9#:;ל6c]h"mm;m V z`M}nRuUf{uvC?q.Z}v=GJVl<_ַ md_qAĦiْ- i͕zR;OMsYSf.}>kҒ:g)\=nNl \g^cլz΂@\+;iDs3k{cosIeQ!Ĺ-øwv)Nre 8p{][z3=f߁E*y=v)s:+qrN[?KM^j K7f>X_rl6Xxc}ɹ ߰&9X9s*sĎZC%痿{q;a'픝3 s)+U{v;k]}X?]߭=z gu›xrwXm^;]ޠ]J_Fcx-KM} yyqj+N5=QtCfn][ >{wkZ' tF9{ͭSv՟us^ơ?r%' ͝suf~Wۗ=eT_*??Ogk-bristol-0.60.11/bitmaps/digits/redled3.xpm.gz0000755000175000017500000001004111233572001015660 00000000000000eHredled3.xpmXgS;W'93l3sN&U kw┤>Wwʩ(!A(+(Oح!n0@_,B}\myp-2/+" W3 7ka!V٧0#83N"?!VS:4F3Ğn4ٞ ˬN| ~xo q-o#W;kUel1 >y =@}CGoN)}f"iQ̺yq#_aW,V_3Qohf q5fO ؟u,owDke G{m:wOV|ǟx׫!!  ShoWoQO?n3/O> q;a}.?~-s(eօ8G.G8qI˷n^'}{<կ^/wpCևp? v/~g>s vK}>/d|>-wG~pUMA̢>9O䯳seS~p|hE|WFa}L~k`ߊ^WQ<>TeEЊC/AQE?O?O'ns$q3X_=~?YÀm#~op]bz|#̟d`1z @yYp8}xc{ȟr*#ܟ)C((_R7铡Ac·\s~r'> ywKERh ObO qQG쳼 ? 7_ I(>GL!vhOOȗg_H_>Gp,Xqaޗ~`߄9ܬr>IC|݀c7O5Կ(?Weom(5* ᬖA)~X~s]ͣ?d( ݗ~?!y6ԇ~Z y7#=~?Ay=y+y'} BfZ~z O> ?ɗ| 7 ۟*b7Oķ7 ›W._ ;ƧW޷>ʗr~Ç:dp]|<%93Tp#a CD8 ^:pGU8O~7_PMZ y6l߸Io{,#|Dy{ Myw~428q5?菔ů_}?A;.z$ o5O/N!뷣#7_TwP( s<>|[IK/: >%goGOc':=o0ປ|'Dyj\"g-#ȯl{{$kV/ԟf G|.V$o~vkql|ߤfX>mZ/7.ۏysGy\A=ipa|x>Gu8u\uJR?OIIk j{[^1kY}b@tq+<â_,1&_ଈ{q'|PD"~쓈Td"X/ru!6Ŗ;bgǮ}q ő8~D3q..ĥz`7◨hhqNLz9Β|JLO"^7]3bzvFL7)gʹ, VhuquYpV,㐮Q]%='} J) zQ~}ʸGWڬ|aG}ﴯc;眈tHwYεW^ӈ~7޶;UzO}սsD3}1瀾ЗJ_q*ǜ%Q5] ԭuлbR(=?[/rWM?3zV1?6e=ב}F2jQJiݧrދ/VVi+G]SX)XiY˿qFi-Z-wY⤵愵긵@̹T'jݭvŵQjF鈳F*[!5v5V9+Ԝ͆9J;ԃU jQsVjr15foL#՝UvD"3QJTY4%2+O+ԺT;gK雪Ҕ( ԶQjO+󄳨s_CuՉ:Ug\S\nqKUUMUC5hNTYwFjRWG5Ŵ*"Ǖlf O곺}cbo&~x@ϨYSͩeRg/z0(c4ݦ<ekM QR bJ .v>`n͂Y45Q3l͒1O?9fͽ35#D&6)?Y5}"5ɍg^ziŬ5b#ffe7NkͬM'4(6̦2fg-C \sl' )^x^V}}s`͑TCPAo;_Ĝ3sn.̥o|\ST+smn/S55S7)\y+瞭 s%ez25E\UsfǸy7sMQ=c[C9ޙ sGՓ9fB#sva5H] 9fY햷vu*r\e5p|ֹ+Ϟok=|\;[f92<7{smsҼy=|\S-͔6g|58{b4w̘Y<3[皢zΙe# Ai\=n"^kꑞꕃ,i,ю}S>rTv6TdIWe]b9dYq%d'sͭ\rXn{5fOg)/}$Gk}Byy/y6d, Lғ+ryʹ*ܐo@hKn+ȹji_Cy$KߜSy&ԞB^+ky#{DYc~=~럩70bristol-0.60.11/bitmaps/digits/4.xpm.gz0000755000175000017500000000041511233572001014505 00000000000000eH4.xpmՐMk1EίxL^H:錈 itY("2EA͍".,r!o}BwK|Kf9%O$-(bZ(|ynqNctZdbristol-0.60.11/bitmaps/digits/S.xpm.gz0000755000175000017500000000050011233572001014537 00000000000000eHS.xpmՓMK@W LcQjY6T)B/)AЃhߝwQ IxlQZndi~tyE޲'9|7igLJɽ(`l&(jxأDd`1 hAP@<Ei?Ni"wLqG oS3A;Y6H+.tU1ɛJ޴gwr GץJrt9Jq'$K?$ߪ^#U1zj1ڟy 8o >Ƶ_Z_di7sI+>3kn F߁o4qOOfF<_y|ly^/fv 5ȧI-)4I@{ _Kj oOf/A& n"W_o Vrv38oK/Fǭv s NM?fաsxMS^& ;6#!wv&Xoq|nmמ;\ tkߐ|;.~߳tcƳ[~=S#RLzDmѭG'<>HwLy>?sSέ?:a/gq_,|>g x>I`ox}CP#IO1>!ɔ}i0ɠ_7nΆ|Ѕyx >7G7ZyJ~|/o?C>3"!oGy8񯮽iqIȋg6޽ߺ3?Rx}w|]yo~3?׏8~dկ'nۃDQ]H1&h*Bkчh9ړ;(?OJc\ 7?5O<3}‘HC~ȪI =]u\I3>d.\;|9fVeТLߢ r&hF5!ʀd;<gĎ!Q%Kk ,)-G G"/Gϕ|(JwTX7AGl=Cq"<텒=IE%@Ürn$#9xĬLz0e/7bE(͕E瞫a~ sFad9+P=#=\fj3;^0@fb(/Ξ@s+wzS R Eە! _[KVK!tHБ@t9RK#-)(+TPZ44v/ï V@s047г!h$o"x3XZg$9hY oGFД3D|"vF~DG{|*>kXTVM>ѱ`c?3f 5<̞7chMU?C=q#\8ߝ!X/ѢfK(H_In e F7`{dR.$zS$-wX@gDC)zXή!EuO97} ]{錠iWӨdnƬhAHnpUQE_hS)GR8C6=d)Ο#AO&tݼ} 4 =3ȥ9; CfíK$(#V -X~ÓOTF86YcFcKѕe4 {BigGBa0ؐPr 1PϡQLj91Qf+6XMь= 7hNAW踄fYtQcNմ7%@2 YMOa/ξ+A.OFcϲn/|:2F{[4hjJ #XRhUMt=Q΁UEn3+S,p,4 zֶ^UP4=4Y_#y2kdf^~J6^ Qr&Yuǣsq[V?1-S=ZJh]G -":o 9dgby\`=Ϫs;:gbt|T&dR2.* X%ݗ_ Qm[<ъ`O䲌 #;Xt:r[bq^9'xF4WeݶaV $һ,&74VJ'ϗˈuա*6,F42ΚQ60"b@4]HW e0)TGr:5BX 'rE-Q.DgOF=8CltJhrHuhPSz:UgF#x HNk2JnW l [oְڴ4;k@7<zu>^1oDu-ey4\ux@,-Sglnʜe@I,G U(Wx\pao=[[BC?umvnu mДQlyP '9=Y/*}Bn)KFiՐ฽=<=ocm' Mů_"3yrDM!dC=UYٳ5JN.\؜9D@ԞکQ5EUv <7<3^:T~fאp#R۷Vph8Jh2tlCW(B z z1W£էtz$y3;,N |,4MѸN]|;"g+CS+ɆhfJhʕܻX:zh9h1q)ave7\ o5C2 w+l Vըv>TJ8g]Dp'a(kRѕ;f7OVЩ^%r|r;؈~ESF2͈-,XmLzK25[QARkW[Xp'o,mG8 XF^.R~GzMfVkxu; ]]G/r>ѥ{Tk鍭{lkɔIA~ݗPza7\_o8`;nǪ>pnh|snvPC_\V¯հ.X9jmgj ˽0oeՏb?Wn{@r{/,r>XsR-Zdx"Ѿ mlr[XZ5<n\3) >oZЮUA,Ϝ*C4y&1r2WxO6k38n\Z⫞nCT¨؟.bM~;%^NŒL{![b.9f;qX|seێZתPCysoܟ_b{(l/7[g)? FgmVzYмE]i)_BTi~ekDu"rx>ԧnD͛Hc xr5^#.fe$թ'UoyE/[CNE犈 }<<:kQnm ;Z1C8dy)sVvu,b9`r)>YYĴnv+9pmxnm5R\ƽĽЮw8L_'ކ2^OS=5\ 8b.ʵ #(ڭ*k<vAѵ.>󙴛;V!t{bI>KݛInaţR VpnMlbyOSJauv("=Ʃygue)Jp*aMbs$iҕYT:Ddͱܙnɭ>4Ԧ$SD]쭩[MR3{nJUği\sE&]dB=u 3hy:A3'۞J-b [nZ?o,N᫄?@fm{>ܞ-)|E3>tlzx6JB(Bn4⹁&SyI $Jl[*G Zs/mؽ@%Y9)OGx'm(u]*7Y<7<C Q-dy4{h<}ڂD R})t/ϺmGWt-F}!2ݍ,H$,OFSr^_\S>6JCS ΞG#Ƕiؤ010o/=1FgQ-awdK۸.|bhwKQVhT3h>x_ 2ӊ2RtCsyѰ#qa!#_X}p5s6DvޯI6C>Yx8?{OGg֦Hǁ5whN Ђtڥ.ꌮowyl&1M6_/;_3zH>109xKWONw.HgU'EMg x+/}C+ZTzJN_ [,?4(Uiќ e29;hƮ<2~ҾؼgV'בP uwZαkߋ;zڄ;6IQ;.g$V{%vCa`x ' #%k ٶ`7=y-HQIj>(Mbo.h=[6[1Gd654"BwנAS^fP5;W$h'y| J3IFu;C<'HՎo;p FA3͵oD1gسEE[4sO~SӰ>Xg@w6w}E9B읣MLiP^a>kZ+[b}abristol-0.60.11/bitmaps/digits/kbd_stop.xpm.gz0000755000175000017500000002243711233572001016157 00000000000000ѺIkbd_stop.xpm\iWʲPn&@Axea@B !$aAS ᷿[2:릖-nij"a)Ob`;<&ӳϺk?-~Jq5(;=U&Rq^*Vʇ RTW˥JcwJI9V RR?帄=cy*Q~՗+(ORSI劔Z }ySW򷮼M7v ~+I7xjM~|d1-!+q)U~IRBgɷ+%k+qSF?l_48C~/~R$_"ߔ-ˬ_[qk_!_eyĸ_b%+؟B,oUkПMC _\ m\~zո^vY^c$_t*=qY~)C+iqj+£W@NX^뗕?%_cl|劐,/K O߮'w\XE_t E#mwm>7 Ƶ |gIH0>-qܬ}|׫/n%3o5kW1-Xe{kTmRD\2s|[>|whƣZeO_4~-UUgwgj\ukZ-U1>U;r}_KN < %$_Vj+IڬBɗ ?!_FIyIZM5ܯN>8r&I4heדc|yfE;֊uǮiS/sZOVk>kOk˥c5xZZ ~7y:w@.ȷ>yiPYWPپQ/rm63FIX1y5 ׾V^1_پZoQ7iзȷBe1\!zG 9:kV=!ߒ?OY0|&x ,oF2W _'l_OH C!& |h4 '<ٟzpro~:˧y\eyaF|K{Y4 ܿHN%gZn`پOL)_{ >!_w׫SgyGџOz6i|rׯS^ۼ^(?1(u-l=_/[~IY9|#Iؿ.k'zUK Gjck5|C<|KoWb)]V4߷H虧@jڮݧG">=VT];Ά\?F+їJh6ޟ;QZ} ؃ܨkHIwdCH~Z{VNKx# -qA%ѝQ4_͔H$쇛f9r緂 m>=SJ2BlY}OY~E}O}%>iա 2~V>fˮ@,D-Чh=\@aHIVTɮDZGo@.DW[C?I_[+ykׯVGgO˂M4pdF!IwB Z_44l\B'23At=ҢYl? eO8+4ga y> H ^ FU̟lD hD q9ꡯ>/9=rZWYиTM>2y cOBGȡY˦QKG̩J\5mLRzIx$΢Q쿑zF4y3 :,2,CE DSKVI~=,O ̈́xXfhEa[z+4d<\:(8P2TM[iSl2s6a H¼i X^ Y枅KQqY4ߣP)fzf)=L92U*>OP0U>G#A}gs6aic~/V=t6>b m³hy+\/T|&H9D 94ٱ}ӻ][]rfL-Xs4x4 -5mPtdm l̈=bFE?`:BoZPlU_Xz}laẓ`%MQ6V7ﺶ[f-AlhF٢sơ9 "'̉i,˜Fo≨7ٗ:,.'4B%km,l-4Qє!Xq!MV@L㸖 xVKz֔4 yѲ-YH|KT#OQh[w*_ev:\1)Ex.{d1Z>)lg xJԣ4 M@FehNet 茔4 G")CH<ʡļqh-V'#Vm P4*t޴1r]M[e8D%iM;SueXļ4]=[GS5KO쁳nkx`Z3 5h204#3blRZZW@,4N8h#<.`9i^f2b 9䢁ˆIGir-.BךXo<8MS4EѴhZ#[:KM\l+ABL.X|]3U>1rМ #HF]1*CH'3HF}{Ȳ61jڴeCɣq^124Qg|bQF4k )Evtb1fڭi4JV:oRo=]o>/hw>la\u7e{ah E;Xq'˩yehjWN{3GqHbCrkƟ.!VC,%kZbX_oht34 f 5n!TZh2צ9s@y囆tSͅq9k.}G&p^4"`/ \ȚM V[5o8qF41kc.eC3Z絬tr(ϊF36-ЯX|"Ff64c ٨UEe2+VsgeʈMJ)5M'jK&իp)71мhEJH=IAEfy z ЇI4+.< 9+0VNfblͰo=`i4M_}}ɈexM6OC=͢M =MS$f?ͭ7fTA: ku]Cx3XaKeud5F{|<5)ɼQ4;@sk^՜qhT=6>6+Se["/UEޚi{,ghz[CW-fV ͛e:ѨXD8 oKc.,ryp,n*]4~33#Ǒbo>PCh/@yDeDҷ"@hݙ f VD*9 U9skZ~&dpÕܡ:ijihM4zOñ.}8%0h3y}/bæh{C>bxn]vn$1? Փ{Q-#~&#Ν@"Yx\~]WmG`hV ~85=r *-zy/Wϡe%d4=2 ɛ57n,q,O^6m;ݝ<|V`t-AD|֓ xg 9d+i=<]ٞۯQrC-˱ghxKnp-Ї}sn۞<><+Cžmzyvʂ {6%pg~fޣy,~ 4 ͹Fj<܊V̉E{;ejCCDBQ>ڛ+ ZUí2Z5t5w1oI^JGIC6jZ LWW/dǾk}5nnYi˥@s ,+/N}5O@O.fhv#iEA[=ž)p CY<ܮ6 A>Y̛tPv6eNpA!_[=,K?@nwW+,Ѭd&bi7s\[s..X>}5nEzh6zv$w!r9FΏ^gGDӶejs(<_DKNCnIp&\HH'9,--ry4SۿϭGXQHnNZJ-9ӡ91$tfY&Z#i ef m@jV X2I҈'lWV,ќx 1*pﳍYJe8c? q84G[MK&7xշߜHZ&]{9$_[M!PFF=lۼUә?3a"tyf,FzIkyntG#az|8j^f:]l.p[ ;8$IK9'ɟAq{ٴ=;S5&E MxiIstߣ*x6p 3Ӹ=}⼫a~M~_c;x.{=tmD{8AC3k!4GwOٔ8fSD,O7cAYfOLN?\NfZj';=)='rUP1(/8pבe"`)~=H) um$zvH'U]ǜœ:&O&.bguU4C%zg_mY Hgwrt?zќD&xG`BBD=g7NZ{y{7c ϕUևs\y]~Y<3R<<2rz= > 4๡=A+:xx @7B3^ox*h!O,T_O]Po@kt 8ꎴ"[Cs3ihF1N38ټÛA6dz!4OtP*@+O{w"O<[JTB3۳tl,j? -ƷF84Τ̡14 rh2b2J}P7TNlc<8<_0Wdަr FK>ױ LdS34BKAA|kAI>k}ˬih([ˣ"HgC Hh.`|, 9G Xtǀ@}0(%=d\ d7#{kJ[oٻE %fhhƣiΚ)+"@!aNGqyP_6l 9[ xqN/aAԦ757xGjZhtPΦ6rqCym+%.~Wނq2lgޖG3'HaEA=rDɇ~]_zoQ4W%Q'h{Q \q{Ԛ=lf6PkgWi2ks?c~(gT&[2mZ荭ԟ2v~H6GmMQ4j{ΛcAk׏cOkdD2Dҥwex~:̥y eCogN6=!؁hڜ؂1X%Cslҹ4Mtx؇&_~~[V]j9/Wk@v GEGVTx{!=T{S8sfl(#tWk/##7z9[5k+_&#ˆ zwA4't(5,?\0!њ*1XJ;a)bD2+)imlZ?mH!h>F xJg\<M3Oˌи|9@ϘC)q ugO'w֚W$=ƍ~ M8iԿwl;>RFC4nOq0yȑ:tw*6qvEE&y#h.wDՄ]r-)G =kN<)?{a he5xP9} 'ybr͘N_4vHd ;nxpabristol-0.60.11/bitmaps/knobs/0000755000175000017500000000000011233572001013103 500000000000000bristol-0.60.11/bitmaps/knobs/sliderArpBlack.xpm.gz0000755000175000017500000000426611233572001017065 000000000000008HsliderArpBlack.xpmXkW|M2!<d^<̢ ctx}j>I: 8ZwKoQ7:u\V7$;s~'{S7oO;{^xޕ\?xXE U)k|č78x)W*?meƸUϻ-^E<Ξ=_r}ˎy7y9 c|-=˜M/X C%xٳxscB?1^?|3N%\)ύ/߼39{ ؿ[ /Mrh ?-9{U9|+Lkx n ?O/P2?ț-||4 |Uc<~t|~&_^1 |Em"*~/q&m~/ߞ{㶞3,׌ϸ=XHϬ_5{~/^_2m~K m|`v7ƫ뷳o9p7縭~{nrS7Ў什ߟ|8>HrY^%rW&Wo~=;6%q^ý{ [)IFeBwfYˌ<MØ|nj1'jx"Oe=&WI5}+YC5i:)I5Kٯ mOHUrS6A5:~;kx#olZٗ9TρbZ&B*]A{\Gju]ˉXQ~# :TV>= vuVx`T\.B+;$O0\_)EA[Ȩs+iM:RVkX.P|p6֢Z]UybUY:46U:Zwb Lջ\sYuy)RYё+i(;{5j ?O= ?/ؔ-ŦlSˎI@^^ va ҭ״: EN8G@yyAQ 75yqc@&ww/5oփ@DV4;/(O~XH4Խ*D<<" $MCv)oL1׼xXu(W24|zG5dkE"D951\C _<ۏ+0 M' ;-] }]F4 Q^&Wh=Lþa#0LA 4X^ = s C]c{Z~ϘWwlmDYoXuIjHφ8P 0fB u26i2!CߪsUETCJT˳FCr]:YW2F V+]+MCo>}UxHc6nloWT)o.&SE]Ubu'itUք}MC=zѺY 'Ul:)Xg>6Wk u2r"/cCA"O#3dW$z{Űvv7fw?kuu⒝,v ,azt/!F6\ sӺ&ZJH`0 }TRnLqɝqv }To??NJ8! wdo_D"1>7σ)vZB3=E sgv u=/^ Uak$G>"lmQ zhoޘ,$BCN!0li}}~":1%k G`$Z$uyP)̮_ O@o$Ob :qsÍ9UGRK`9Pb헤 qɂ5ڷSmۜOF9mO4߷o{Nk"75"2;RΥ{M5kpoEN)bristol-0.60.11/bitmaps/knobs/knobred.xpm.gz0000755000175000017500000001776211233572001015634 000000000000008Hknobred.xpm]kw#pC3ŇR#3N3YZp(%=}*fͷ]!Enŭ'͏߻m}~?]rUr}7h'oʹM54Cڏ=: BÃÃA/5ggC]<ڇ?|ްܷGzU[lO| 'xC?ơG|6~7Wt0?bз+qw/}gw^~?? op>`{x{|??{~ڇChpGy1~|#s'}1~~C 3?_A Yo q7>=?Ϗ&gۣA=~na~u ~8`vi?.w|o/U`LhSr6 dp6>q=g})'ߏ~C縿?#~glawxgtxx|}C;{lOS`?>vuxvAhxv#?@_뿰==s:8~Ϗ*h/"a Iߟw갂_#^/Gc>Ǹt<CڧϞMnᷩka/{m_d&m'yݾώ0Kn%l|Tޤ7d pV``0:l1f/7āJǮ:\:k4*Āk8G1hajr}`_ǹR/q4-ԦQQ{S=҈QZ(h9[Շ >4}#@(0WJ瓘o 7ҁk4`y@g-XDq`hSyبs~;`M}p!t{iFKx MDaɅ_-[%?1X0r %Ra>MOߐR.y<:i.#bT5ijFr# _ǃX&/Ihɭ H{GnqFͱ=g x=9[7 }$|{&=I] ֦bZŸ MR p~f;|W#bB_&,"_g$61x?Cӊ屶R \z0d gF~EwB<\7_'~^g デ*1۶nc& lƌs+YhOSDHh/49NI/qXglY0Z̍i5bbeHIyG%_G̖[Ͻ;bߨȲ Q{BTĞ/@#(}'26ZJXUD6h1y3=F4qt{P\&h[agkGFHIFzJџ)W"7X]hm2idg{{s'7pO5cպ"SVkGbeĀ"|_Cs@ؽr' #ki0"&DOSN*?i܃Wiߧoȋ~dŞ jK0&DE #s_{VpŸa,bя|x':X׹#~m[Gli_\k%9?Dc@ #)m%ذRSYP Sa,Ox9|,}Y0g|bd{u\)~&o#|A_FtYy:G1y MT&ߠ=̢lTHmFTgq$耶 V/>z Y%~xR*H Ⱥ`-fB+6ugD`wnّ֯&\x (h ljhZ%A>W=c10l/ٯG *ӑ2Z.{P 8oh@2sKM>e|Dx9J5CnA,Q0^XbƟy{%^#j dR=Qb^Ab^ Z+ (6߉x"?.\$]8O6#J4(Yk p6IVim.Msץ:s^?Y~Z "fBt2*mK^NTtQ@J5Jd26:?W6`ِ[~5{!ƩBV!0Ay=o*+kBfBxw"bZ $2إ]vt<`'Hǂ yV~F-STsk %o[+qt~bzHR>fWg4yR9|5bfޡI]%)$-Sj½B&`JXd ȫd8r1֠?g\&;H<2{Mxh+r:`iít`/V 8 K0UTH 7B%#;Ȫڵ}gR7Q~dD̒r]by⁴qM !7% .x|dj( |xy@(Pv# 6Iw(JoHKoA%ӫzΕtKtWX$X6 fkј.d{-\I y,s'Q/?ݓ% ZWbWzh<gt-7fPh6m+u‡+C;Y?Y&j[$}a<7pNs!;֜btltT$&Zkf)V O6bUǒ5GW_Y{=5ztZKsF[sYb܀q(I'\eXU:}* _Ch :>Nk +J9Ry<Äk*'h\j`A%25[ni:q[Љ]aj.€mVa eiݏNIp[d/'b7,5rIgCcH[o^L|JQcwp{O&`EҵYV1]0\Wg.Dł80sZnxvB ~<*K(G6B!nS$0v4\Z! :c>L #ҝ#֐ u3+7 y( Ä­WlY+ɥ4$_=܃:zu[urJK֕5YW8[8+c 5sߴFصWRǺWT["V|\CLВKq,5ױ=?,#)E')> }j6G=T-aq1_b+ˍV64EVa"0WmV0Wf\Mu{sL{G~o 3z`LJ-w+XgݫϺgi $̕$z"YJՇb5Oux03[׬ V d ;>BI6˜s:FlDռIr{+ 8,xx~ukUd. 8uiA}gK_O!]ְ4+[ף }\l\]Fن:Ay/;x{;Z-d]i%wQ,rh>>׃7 :N@&H_0s|41I>M*+jr:@Yk+[fF`_QL{˂|]'pz^u,]3Ky&ɭ}H1!jKu҆X>\߶}kV7B_xF}cF[MXL:egq]!GR+a}{8 2p=+Hmd]͚_!eeBLގz)[(,\Y2G!Kz!FI[ ֠w!zvv35I\7rdGyX4 WےOwEx;Ni&ѐVQHI@ZY_%7>=wR7(k{ p}XXLj+F_)7q"oeYh܇9crԇ B?y(]V\N_ͤu~)큽gG cZf]+wZ8q:q-D#֕(_wThÕj}u+s-Ԛ0KO )nf\G$p'+xJ(W=rtdY>G!ACKdeXCpE07܋SG?k9qBW 8J,__C(ֵ$Y 6^xG$g/C~~3A݋Q1RE7P52Ei}0Pw-%鼚w@cx|(-}LqTad<$OG3w~k Z-_LVHK󆕓kt-tb8a_кh&]G£6u$H[m;rgu+3S\B ׃zdUEE{qgޡJk!5B~P9ZQ@W虘`N@+߅oq6Je⠟|N8r4C!xF?BrE}Q٥+߷0B}#Q֑y|d2٠QppHycj8<J>,;MrH:6ˀ6X6 H~J^f2t[y'y'Q̓]Hj ::^e8HyXkGk/݇{fǻz{-FW#e!T=m,;IHSW\poeQu^E^wAqx'P'9X%MaH6Afύ]*7J@hUq >n,OaݢJσlU?bs'KW7Zdzxҽ.쁾cUGRnHZfeqjܹNG"ΚUt}K[P[ɣ\eh_k^?YjR_8F&ouƙ#CZae&Y8AFl'yv^ :eۊlE'ZU=Bfa﹎&+8y4U6.clWCwwb<} ic#/_71V(B{dᧉ ?ΎjGSQS_QΆ+W' 6=S̼uT3d&FwyKuߒ B3 󳎪0 $m:ZHn3? mvP?5 =T7Xtյrtck%t(2:ʌ(i<+$HKrJ;)Jyn{m$o\_iEo'\:sk!8.@BQV8߭i<GUb(r['52jRvX`Jh=4xsk*~JZM2ҧzfk62Β3*9?-$r&Ѽ))CIiDootv O2#j77KFKK(c'^MN|>qxX^]n[6/I~|W,%;gh5 rtVfs#gekXaiY;¶1p+'Oew<ΓOG=Ev<{G_㩨Axd=B"}k2<;Lo):9G~ݎs{oo.rл{-\EY_sdz?mcS7Z+"맺*/BzTVZO;{NY}$VNlz1Iֻ+;77\/;>׾3弟7^}}-wes{="WW`*]}~tsN]xi 䦇ZgV7xMg5-F>MӸߧš%p 7XAJXoZX/OX̓q}fDzˌ١)1֡x>귘b )Գ07+:p[0=צ4)5$d ;/ng]DQoOEn1 cFJB7|8üqO9G΀+#0}'zǁ%{"&how`|B)%/TQ.2/57)|+5g}pmYz:?zך"NKr#]ϋ=p./gRq r9/88oPG'WO~ ݣ?O87?WO3&/ <ԯYܵ[*kyC?gx}up?S}_FnOO ?~>(QE~/D?~[M< 8ic1rRS}G{cy.e*'}b~üY߫ٷŔ*kj0L%}ȇ`^|EPq>'$ ߇6NWe$ z2i)Rd$|xWaC}~ Eq%H4B4&6*3Ob;E4ACbtG7E;C31Ѧ_%G^#)J( Oľ;S:o=tAbW~/߲zTQM؀ZzBO-szeZ*^zKhikI9E^Qw'y^lgyx'x_-b31&_ČeǞs.^#+'!1f1s|W1~5}jxmV􄟊=%~/xW%+~oĖ-5^ ~H$Hdd4w,Ld6YHd"J*Dbristol-0.60.11/bitmaps/knobs/sliderArpWhite.xpm.gz0000755000175000017500000000640411233572001017125 000000000000008HsliderArpWhite.xpmXiWSK\(rEO%*ٻ&"z^d˝ξgS59f.͛kGv73wZwugvrbO&ck,uJZ-x /sVQ͕'V|e rxJ|i6yy4yP>Kɣ@M$Ooy{!4OY3 + xq[yV&i֬@(DX/K("/+ϐ{-=!OC y'o'u򔼒)Gq=xEYϪiJ~=.y^sfR ?T($WE6yE y]|g ;x)ߥ(j(KG90ރG(\/sCBPO) ]&󐼪P~D+?vP(Gy5N|? Rk _9;gʛ w+w/K>ޟ~#P}_zS('KyM|<\?WP߇߶OfVYk~1.797yEM[ KzR/{̟ YR orпs7yIM} 7S3F~lGͨC{пZ%>Hޒ|z cO7yJ?Wzȟ?WMP'zr sAןc~2~.a,psz1~?yh鋚na-dw3(GT3Hgԓߴߐy vy%A?Fc$\?y7L},K߯dͯ. 4\ipKÜ2f0c涙0ӂY3nn[n1 fҌf̘5AyĄ&2ILj&3PCՔkY7̦o-6;f׼5惬H=Xo>5[芊CsdG|R)o`f!ȁt Mzëh;okgYqM<b/73ow^pZjNǦx켊%< ((4eE>.̲`ŬUE>th\7؁gyu) ZQ~@܇U9;dVy㼊 1r1{[D~?(td<"석8) C2Rw*6DF5u\7¶;.45 Eغ)Vu6s\p*͋.bPOܲ/fcE /5DALH򿞼.L;b5{"5lLe#)dbgPl-hi?ơB}1ؓ'G?3Uڳ44vYDڷw$*4/e'g4tD"fޅ vE U ͋UƃBМP j8 Ky?̯(>OС*4"뒝 =vơ<(xn#Xښ8/2sy[ m7 lӶ5EWPOh},KGќ`u0/EpWφ"&Yyo}}O"'F::?t/QFB^~ h8y kP bT0q^ÛSq|2ǖy>c\ >T^ؕϢ30!P|@kڈ;*>zu^9;X\9 ?0A+cR,DǮuI76wW^E՟^n߮?: ͉-:= ԰v[gIѫ׊XD*6^ qص|r=}9WB?Abx`CdyQkyzG98GI?Kt% ./yr hGi/1M=Y`0g}Ӛ偌`4BTf rS8Zby+80Ns:G^h0/gP{tCs4Y7۫ 4VܝvT-N\?YqXƙp'=u- '9O\h=*yxCyE6.s?9Lu$j2ZO}ޚڿd\աJTK1{/`2'ic4xL3Z N0a K4(YP] W4\iЛo2N%/bristol-0.60.11/bitmaps/knobs/line.xpm.gz0000755000175000017500000000067611233572001015133 000000000000008Hline.xpmJ0S%KYںYKiIw1pSt/ t(/9+vw{8n->mޙbU˛ W<\Л-y=ra=`7'4YuYu`hΝڹ$׀0"ouӫtfkuk\e]/\[\ HO}_w;O"/-yEG`B n0*tQT:!Gjca0ncAÝt0wKPp[:j¯=u5f.c]A/v%E.~U\ǹ+w}T* !;NAr 9Ar 9Ar.&bristol-0.60.11/bitmaps/knobs/knobyellownew.xpm.gz0000755000175000017500000003546011233572001017102 000000000000008Hknobyellownew.xpm|g[˲̈4(Q@`m `mr4~W(>a3ݵjUuotw?ިwvyu񯽧ok㟩tKK^>ʥ9z;.E1IROQOSωP/^}P~D^}zUDqյ;$3g "Q>D&"gS"R׏M9wEDߥ}ϊ>L*"hO]D)EѷDDYџoFDi>=#z/^=z "zzID"%ѓk"S~@=/"!u~ED?^zMDSڗ;񨈈'gī "9ǣ~A}VDKuѯTWko~K]zJD{I_QDGWрzYDħ$"z͊^fB "zzQDϊ>2"׉gJD97>߳ "/Rk"`%їٟN+/#"*۫zMDOl_'@ϴ$" k8}_ެloVDMQ}ϧDDF]Tۨz"5+-(=@oՕ՞Q>oEo%oeooUoQ"߼&M}VDz]D)+( SM] Z[d]Dו*7QBW5+ߪ;9)S׏7u%Hoo]D5)7ׄz.z.«zYDDy:QV]ӓk+s|0߼^Qԫ"߼_@k"ߪ+/Mߜ7ׄ5o^ׂE+"7_(s|Eo R+*7u (oޯoյyYDC(~uxoڣo^WWf{:a߼"ߜoM߼$Qf{"ԫ"ߴ_ _WE~EDo>uCYo5](׏^g@] 4oUO͊(7Yo5\u|kxPׂ[hlO7u oUoo7u%$oZ *SׂT;$lg/V#rr|H_u3rŮOR+44b%E>PO+,rįR>,X?BmX -dX|d}dYƛ~ƛzzbsDVɱ9 ]8qzSw}wex_OIϟqRsڛW>Pʲ$~YT2̇KgmloD{a%?\vz78|9˜Ob[5ثz`,zιs\/;} >[O,Z>KuC1+1ު4h\ ~Gx(>->5?%׿XdXQ8 767iV߷~ߑJZxW#x=?Ks>,!zyd{Xo4i>.#Ʃ1rcƍ/Evs!gO1Y˜X^_zvb]!4㯽s.Rz{xez}#[/cX;{\/:ݮx(~?8dԳ*5>y_j?O.)rzDn"/ux;Z|c+ֵ'7*óxoPV~eWڳOZgl/z)?'byă$ea<,.3?.SA8{ W>%[L2|PJYuJ~ggy1oooTPu#5Cro5~/d{%Ч?z!8Y}yM-{K|<:VIloL||ryuzmƺڳ)]x'K}ϖs=ձ+߹S)wmO-?.^W߾ K-dg]9syghOzT۷]"IW|mK}vW|s_b~=qgY'˿s!MoE/jߥë|ro7eϭ }G<"ߪ p?WFXN2?~qu|5%ޛ%oeX|x ;# l??h>S_"7^h`+꺽 ,?2g]wCloVDGykЊ/7u=RaYk}~e}18~a<);|65e/3ǣ:ԫe: /W \fyn*zû*2^%_z~uax~Zˇnh)[Qs_m'nʩ/'j%7K/Y`Ǟߜr go)gorAi%G޸<uwqj߽JroGWܾvzӰSt>˪gE\c}PUf9>=S(4歿_kVǷ"ϛdW]XMr᛬WD9~}BgD~/>_:ߴa>-MuW;Ax>jws'J>t5p|Qf<MnOXKoLXt\7.Lx;+Xo+^= UEܯQwu𑶷O?S/rw)G_Pxo7'kfy?iy? *hOؿ(;UoO5I>;C~}-c7^> ˂/SzM.HJ37}sg,?/zOp:./Ͻ+'nx+],je/?8|!ߪ/+lO_R/) /JE^Fioܛf1oWx~ϻ0y)o{W|> a{ 4,W/弼W^ Tه&Cs{'3]>z'f kaYɻ.+ڻQk+ȝw;ᅪA~yO#yMZoWQZX)KŢx?ϟޜ7 w^e",wŝ"F|}@/#W0;k;WU>v !1mT ?Ocx%.>Oi䋕6oaA$8e3࿯ o#O?z M%~\#"6]@,q0!tl!$R[YkDdZV\{Czá% G@œA#_nϹj7iL[k~[-?b9 4gwYY/ǶIȌXK"cN!3bvݺaJ[-cUrLZ$q`T7v0$Qx ;fȜHm~ ?svi;힀 [v$ F-^FjiC^K2b|LAdJqiFL?7o1CN03˨Җ0S2y0a^̳9nl |l1_slO!b0,aj꽵BF߲C؊?By(kGQ71 _A2ndsO33>?>Ž{D*O/!X)o`1k-eM2$ѡ2eAyAP4X_kmaւOrV-^+bY3wm{6XO͜njս)W4?,{{fVVKkUCB`[d9a'V\X 8hͿX>vC,k6L{%#v4bx| #)@1f^દAV0%a}?@ `_!T0,qhe{Ɠ\B.+Iup=^rcw<' ǒo_0# :b܆ ~zJp+smn O7;\w8ݹCE!980`OO_J}Z>0l&~w ^fq zoZ<{p ;`붺^' YB|G;<(̆1H#0k/Ũͯ6 w7xtT@M"r̾UŌC; 2jMo`@ـ2!C]+ ^wJ `PV ʦb mo3o@{}uײY3:O4RAߙ3 D`FZT{޲ &IY5<"׋<0;/pk@Oȡ,y=m !2bM=+2`Sf[  :jnX MЀ%/1m +z&r.vP=g L S@;MhXO >@[D\M$l#{sE^J V 8[P6` 5XT\;3xo^F`٬hvYޒ7ܚ lhQH#5=sJ2^o{um-UOz]Us'45^ɉygTU*2| #UR^  $x/+n ʐ@cl!?~3fd1ᴮ6^݁#@xJ="Q8B*6E>L#vP"S*!s>/lYV?tZ_f?G3 $`4~_:C+ԚdO#C TT&{AC<Y4A[y0xP?HɌвm;z{Dl-FON ^%p6s|^_%+#\ `~ ?R!;m(HI9 ?{6Zm.pT 1A/0/pz`4"Z%\| 7p M^n7 ߚh(QQ%裗AL( )#2T}dž5+P_ d?KkC} 2iϿLb5mnOEo4ƣh6±h(Fh zM+; Aa(LD^.F'f P8e63Q*^ v VOYb@?X/Nav 6S/qoFlU%zVRXt {Qe3DY- (V R4˚)_m<,"ovb;#\{w7vvO @`%tH.$k!?!-^(¯pן[iݼ+\r9[|= u7#N+okQT,rkihF1"_)JkmvYyJR/"YY7+@N2A̷ahM6-6 ̦N/𱪕p= oZ|~J%0(dvQ}MX?A' 0ap`c1+E1k  L_ܮ|swPo!X<ywߠ@QZ~~ PQ ;J<0<wu®GJ0߀€7lL4ufSP1 wpYGU kO, P|3ȹ~ ߉kpVֿ>YQj1[fR挜as^/CF:Y3ßjwy[sN=r`$J@ܚծL ^ LOd%1bhQK<<_j}uxqIbO0C;%k(gf;m' kޘ=K ~(Wš^hTh1}dWŀ Q=aC=>2*n Ƒ%o$@`F 81 /Fހ'5)5?u_)x =FBl? ` d ~. C3*>wޖ[~ +rbhhW,ʾB{8 lu͛iE [^8 do J L,a-D`z¢?`:>b SfbpozyCc?x0o`0!&`&}0+X0y_0?<ֽaˉ7*}4or fB$','Є {bɀEA 86נ!1`}Ў 0`8c6/duEG((/4sf_8 LzX j,,Uss~by`41#W_>bb/K4{+iˋd6sA5jM "'?a7':{WPI&5їnϝk޾ҏht+޳7ҶRb~\b|a깩a,̅(F`%X >jP4=w-~貂|wPaw_Q4(wF B M}C0/z`Q+ѓߴ8bׄq6t| 6M e^=;ݑpQ410^\<(?G&ҦaQGO81 ^b)0w(0qo`?fE"a=@ [1 /߉- $ꨑʊY{]]M>ѱό- j`nj~熞?]iW~|e0E06;Ć&l & `ouK{2/y3'';v몪T^'{8Dח?EDƦsY=Qh87OA-GiD Ί5m^d^E9*dN( h|$ RO ѠZA[ OjE0Q \c`td쬸Ȧ•ԲkÈ}j kuRK &ԘU3W|*)2Dk>T?`U1H5k'N[[œc9K(ΨmM ug^K^7nt(/-9Yܣ ]ADu?X! 캷Y4X <1vx\P<3HԨZXLJNȢ,+wڝ` {]ojV;%ELttT j"^IY񹒵2yCbK#vX.[kk@jF,]H75l2Sy$^ˆ<_乜hk`dU%嵕Q?VcsmX?p&0qq.d )Z]'Gnw4Ԃ{!/啼_Җpaڿ+43&ow=W4Tgkf_&5TlY'T{Ă  ʞ[YzB$&LQT"oSS1=7!oeSɟr-[K%ГD:CG1FGƸ-@U¥h 0{%>m2q@Y3EtkPhj|Zr~lK}c f CbWA# ^P\RD8΍P{Xi(ծ {]ޣ<ⵙmֿyF%r t6i(hqO=o(a+Ag{gX`M`͛CqN|4Vzc#z]P@`,6С1FbTS3+C0x`~A"g/X5֞EgOGyNX20 r TYa$@2?TMTo(uJOga*Ek#AHyGX xTg6RQG 'ZKE3K8ɾ1@d?(<l@>>kNOlP8ٹ'o^}tӜ IMW(\C> Zt.1?lQmA-}֌Yxq;:~>OWف~h<44 !CQp5 RM1KҾaҧ' d 9~N- FϸPa3牘?wQ9a&ٱ2L`s^:y9h隐&3I]~D {jQ򕎁i<^B2nTI'B몯Xw!ED-Tf~=Ffp 4 G O!6 E՞8mt3c9SؚQaGzX81yGQMYlbBFn5T`Hj@ub V[ F>SR;p5l}X!n6WI5,/=~4 >}^R\m%0㠝7"h1sLUo%[=-@{*}AJC!+ <"^ mgUR,a>z  zve/Y٧W[4W `bgMԳ$(P[ eȎbӳ&;CUQSF^JEK`e&>@U0~@oGSzEΚ=m9kMh=XZml|ڿ##y?!D2m A=i;<>n^7DPR߃t3|.A5кN"+JTVLoxEJRkrrf%>p{2nT2=YE1LwZ? GX٪bristol-0.60.11/bitmaps/knobs/knobgreennew.xpm.gz0000755000175000017500000002551111233572001016663 000000000000008Hknobgreennew.xpm[[Gd0s[!ǐ] .+ ꙞMxg?[;=]ou\\^Y ;ޡ` G7{{k]/\/|7Q~H=Xϧ4b>V4\!7tyrv];/x}ƋȂş>ȸFQq]qDzxU<yE >s]>瑾!O4EXlc3BnF,co ً>y^|r$n=$iC08q3ӈ9i)[9?cs"g} ܯJ`K*Ƨbv. 9]^cy,rfQe-y geQ>JϗY7!gYq K OÔ}x}??s+]EN 7K/!bˆ?ڐ<;6C!.CNs&8s=^-a"Iߧ?(qxisGmor&)'*b5^4R'?uU~YYs|6$z6uQo@ b> Iq_2ԯ>Z~9(C_[,B;w̟NG;[7!y؇>w:e|d"@y9! gPxGXG2U/1Sd!꽻x>~3YA&z^.,SR^"O<4ۢO&|ߑ K%E/߅%•2Nx GP(F,n^樿žTN /<⾛&ώ/s~Oe}'p#ڃB=o)g}#%^xK}1(^~@rwAv>O&KR#UCR#/Exz)1NEd9ҴUIx,YܿYUO..K{"W xY^~9~L[~?bHY|rWi',x3d>|WYyq"_|^/%;yUxn\yUP!~c s-Txx>+y=޲#(/YyK,B|!;$3?".Ջ|,z&)Vq;o1c7ueu˺mݱuϚZ7]syzM~~yk,?0!H-څ͓5~t]X]ݳozaGVL'Vj9Vt鋞h;vK5?ֿltWV:r#$T 7`%#gkXWekxE^Px_AG! ?GSvWc~3+Z5v`|wmƱPxG(|=C֪kG瑁!@͇&F[8gD_ۿڏYCc\MHN:$s02y?_o,nqy8vl>I*(x5ƵZLg5sTGD5gi]ub"(4Qot|]Xhp5 C1h33?_fyXi4WV(lѺΤM1H4`'Ԏ뫭4 L>pIk[H{WA08#68[h6Md&W '8|=jqM#c sM͕--m qVk=JJ!6YG'S#ҫ؍r ^ -k1X&Zp΃^0 !=fH;"mUVT^d4&Gx #+GW0 g\ /a({E|;V[Xows룕ѕ'P7Sa[uN+:zkTxfą28Y`x&3o=)i1`1HVaVE$$؏ꦑPX,r#v32LPاY(8| bfKJ=})7Z>3u ?fo7D03.L"q==oP9sKhT05cpAZP33$|#*(&f]b| a_G-淵GdQix>{a {֗G{EA`E%ә* ܳgTV>PSuX$u5<;qۧ1t=Fy*K0z\/]=_:(:g;̈́00ߑig~*.dXN{\Je4 T.3k _ijM2<H52:7oop?#?Gw" hH3\p}/gj=:p`*WHgT!Xѧ#M]qyz[7j;|ir`ͻ2c]#C}9}J5*!I<(HwsnlU O\A5 Qs͔~}Ǝ~.m.m}'͋<^}{8U/^bi ƭX0"Y3>O|o j֦p@_*sbL/ޠbi];A#cѧ cGuwgb+ǭ\m՚W*bgtIϻEj?[ڡ 8[LYY{'3uf սh4Oב|C1Y#g-ހpb$cO]<.H0:Q`f&*jwψӝ6*'Oj %+x̀|;C;cj҅`œpvݷ}i.lrlk#G;'7,0`y3Z>ѦD!tM{޳Pgz'ھ{#{H(#{0mȻ!o3orz`ߌjO9J;@{L @8%Rеo3>8ĄؐP8lDL bDvh|'{HA`웽Y@"#pSb}FMqhgtCNWDPGإ] 93)MD}̈}9∠1]kSYT0EO wV끏*LC%v3A1ك*`!F@<}`@ 0򯻯SBƢ3Zy1sU_F4Ypu!I-b0;KPaKW\m=޴kJkO0h4 *|Ќău~ doET*@ϚF,(\@@4ao~t]ꢋ=g Ev`I>P:+h uPec<<" *s€jkuF\A8)ԅia0J0A0i]+(:!A}T<>4nP b!0r8lҾLP&nUP%A5U$1qׅCh.P<3Wls>1@@w8Spl>XN&|5." 'ӆ#lZ*> GL3}IW )ȿeٰ;)lPL` 7 DQ (2?&fEIۑ=Xv6ᐧbϨ W$R2(y@F\.`joFcZk3 `?1 mX0'+e#D`-)b+ yKqGĠ!6L]=\t)[v$UK,r Jswg "]R?&6͖Yy̱4@K8d?q1GUm1=kq(佞t^ f4yΊ 8N s=,ZP|R 1k7nky PƇ>J xQ#Gn'6҇0F˾ b[IA#. _xC!̣}Ɍ9j^&g^c9tqEULkE vJ"gI=s]y+2t4_$+cS[v0Fl ^Ypwa h(>r%K4-gL ?bjṠ6u@,AUZj~`xfRAՐc:o,j,iA:ZP y &lj<+ t1=(~qR:yvqRIj>s[(RPgho?QHtY%p`G44:S81qR-\uy 82arv#oQG7z~ Vpd!~ͿAe3.[ߠELa ]6qQ Ɨ65HDJL&|]iKo+eV1ą~DCJu굟r]!+%̚1 B`-krH'T|* C([g^y:qd9{X) Yg>2J]~̓D~ =}̜;>@a۝<*,ۖ0QQNQ/N+Ո؜*_,P[(b;pઇT9%9zMۃs'!pgLw/W6髾?1E =7(c%:gpS P$xL8j;„;W̶T5w (Y֥rP.7JXj *kv)eF/mg |9ߪZ"k g*JHEKq0vL@Z1 K'{= #pdLob_Wz-_(D„vuՆ-q· (G{kQ 4ʹy˒|whLK{&73nH"'e2Kt':U[xh-ʄVʫ+}ρzs ۇ2,,c _zxIG <4[tHg&㱉E?ΙK@s{&Tu@çR,[;d;;ϋ.ע)>qEߋoGף.E5/$Dڝ0V^QվkťzTBx 0~(C,~S5􂹒F6 ?Yt<ڳzUg %4wy5k2>Cx^|=C}N]\p{J\d޺N_O?T+m f,{@Ho[֌{R(y;Wg\R!hq0tL (oǡÖnyӎoW]Ѝڸnڞmg aOC_Z>Kj!_B@nV0 t|:v>Am6 r2 A kD^ ? 1\%QrA9p wms@,1=O6()ځ;M>&y(NإݧcX  },X׈"ЉQINOqHu4f ǁ@#p!ezc3U٘ڐ dЉ")y0Ϡ /߷KB:(C8!7@"4EW ,ބ?a{;C-msC/-C >{{ ) J7ʋ"mb51^~U ;^&tBKF -m'C%y"yPq@p 88+b0Rͩ5^i-KYB1` <ȱfd_ǵN%{~3b@3Q*^mAãf1= z~CՋY{8+ %1ғ mײa@8^kPw_Zkl{_<ă-]Ns0G, qWY%w ='}:vRQq,=~ϲBRz*2C7upg*Pr~=12֢OkX̀nG Dp]v؃, }(t`g2=pzƂ<-N.ЧU©Bc p8~'o) -*oC_'JwD("/x|@'w(=p!?4?]'I9?>z|OX{ \⟳:ބ9ˉeOx@ Y'x__?F7)+Ώq!y-7%*bp?ǀ)[ǁDMc8 @x /^npM pNwL=x*^wxS灣Dm8I?^">/^NM-^Br1^0.R'8sR ¿i/2^==p8p\ءٷ8>ז7f2\a/WNY9rJ କP+j߸ 6㷪"g{_MgˢȁBWGQ;[%-#2~i zTԁqď1*Ɠ Uj$*%^e~ pVHJxu|&ǜ߼wb}[?Z')%>DRYJɗI ɏ7^!|6R564/FK{͘%mq5Kb|Jɟnj)[S-KǸH(e{#l^U￁Jm^][w2쇞i?I;_?Q7pRIGc8D狀_g 8z17O}XmW ZQ>r]_OK>%8Yߠ^XgS,W cG֝s??b=7$~*ɟwu SaW _w%WWJ=/Ac?r8]_귖H' 9u)/$_)`yOZK%cm?_~鴐_k'7g_̿4?UGUۗxCO9lBS'k=xhMuNԩ:SΨ/rbPԥ*rUl.h!WdR-5ƩMP'闊X&51/KJM6i5C_0A򀝿oϪjNS[f./ES1DuY,eP/ VS?Gvו2ُ2='gv&]M5kf0A&~g1 >iGlt̮ŕqg~7g`cFb i&"ILjn)GHj,O*¥1ltLET4̆yg6?s23¥DKScv͞7oCFoR|3smMđyo>9|4)*5Psj̹0]j2BZnJbK<V,^s\쏛JTe>(^n0L* 3¼4Mi3<`@M⏋;J̚w8=3 VگۂY4KfLa-ߔL~PwVb[:+DWAG/)fG).F)G?&)uv4#P{bKÈ687rsAy0beŲu)*GPbX,QT4j\'FcRu${Ff̳76.E kU[Oy?yo4=Y:;IO*e (?bx,S.} elm5 #NSwvQ'ؘ?,2p=rc3L;@4ܷnNNw#{cX֌Is2c%[A=<%f퉟w7%W cHdOkwlξ]5(OnJ`_Ӎ=[<'ò߹RN3w=;֍ή3q3!"/'֍s}Q'T?D}ܾu ;'ls¶3}gWm9qG?1s։s]ٳ)GpsΛ*a=s"Y'P8{d}o&H !7qr%/w1W({U1IJm2{:`qqVn<,~?9ko.n07Quumx~rnԕC'[zL.A{k![}V`B{?mZ/+=_tݮw7&,nno_w$/?\_o.~?mC"l"n~¿}7+k~X ׸^l6b17fo3?~oOp|Ws~oGdz7^3>>mvbS\ߣ}ov{[[ߜًG||nǏz=;^9676~_.~kOl~a%4Q&ޤ/>ߓ47_oqfG󷹽;To~Gqꏂo6u£nR{K>z> }||g$.z.n>||wK;[ۃmހMB9%~/n_|3>~sK)w/]c(?ÝnP}wkw!=, ,>bѧEMA$<Ψ^ {VAr'|^S*wJ/zyMs`GF@֨bŋCpޔIP2Q=U+S*L@Հ]oC`ΚoE6?9R2$Yv+6L 7㦼OOzYڛ)L}|Ml_&慳"KY6E 2w)񯻯; y,_mi|AFa읹9͞] |Ok'3q p:CȒrSx"c9&sm"1k]w({ E $q!1i YBX;\?.L.ﺱ 0k0 UXD󽝘e >8MpjitB+]o=gB8w $^*r߯@^I'tB08^8#~u\s`d$~ >78'm\ЅP(jC}l@,{ %ښkB5g9|iDuqVW,+wB=dk *7|[tf͕3x]/,E*q׹\oRT x NrIU-^ Ip+8>xEx-:a"ԵZ-^raAUOm/u He5Ñ";|fDf_ /=Nr&o6|zM³f[*<Xe:.- Ϲ[Y`Ug`b/.PǹP??o)]0k.yeLW\Ξ_{늁ħL9 fAyC,6eLI8mJ}78ܐ$&! rsO\X>ǰ mx|Y0Ry5tPZ?K׆_ qCHG>yj0xBHGH-U& V?u&|85l6Ccly?>mhH%c2" q78,Z XOhMOcxv_ xFG:J( [ 8ob0((t+ccN Fq|օ|"$^Ul%:%֢)qOzmIRJxR~ S@&1s1}C}c|G.w"?D۹G\.M|kƃR>~|l0EZm|`H*I&XC>6n#n<*.32U68{{,co;XG@Ȁ \D<߈GY{sm80|j+ d&oHfjBٶOj.y=B2bvbe2Z ȅC?Β>h݂p ZPa-SUz[3ZMXv o\ j74O&M5G+~"N7p0vjU1u W! U^~"ӄL[GN##u^v_}Tɰ=akt]P= {{}cJ`5(^3E>`qȭê{Fd 8|~'͞,%Aڞ~vA4,+glgH\Ǚ+rqFv5 Vq{4XYX"`^HWn%֡N20 ?b4[:%GiӖny4$YƂJj>LeAyQ;<6Rqr_S,7L38̓,KegB<]ʧjG;c(zxL~ʟ%D8{q .k. Ot,è3=|ѝGNKD7{y5: &;p*:V%9"ϮXWVA=oSE^ji.XX4s6jF m?A==v N '$\I%bn vΪ< L%iPiSnĞdX(7Q/qEtcNX<|V譝Y\/&-MP~Z >waO@@^V| uQ%{x8`Bx]6%4q 08L[HOxq)#m8#w #m9I7/kI tiE@1'G p%Yg\f0냹xC* CтÔ?:'/PHLn(B- +KΛr-`˄8g%IhNUB-DoِC?q%cN> s|ӯiݑ1ϱ+ #!ECF!{1"r#u<0mQ+ D3Y!rPw+ J=A8m-|eAm!/*`y%Es7 N\[8}? Չ>7P…%MžZ~ڙm>s|cwQG]^0,}[*7\Jﶗ{҉u~v\آ0Rb>ib}hC'푣by_YDv:߹=bA;O%vti+FdjFm/sǕ/\\*r8Ɲem1> +Uzfd1l>I =T-} ~DZOtqB ӬfXlI5\m[F)Q Y k-H>b@'Ee~(Ǻs۶J(m1yef V` X%)Mt8܇޷\.Bwk b54q9ا3P$͝nMLo{xdLve{ߢq3[~P 祽0y2}ߖ&k[Ynٞ;6fn= X"em.R~r+9fB/VXgu4uyyQo! 4`v6 4m[DmB۳{l`Nfx*]ͭ282KVy5Ә\z^森^71YR0POB2@-A%(xͩ1FM;>j tϱ49"v=߅ޭ2)x=_߳&}Ĩ}4si`>G,ۮ3G>:`va{B@% bo /fPKc6xb5Q *SFPs9"BFDq,C{YuT`oPSߛڃ]Y|<*xsiKW;>xxĨ#H󼲟Ͼ8kax>/Ӟٺ@aNltNՈw~GRY~R9Ͻ:Ԧϼ욉$NR7,>N6yxm,AzQ|['38=|/>mN@T*Q= vN. l#=Nܒ>63X*},U} =W:%9<'V&Yրj5X;Aku}C:G<`dݺϼe .TmcP2i'vV!nO}XF>X7,i[m0cѥ<pLdG`#{(NhvA<ն^J"}٠\5T'x8}yB 32/p D?Diճ=2?YҮu]*2I~bT*2Xy!-`٘a *')K,"L)5:py$^GMki{8:VQ G4R}]{-k汷{SYRTV٣5h_v `y@@ͯ7mCdo5WL>aqx>o^3j󋴯w'˵Ayb8ZW +[IsֳZU?VS>'ull \R`ϭ)cu-\#MU3eIWkbėN~ ru8jL 4y O\$Ϲ{ XZx_/_'mQI˶VYkOD@?n}XpbI(y'͂C i 'Bns}hϑnÅ6!߱Z)e~ݹ9oY'#l3%$+h~k)6ww ->R.}$lSw?}xxSz-**T' k'}nX>>]qRЩY{"Q{8gc=7(jOK3oGq"lv<^r:9D[%]a-Z E(O ?,kV[HFM@ޝq#yۛOغ"nQZv.mX#vl{~'zfW˯kC>%Oq/eME9 t63f~#}ߒURգM.I7971ʏ=܋=x\+;xJhIb)ܕTi@7-6= xᵼfMhkcQv\{ӫ,uұ}QfPw T;A<F6GSҀ|6.LO*LRD=uFObristol-0.60.11/bitmaps/knobs/knob3.xpm.gz0000755000175000017500000001032111233572001015204 000000000000008Hknob3.xpm[[~$98kNh᾵c(R@I桀rfN^ZJ+i7߹"~ߜ?_)Ïzp>={'yӯ>~K7_߿}ܿ ~x5F|T 3e~ M|JM!.(!~0zA($b7BC*)vB@ BTNJ\͑rh6 m 3jZб/Ӻb>EyZ@T9Nڼ qUjF_` d䗡uiZ1% hj?4$0P>0 ^}<%(xc^%I 8W)8#Ik je) +e%J2h\46 K OIF]t%j`1 TR1,ShD ^Ð@&L(?Yyv cCHz[L"60<~ʂdd@^z b:?`BQ5E"2xU(g Ùu C #tiDر  C`] W! :̘اH~р` 7>1Ky D<}AH ] pD1 (DxmR7ш."Lw~;9HbT-sYu}U0AZeB>h$iN n5 .iElāy0p pM8Mĸ% &e'uX(q:z6 zP{, ;&âz it5Ye1 c1$zc ăhDžprY>ͨd F:<̓Ż*;qVw#x<^AU@E>cM(!X1a5`"u=Y$eZD !0`ҧtW(k;c ܸ6UV9 <8pT$ceQeto!g wZMr_C>V'g9#G n!BfY٪Ӛ[[V :ؐXumT0;(A0* oՍ0ͱӀ~q>1S}]ȾJݽ{> Qf^G X /k fR-^ŞDB̜μF+SV_M4GXpe|\6'g\t9֣F&0BUuhm! -ecxmНYNwU"P⃈ >k,X; .dѵInȈ!\(ɟW R;!>x \p%iNS1<;༤JC BT(S9Fİ)XLĬ!'|[Y/࣮aHYHw[2mc!>>'->8YPX&'Ah~V, cgn 8Z:Ks$,5(LoWy!n[bܾ 5Ph$]@GE?qv0$,Vj:{upX.у鬡n*\A)xu<4ൟ{8bp2nŊSiSH͝z&X'4f)mVpu p.wyެ ejUe-튺Pρ* fveЂڤˊpUc8a[GD_{-ҡA8Ϛa\BAҘ<0\/Ћ՘p=4 6<'ɵ)sCΦ1:GχS.:H+>SL-Ǔ$3QIDHyNTخU+# gkH,nӆ흷k "HYd Q;nla1KhF{a| 0&=v] MyV jB?ں !4D~̧A'}fyfwK(yl"+ =İn0Ⱥ*z# r Wnˏ(CqqxriljSuϖE*-H8Juc`reD;"HK$P̄8LaHy(}(@"Ӱ?@v}j!6"hːDl/˝ 䨴ʐE'ٳP\Ź5ns. &Q0&JJa>[pl(d&A(u uҖ0D7-B]'PM!ũhiIlH\p @ur 2Eg^w$fWl"ԽX> (rߊa m5]qә]1J[{$䬻$ 򞁶`\j?,gaXמS'TBEp>nA.?n(gCbristol-0.60.11/bitmaps/knobs/knobbluenew.xpm.gz0000755000175000017500000003100311233572001016503 000000000000008Hknobbluenew.xpmZk[ίhLpaTQG/"bZӁ㜙sz:N^Zf[ֳGO>|߳X-{x᫳Ͻ[ϭV]/\/|ߵw'Qw_Uߓe{:0|G8ݸL18 (Nb aObaOɊtg1L:s@4 _F:夳_A:ībwb8{'>&~IJysݧ t'| X!'ar =A%hDoa'S^')RXF(w' w'%I)8I%bA]o__8/ucيN4O/t)AU{q̦"~6~nʪSA;~'`O;e!w~8,_@~XoIU$"eU4EY=W/fqΒ u2dG6'Y9igXo`['e<.II'ge~ |>i'+ a B#ҡhܿ # )@dn;we%]N:?HsW/?R*GI }%D){/^ݎX{@֯wK'0Gs,) |4>$'ҕȋ3-JוsO)=tw2ġ}?3i".8?#KN2,+׏'&e|Poo@WocUϗ n L2*Y~K%$αϧ֟'_dG)KgR`?B}نsoiٟXoU)m[z|qh7 ]ҥ'ϐb=_ ?%kqJd) v=n>=?}ҕ!_DgRQN| >9a1~,/>Ə-HS.08q~ɣ=Ohy%>$GQU󛐿PO vUEn3Iv>{f=)Y)^\cnx7mB۷\>K}p}' 9K`}qö9;j~鱿0sR_?lY85+8|ҟ^T<7z?8F:~_nϩBoGIivHg=c?1/q~Eem& e}-P尯qd>ۜ/hs"kݤdK:LS h3?TTMOsF?I~'\Os;iV+"/#}+ё) Ҿcߤ _R_כ~@:6KZyK@eח uYFfsH 'ʭ~V+'zX4o79OH߰;ұ =i_aKd9?=_ZAEkn[V˺kX/ִ5iݱnY_\>sz!}3֬5em[s?a$_Mh.E KkV(jVO^^+i>)8Ҕl;v}Ԯ~"'0P%ZԪ)$U h__hH$Tvn;#q6wߋ?%~rj2FyyZg|X^hkWޔP?Gړ Xxy>`T"Ӄ Hci|r/߅ߖj{0_'33m 3X!1Uu s7)4_H|@W-糴Y}*%M7d ~!Y?5z"ri{0 7W0Lf^JGЬ T q!_+-`aFO >!A甝:=iKxYrm#GzC^1äX%}*6#@ s-i%>;"CiK ^;ݓq ѓG!q(&cp}P&dG1P"R߅OSːHF#=S֐k=F0д8֚˶߇p-Lk{"2ZT[Cb#51'tO8k~R54QO\ ;1P@T_w/AuTyY/tElطY8Q .S_^'F%(b-|cysgxs%+G"AHRS"-ZS")fMykr%:zCH6/k l89 A] 44,i3HBk"y*oBrutjM;%=l1fb+@5d 7= q`J->pP u߯{ySJ뫐^!ݶپH)# R"B+0n_o0ҕYma`Ayy:D$Tti*dg%[_&i=H06Svq3W[5*2 .B0P^4^1{&ːYߑъYuKKR5JM ]ib fUGEЍu4 VGx0ƀ6pPG½|B$ tt\~_kzۗ+ym< Ab[鋜zz7Y2Q{lɞq{OBZQ:'2-x'Qy ~3ݺ6_=̣kgaHǫq68l PݏHEKYsEŒ|yo}ϴWx -(MB@_`8\+IP4(Wo~)M*ڳ&E;~WF#A}ƽ 6!D[LLWx `oƂm ձ! , rCQmB 80k_G1P#WO^YguS7|G%˾5C|+S,aTlu:t"SsqbuoGN$TW_cpW>%*:õS#-zvQu<=x:7f Y @d_j? '~6M]΄ ]i lՅ]bM S6.k%ӈ U7a0XqXu6|SW3FZ\z[=u?UQ6`L٬i \Tѓc L<\ ;4#c>Ryu(ubaU -|jݱ`Ξ8mZ ܈j*+ۗ=ReD{ejv8,Ni Έ# \hcLs*6TƙKE%-~L$ 'KiT`h}T0n_6Vu9nvQ5n^1pkjޔD]9 paP|?Sy x3WR o_lWg:i?Sܞêxc?>o~\\ڸ=l NQ0079*YxHݓ ߚ{=;i!U4|)"gЎ /CCC,q5?(Pw͓tP(  aOJԃ(? -"Zf9Oо~ & dNFړg˞=ղ<Ot;U35.nW1hTw#XK] u9˚D,xED2X ZNGޑ  h6e X_VxogW{Dfх"_΢ԋ絟=t8 c{C ~SuknSNw6>NKJ@||("`M4ӠJ0jԌ10U`PY᢮Xud T#ڿ?/Ь쥂,=pBC_^Hx!~0(TԨ\48c xo}d!"߹d/2/P{>bmb0%>=xg3i}ca>:\% 0P'[?(N/癖bJCEBߨЊ-u5hkKWyYI+O>aɤSk@3u@(۠nƠsFC캩HE![5}cLKZ ]^}8utCd0PbۆMDWƦ  d6/>ɞ7FpE\׿,L:0~jy])>$دiok۾FÓ(VyYcLG’QMf،n]'4IBimoM KUc0L|R$l^iWr~dcDA^?J;o{'l{8}-Ơ߸+L~0aN F&_ث#!Xboҧ]Y!LYqn3;G-h|hq`ˀ_]Ew`>s!Wg X#KHÐ ], #8A?(3pk nqX:!U/U̢'E-5ap``V> ֑mB,1S l9!/ODa2CeSByaC= ꜠ unVak}6A. 4$_ aY8Qi`q"d QMFK ęe Q};A`⤪lO;]CdJ‘ C`q3 ~!TtbsI,ڡ01 z l2^9+{NQ1j/jCp,#1a|~#?@ Y5pyX`(rP# 8I'\W0 !C4$ Flk7c3N:C1,tB?2?LLA+\! ] q,6&5a94z;q)&,T4X,~Zz,2]Iz9{h+Hok 夑@B;B} A'> hu $ka\h㺁d9 𖥂)="=>r\R`AEG-O6ί"^>}Tg >S4KOXqW>&CF~U]Ч=_ dW@da,{XpY@zT a]hv%o!g jw}v\Y막x z٥F(' qDwWpM6~/YP0K(ujϤ; OJ]pV^,l 3O>:Iꎡ +]5G@vXJ²C pmo)>xKgŠ@'q.|N5`eQd"#=ȧH=1O8mЀ"ܢ^5+XߧW+]wH /W Xۼ5(pΙӇMQ Fr(O"UVDJdˤ'n'/oI}Ou F񶙆4VH yƠOt`^К/kăKf<_"]K[-g8r8pk!5NB֤'x v3FyGwفm`(6atU^,so]eufA2C{xI ?ƆL:iھVΗsl}@eqX *{IOPCIh_9*Zso k~JC-jd^Od6~nlWbwd6T gT&u8jۘ9#]`Y`$݁kX+,eMobjAND#yxHY~K;tŔ!fw;/$zj5BMcwcvl!fl#bD*w l+kΨ|3>4?2g䗜!36/y |:}' O:ds(S<QUF%B6').߈I\Zb3&;eߤPw劣`0<'X.9bfljzN0c;Ȭ<8+ #c]#gPq y(R ià#(nکyʕ% 8e XX#Oүw19'|Ffr"VV21(dsȄZLix&GfpaE ٗ85{;##i\hwF y s؎>2)eZft̯$kF\ą Az:iF$|G Wԣʌf~ND5QAp &鲠ã0pLB}le/Hgb>n Bl*: os,/ 0 *R@|Nc@$}~O_H4* !¯٨  Pmy̢g) NjavTZ |k$9qz`.*6M19X֟(=ŃŪsTXL͒3Ѯp4Jy8ltƷ5&n_"O^¥Ԥ3"\EWޠg/3W{fPfHV)j$m9X/?Z̪`.\$mG,ZG_y\Z;4K]%uD#,B%{W*jM'QYxޱ\WX;HAR 4Amfthl jri=XE ?{iW4ȱ A]{VlP-Pq;υ V-r!#Diz~L?Nܤio} ЮN" 6N D窳 a> q._p1Fi _ \Bٞa{_Qh@;A&dk'WzvӋsK=ҳ\F {⑻tzLQsӼ6 [?. NBD'tub W]~GvG%b" l0>,a}J{ɺ9.ZN91 0tY8Ssև}4P$AE[L<]jrU'L=řZyXRNX 6#qq]SrBn/}&yE g:#wyflX.dOz{fbU7?'ULN{Yo.`X/9%D[7e.媞3'ݶP-ɭ@W4zy}mQ6s<~]ُ,!_qݯl}lmc' &]TtumM K|L/+mXyΪɴxS aW;$lFkqؐ6uT켁CXpƾG؁i=ǠL_7O1͸v23L#!XL$"]M*0/88$.qOCqп`g|+m0f'ƅ3ZŲy|6Oa.zi$#0]@h5Hb@ß`y,ǦP/ʳqZ38/nt?97 ϷhbVz=6n1,{QSL.a-#فֲv4jFyLġ0ybv9&o}$i{Cڎ*?mP-S$}.(ChVh& )C a*d6exڬ&?6kSup[Z99ncT"EJE_"íDOюcmPA{ &iq[a\(zKYpѷGU;{֕:ӑfM^zX^ehV( :=X$Ȱolp}]^*ylkIvYZ0` 8Ո5!J#_K tgX{Obf2\^!q`~C6;#ݧݫj^>㚷jƀj9ϣV1Z5^_e?E˵|2uoV/FRr;ty'Ǡ/`Dj ]jPXg~W\ +U.a𭏿yշ>A,p8-gM٢J}Kc+yY \'¨w"@ 3pRbristol-0.60.11/bitmaps/knobs/sliderblack3.xpm.gz0000755000175000017500000000325111233572001016536 000000000000008Hsliderblack3.xpmEgWK?_E!I($;;;F(((I@E~{/> }!otUXG_?ްװ^:LX-'֛1Z?=kjS}eipnl$ܢv 4ӴF,4yGoʅ)B/+EZ+FT*XE_a[kܗ>{mmocwkT{ʾ?zgpϧÛrgpZ(K#AG9s1M7Pt~s =^x[R? M܂yh}phL7)H~C?z褐o ,h<y-Q78_9o硉w67OCQs3@!~T*VПo;'~1Q/RsRX_T{.\zzYa~]f? 着+_xSp^C^Cz˼"k/eg^\V^?Ylkp#Y/zgmzy/o2S+0_ṘA i9+8ķopSiȇL ,czxz1?3-S˸ޡVZg"fNx1 i^YEɡW#bw|ÛoC'_1Ö{ės\Sm]}>/|Ș_)9 +ƌ)K:o=b=᧲c>e^ᗼl_k~-{^{#@$R2X2.6L$B2r;d2%6$wɍ{VDbristol-0.60.11/bitmaps/knobs/sliderblack4.xpm.gz0000755000175000017500000000110411233572001016532 000000000000008Hsliderblack4.xpmYo@)=v[>VqC8E bOU/YO)3}o?8iob6m`v?6˗Su>3Y.-eηccc"=23b28.Sμ `"`K0 >E.V+ e(U(T%P@)WDw[2 ~yCbsCCTJZ`#@η.'W(pbΦq6`C(!ڊK@%K*H{iɑA-"O# b4CV m$f0IQ*J 9M'(5 )RIe׾9:݌XzI|K@l-U]U=DS_'|uՇJVZt>=O *mP;0Llvqu>\ryw|pȏW8U27H5_"bristol-0.60.11/bitmaps/knobs/hammondblack.xpm.gz0000755000175000017500000001354211233572001016620 000000000000008Hhammondblack.xpmZv㸲}+JHvXPtr9M|m=@]XU<=<_GUP77wLJGW{7;j\}qUUʪV.CRwt1a˸$ņq?;¥)քb\,USSl8uSg\)^qWaǼ> y?.S<{[)d-JOߎ1IW{jEq?=R=4R<I6n~_+1n|| }`qˌ~+d\zkA?C[x>nKqCGߓy r3-^FV|^q=TDCP7k ۻw7.Q=C0=?ٟgėp0.zƉ7RD{ gGxVgGpw_eS|7ɸ%H__> *?Mi}l\7l?_b>K^֗ozZ |k'"oƛB=*ٳ64V'e֯)ٌڟc 6Gqq+oG؟Y!+#M?h_k%_XޱuE|q62|!cc}ß6_ =ͳpʼjU+#>~J5 ebp<,?[|i,; ,^ȼA>KP/4.>'?{|>>uka^~d ~%7!x>G}ׄ]eDCQ+nX{Gd؟/ߡ>^y3OOo7  ^_D򋨇$;}ܟ+cU/Zr^C̓ 􋜷a[]Y?p=)Fk~`kKd0__Λ|'\0ټ|ga33jD0YLV_#z +vÈ[wdwi -ۄoWC|Rؠ~db!li~y~!K`_{+c&㓐w9gO||0ټa?׈G A>d` rx3r>wc0<s5.e|6S#^?^M$ߌ;#Mv Al\oK O>-JKY?1ˡ_x~3;ߌ Z_cy(x-MOm+AP.ٷ.78'K<&&a?~B8$ߌI=!FwvBM`CI?^? kuǸ!>~orRRo;.O];0N|㺷@e1A.'o'}}O\V'G t Sa[zko|qbZo JLP_??c7 )仌πe~q/ٿ8:/&0oOC}6Xy~1?A=OOyA2ϓW'TOoEC|'/1 OP {'/EV8^7?|IBe\J(|O3z|f{3۟ \Oc>Kp^rNWK'2GW85П :O6&Qa|[KˤjY/&ĿR ib[ U/Y=9-|ɼk9_Agq-Zg>u'e\ ->ez ߿̟/-Sa~Ne\I;淖z3_:;?=_I+淖0Ƹu?o5,i/9c-U|u֟_q3@'4C 974(bCGo-AX|hrhoS_z; EHG2F#es"E|Gy_2>҇x_+}ve {#@EcQvOߟ 7~R 4ៜ_e$_U5Z$_|P?K^('+X?aaO!_3#'/BHw ~C|-'$B;KO1~I>} ;y" {_-K?PO7͋^d?aB>w_O?EO{k,?>߅/oԇॐeK|+!?WCQkxR_Wx~U.8?L.?_儯:_9l|Xe;9C'?b?囿IUrRR9;GvrYy~7OOA̷?'1.b6K=|Þ?%z_;M,Ws2jȇ]ǺX~q<6s;ſS`'gG<'] ~%"7\ &7 #}A?O/%z wyOSވVο6PnO>'?_;Cx:Cc\3>)ِW /P|?R+Ksֿ~FX'O7Þ0՟:/|JFӊ ,NCI ,d" o<~g#+/gݼg'#OΛ|67 X^G>_m?A^n'Wy~c|">9/k'qo{a>?~c#> z=źgȯy^___O|tu܀9n ;OI>>I~^_+ȿ|GpRO-/w wCOx~~'GKm3'z}l/y%˼\}w+lҼ[{<|''?8ѶWWa_d 6'~S?VVUAgwwB ~5ԯ_R;#vՈP{SG}Uʪꪡ@#uQ߫uμ乺J]uԽzPI={ߛzW$ZKUuU{RUSjZS3jVͩyՒZV+$V՚ZWjSm}/^Xg윷y[Sj.aKj~m_Z{>*oԮ^fݶ?^nK}ےmb-ۊ}PUoVl6lC,#;vS{f=wˤOdgԥ \kۍ%;{G>hMY޽[}ٺz6m" Gvlٳ³fIn?cz>g쌝sv.Ed]k>u]z6;^wSmM,)'/7kqF̅MʧPC`Ͱ57x.Ԅ!oM5_f/e̐T{Y̌ym{{jȤ~̷2%o3R9rĔ͕={y90nrE3Gv<kud͉)dy oJ/3srjlUxA)S>Grͬykܚ;e`̞->̳Y/=2GL,zk>[roͤ|iy.k6}ڦcG{MMQM0v,fƬ[͏Y3gԼv.%sD6]X1[La6͖7J9댣FV9w7ݨpC >܎u#n!17ݏv%W3s6v++{ݑ;v'nA3;wMܥrݺ;wܣ{r^ݘW >܇;p5]˵]u]MnMnͺ97ܢ;InŭUwܺpnK!lNkzTOtzP/?ғ^jG===ЖtLrN{u׾Gʺ뺡@#}O>^B_+}Mr7FS?=vݝQ?g_~S7I2k\Wwg=^ЋzI/JϚRuo|5}7?ogHGQQ!Zp4#s"#ˬ)%W4g2qEDP9Ƹ. "" [3 #ߘ8j^1``T'N1XU'AtoȹPt!L4HI5 wp c cp<)3^ñk oƽ#>з>e,H6m $s=LFqtӣ̠ kz̪3e3h_\vL2G:0 RFLrgHmaqf$`? F,^ƞp#LCSTxh񪌡JpZ޳f:f 3ڟ| 9Omj~H_;URsXWטJhQ?XCm1U_~]hN4n4E#:լ [_J8VtRM)ikj`F:׌۝c|ЅTSWqjga ĽXǴln5|u-ڝzУlf{֋&lBzzlҽ_|7->t#+)~jAZy+iMEkCҶVe ;ڵ}V{*Zf[+d5-qׁʪTUGٞLYKg$C{C@)xO:bristol-0.60.11/bitmaps/knobs/sliderArpRed.xpm.gz0000755000175000017500000002457411233572001016567 000000000000008HsliderArpRed.xpmr?cx|:?4 x:?:~h>-]omVFPjԍ?0ǡ1{{s܇f>ST*kZϦj,-n)_.zEŎRP)t wBϱ\Ϸ >|3s|ωp!_+|]sNnu+>Oŕ^VVo+.gGqQmU?RR<(5 .m#oyTo[5p{6(!LnJ*=uڗ}ܠռg^)UkX͗%'^P>%gL?e_wD^Rϕp񻦿 e<;O|/\$?ɏp,olm?M|v?'糂1ƿWg-?N\RNJ>xSM|͢joFگҟYw?G!>bo\EO)S]K}ZnW[Uy .3OM2iJ(ܢp!!Cz@@BGEG!'EDoLOϐBvuM]? O>!wBcg8| bbc z: Q_Sz:c>s z`>7s%z蒯OWmud%Jo^T`'.,'o.K> S)( *~-6-#w p.o {&ȰwASz=w2>yă[`=DGgz[f|Ak'./W̪~~4 V'g#Y{=xJ=">pg0?!?=;ו}|VeWȾpn.>ɰg =? z?(e<ۃ/ďz+ _G~KUf }Uԫ=/pC*yYoj_okE^M۴ i q*\c$>%||^HKpv{YPb>2_ 7b((o;* {x=` {;a>/D<?ꯃ2?]1 =3.D?]p)[)fDoEmV8oSwNK]?/~AX^^Xr- [x^xt[!3ߛUcO򛧾o~BB?`OUh5Mr[-퐡_þA큿 E<|CJ_s@x癏.3;NQOPSp7E~#)=x+~)~ \ S\g5^ˊ3oPI1*>Ui_' !~ʾ?xC:q$c}9NQ0H>*W-ίg){<]KK׶n[NA遌H=O=}fWM1>xxx2[oCoog~?$OQ?i %ֻ_ߒnV^w[zWܩ-v'bO${gFS;ݎWnZ7Ԩ6bOҮ>DBO֯M%i w8~:d.=OcѸpI]GS "\fg"\w_01?A2^ϒpgVqQ_#OW&ޓ߯S7,}v?]T ϳ0S ݲ0؊(XZ&v]?QSTt]Y+TꥺWU|ኮdmCo%a=|ze[XXO σ-wv۲Po5% z(J)3? }U_0?݆+Ίq/ݏԤ~ Hñ~vbAT3aAGad>B_D}_ IǷg[a;zt 1ƛ'x aߜ}ec׬|߿_TnyO-z(o^@V,̿ {~MqD ")\|'z|٨oOjq-gY6o G| & @qM##ؘo_X79 R\l/zrGq6S"Ol7kc~Hz=;*[bᅤu<S1#E_`=*+n7 z שpz ކ AOyO= 7)t}QOGOS 3!뷍=KOQkƗ/-}1{`'S-_3/EXϷz?MmaoFDoz'\x(_?=zIX??yꋰ~*MX/zCG?n9ϐɇ L=_#c?pp0c}0)z+PS1>-x}ȳ|NXߟ 2"=Kl.?Wih? _m"./t%̯'é+>L~,l.B_0"'. g֖R=CrKz~OO;boϣ_aW׏#MkTϛnI̷>% O碰~\RGe[. /.\#7l//alǴ^`>99x_ ^ǥ~p2׈?}P?p|BO7zo _O+ ~]/xxT\%E߿#Kҿ'1Gדq.9!IOjJXǦ%<׌>_=+^I> ɿNjz=$[~>*ܣD%poo=Fb f {/KXӎ_/WXc'WK>8^XE}1 b<C1=3ۊx'>11}ʾQ>%tb>%IAE6SISe*K<a]ޮ X?뒿nCzQ11wz Ũ'1 >n32?<`%W_^Fi3~=< ~_}gߘP?~&MAm%|#z[7;lx7A{I1EihDfOsDOOoWo,\VU:lPw=@zzDzD|zDCޜC~;V\IY+.u.@}x _g ^`O}Oڋh ^;F<8 "^.| (A PO PWwzJ}ԩԧx{?@A0xK z8V\N$Z?W`S<`>=b߼݈zVu'K܋?7Ga֓S_,a}?*MX|PI}mG:vaуa<ᯮ߈1x1_S'40Y c>y/kA}YmYX߯~תQϗkҞY=Pҿ>)Ϟد;#RSB }^H7~Oy߯r8B 8'>"#Fg@2^ܡ?a/w|B/_ .DG"\V\a~UqI&OCAҟޟ@o#OX '?_{*7$ϹpGHЕ_k}Bo; >B^?h_a_i?FMh2~W#gc>c7ϟP|zћnoJX?3{>ا_͂Yx z} kIyua]6"wMϋ^t5ź7;a}c%v؏ IOċ/ē'~J$O'z~N$ O(ߊzfDqYFoiOoa]^}Se-I| K k{{Ni?<BxƋO$0<%'/ϟ0<&ϳ>t}IP~%.>~sSXh%Gܑ'#qL$f\3\> gg|"7^];M&ҿo7Xϸ?\:~?1>MX>Gº~#|(/2/zow?ߡ} ;0\3^|;7򳯸c~+C^珄=Ҿ'S'>ky.O% xõ߽1w> 𽰶lYi?Bx~AƏ/_}SQy|秶7=~;Ҟ?rأScbg\X')+7-7c~{7X?7/~?0ԣ*G[6ںW a[oȡ^C _OX׷TX'VwhY>7G%k:^⪾ !~`<º>cax)g9{y %e߯F0wҟQOM m;r}qI_|#xW%j_C)Jj>Y<_epχ_YίC.ϣC!'C2ު]YϦrECQ'¥,|r{-K!WgW'c7r}"f{p>nŕxd߻ xL{ۆom_6iXm8kF`D'1|#g Əil?a6]c5o(E}FŨ5n4oƑql_83΍ Ҹ2ָ3x2ϋjƇ4ZF̎1fۆ)cژ1fyc!}X2cX3֍ c3F^fhvnAI臹p(0vMn8[wbX a%6|QxYx^Uxބw6܅CY>/kho{6V;a7cx8NSt8Άs|.Krkڊp#vk2cygzwg؞G{y{9o~OoAoF- ^+ye⭅U2H[^ؐ;gx[xg_xޕwxޝw=xޓxޛ}xM嵽zb&Ioʛf?0yނ-yފ,Xֽ6^fjvnAI꧹t(Ht;I{p:#h~_i!-ކJZMki=mt?=Hӣ8]N,=O/[2Jӛ6KC>KGL[i;ݴD:NL:Υuo>]HmRZn^VC3S4-65c: LL̙Cc~9l9jnY0f,j̺0'7C?pd'YOs¼4kƼ5{|4ϳboa6͖6;fc9aNS9cΚs漹`.K油bkHnni_馹g Z%QH-Ӳ,r,׊ J,YCրc}Z֎5l Zֈ5jmY֗UV*[jլ_[ +o6[֡ud['֩uf[oʺn[κGz^Wz>ղVZ=kZ3ǭ kìys7iMY֌Wf9ĜEkZY_[V5kڰ6l* mNmӶlvl׎풕5`-ضw_6 ۃY#ey.El(ebW]v޷C>OS>/KZ=wl<؏M~iѶӬwoc=aOS=cs`/Kbkao{b#t<'uLgšIkY}a=fg*SY8ͿV8sv!gq>m?.vaguFQgvStJN٩8Uԝw9r9sΝ 'g_:Wεsq9j'azp'yq^7pNi;뼤=gw&[kҙr {ƙuygYtegYu֜ugtEVznꚮڮnn֬;qe|NY46[C~;;꾥[Xܲ[qnͭ 7{'{枻{^7{޻^Ϳ}W6|d64ݖv;n ž{;N;ι.ꮹ N]w7Mw/[Xfjf&;vb7 $\<?g}Ukp< [0}+n{r\q-Ǎ8A|I|E|_M|C?K q3n)qdm菌7lض`7ED<OYgx.x)^W=,^x#ތEvxA6Y' > hQmHAl1VaC. -' `7 F#w+RP*A5@l8(ǡo׃p}N`'=.*n.)x^-x6b4V:A7cx0LSt0s|Iq1Kr0A[ zl{mLyQّщGWqmQ ȏrP4Dv Gn4F[wbT4.oC9DըգF0:$:΢"֝:.jу1z5zޣvԉQ/ƣO_'gV:MEp:FEs.^FkzmF{M^vxI؉IdIOrP2$v '1웖3&WtIF;)X_I!bRJVYTjRKI#'`?y?H89IN*.Oԭb6}~v70<'/kr̀[|$ͤ8q;INMzOte'd2L'3l2̫(,$L,&KOfh,'}E|f{5zUk:*g럕d5Uxz\Ch~#p7~Od0}?W~d?% Di/yt:zr~/[u!?q~OaGQ/ YEoU*u iyEU?Blg# 8c?s¿kƿ;-*f}Oggbpblc##| <9F7/˷_!tBAP G=$Ayh׊ qz/j)LG!!ɩyϨ>Cb%`8#ξc18HK, uS*BxHCPd-qGGPa,϶"G$h+cy^P{-1`+6bđ#("{gmDAQ è\cþMYz߶ >7}=0<1 iP,?h-&1-`BRZ>ɲJ,Mj²c(gyTPr(ƶ@A52Ak>13aIq-eDY"KXKdL3<#^!'UW҄l20=_Ҳ 飐`MXkU 1LX+91cމe*MAec3P )'0@xn[&Dz\&+y j(,c2ثeʢ4Bl@/-5ViG(zX؍Wi[6{X56 z io*LdS &K})z}FZ&o4W&WC\z8lX,M p.]ax{_7qeӅ* uo sðcn? [q층cs2p)knα:QfSti|iB?:Gp&Dup&')N#9$-\g|\>/٬/ t1eznU6 |Vgum_Vٸzzak6^Zozz1}CiAm?ceԘe+/d|zO=?o=y{߼ϼ^y7o/~ZEbristol-0.60.11/bitmaps/knobs/slidergrey.xpm.gz0000755000175000017500000000117511233572001016350 000000000000008Hslidergrey.xpmuNP* 9NB*AD~Xڧ'gu ,UJmw|lgذj~?qqHyRgƷ3ZO8g}hk;N`V]sC `MX'{ b@]E]EnL`('&u/tGV6u)8./ ЅxE`Yo@BZHZK`Ms= s@GW8=4AX{KD|\!p&6k{..K$4#Q=bHt ܈OTX lX#p/{5GԷ|T߱l.KsQ?gŢn}߷b!wg4t:?g D:mT|?(Zmx84[΄2á~S+W euPsݗ?zqFw5LQm=< kgөq=6QmpKn=.9~RSJ'Vϧ2![si?uOQ×bristol-0.60.11/bitmaps/knobs/knobgreen.xpm.gz0000755000175000017500000002026111233572001016146 000000000000008Hknobgreen.xpm]kwFeəcQ4#3Q' W CDYN߾誾]UݠdۮpH @Uߺә{O}vv7믿~_?~Q}tm-A|ܿ}?|o~{x߷qp_sl;}A?vYiC>nh'>h>vDۏGo{w[G-jz·rnVǷ k|f[~ZOל֋։o?vp>m+Oڭ֑ov}O !_ۃ6C~ݦuon?>nQ>hEEuڝ.c_߸]vm+nw:ma:]2;nvzmj=ܧGNs!ߟIAac|:o/wE⸖cYOjunݥۋbMǻo;uE!y;vxnt_t{}(;}Yo{v-j.bP_{ey7A] =ol?^yҥxIAe9(rp@>P?wNXp$a$/m4K+ju#kQw{}=>8qw||LGݓ}N^9S{b0E܆^6u~zZe\6-9A ^ԟkzɲ/Z/ul\~9ZbwUguZ^Yʲﲶ[z$-/E^-K ^+=(lR z6;6-LW5]Y ZR,}oܞ?*t"FdL߅$|O/q2zmmYjYXl91F[XT;fa-Yͨ׉Xca;`sO#pn}GMwa#ҭ_tTP;y y (x+5&iwni> (h0'% a17'`\yໂ^`xM6!FH`QP)oL+xOUDcoKaI3w~KG숨>ֶC~I[ #:lo\,j0(i_HT8 2MlM} *, Zwugzdw 7n0#%ܰw Bb L:`4\DV)h[-h L=gQzK i|9|]G#*g@.'GMcCS,iУ`r 3+>Z4ĢG%&D/9} ʢe|10>^b{|ZѺΫ #:f]>+%xNa[,i2DQ-zR"ؼF ߻/N/h`T!AdU-bvy| YoOo^!3x{1? ~ rUŒuTRGAF/;+Ɋ,MQE@}5c^y<,ӂ 3z_DoR\3_uD]˱ܬf xj¬M`v3IE}Y,|*X̋En& nXF=h>&B 9H60=KɓynX2^UC`nj.UD^EB3/kʝl" 6Q^?>7O w~v?}=-o]^^*pCt$٤6W+Ō"F)'i (?sԒnKz˳vNSkdYAkb#҈8"^1eL^.Coj]ֺE =:}f4#>[3^/H_n Xe XK4 ˹ZA;,ha5!Yh<[$LpNuyz>,_Qi״6 ;i/X!]үM=)s& .~$7G Uc`-La?~iU6mXz"[}]Ck*=auZ^п&MPL#y ӯ6bN>Q#ohT!$OML[+ $zf`t%813SeS6F EAzYuȥ|4u  KEcmvd J:&ęOl?BW 5)ێCFΕ,tFrO)[Q6t#<$z9wҞ2}0@XQRIsc|Ny{0?fBS Ec>ϝ^\HEpq0W/=sbXWS(4> %3nܖ88WG no:>5Źa.򺲞 UJse|$hxi9QA-}?A9RRV>zb+ȸ)_,_;1Ɖdә$<@})z ZH-BZc 23 h Z7>SΟ1bY8BIԂ;ϓ3\9 H1 ^& 0A?EΓ/;.uJ8c";lBR?CSaD\:!g91HFp`Mn(MO@6pF^+-Bn6X蹱C?ha` @֩1UJzOf< Peܗ$A^_ʫe /DdsꋅձƁVNi/r i3舩9zna%>J^ 8^c*NU^$3~/CiƂ)_Co' :>? L`BÜ-"(V엳+iF9OJi;FV,`TR`e\GvrF|0$s/!F= ӆq@ "%|jJ-&XE,㎷4<ӂwa-zIf{#O!#eVFt^Pu ״k/kk`֑Nΐ%KR0%BEeGeN .Kȉ29^WqrMomʯGNm<ۤb qR.*Dg2is d2vIgbMO^0b1g Þ 8*6uw,՘_7(M*,\fzo0|dA{O3G,J~F .MX< :AON̻03͂DE!FW|gh5:Sw(-a6IcKzr/c}ު(G"#'N׀[3㩈FМi:{?]Og qeb"C5Ub䶓;$H3Pf Hm}l_/>Kf2A at1N*V}F UD\7=QBuq$;dZxq]p j#̵c)2ͤpppɒc?Iy0hByZ^ o&|ASDz ʥN@]<\r]jЃxI؁Ǯ穦W=I_2FkG8\(񫎈r!9)7 +Ls*ʬ[r4s"J;Gaj6tl|`xuUc~L`ϵB{W0=odmEЂJh<"nt Xן!ׁ[FX~R "]:U|-"aa+RvNGIiA{Ħlm xFk⡏ O]kid>YY-`}I^α) 8sVMkXV@m"C%R;Hl:?h"A$H+e3I/ ҽ9Ovp暱!gn{J`s!TլKHJlbˊv/|tyXB~X4Hz&"Y2Gg$J:׵kx٫8(j;" b!]*H2?E u l夦ĕzrⴞ؄\)3 uCr,UGNl0p72}Z(qBk+Gj4/j$Ȉ}pkbvm++ipk8=kTP`s)@/,NREbx1J/d7EktP-Ŭc;  waJYehetӢ!Z̾dl^#o2OS^R3AQmO̒ xXHg ig7(ޅ1U@Br/ ]h1 7'^,6^vǀOH' L5a˵= PXVhңh~M$2#LF "hb9I$LZ% { 4[WÊ ZCm(َ/âӧʤ8w䅟O.5zk20#^lrEd`b᬴/{)}%8^&*Iz$>mƃ"bA{oe:S\Z36/8s~10OʵܴmU8-GbQ<[AGWJ3} K2ZoϴO O7834oƣqDGTn[hvUan L[sl7}V?TDV䌨=x*R6}f Q7d O$a|05GbL% 6Rr2ky;KUQ LI_U mo'Ǡ' tXBγsGGϦdm|fΫ͟2,;iu4arme:jFK%WE'ޯ]*~l?Ӕu"ߡ~eHg$ϓڌ% f[\WOFpPOg ܤʡ!3=tOrh9гi/7<@ȜEr(ϸv_|jPbristol-0.60.11/bitmaps/knobs/sliderred.xpm.gz0000755000175000017500000000021111233572001016142 000000000000008Hsliderred.xpmRU*.I,LVHH,RR(LI-*JM(ȍUUR24R0T0V0TRRLVKless qADW @07֚ b6bristol-0.60.11/bitmaps/knobs/smp.xpm.gz0000755000175000017500000001746311233572001015005 00000000000000'7Ismp.xpmZi[L|WQ, m[Ӓ@$aI̒HC~T;b𱤮TLs[jo#o[~]\\^yԋ_y?[-~9(d-YnuZXE?;Zl=Um2N+W۴~l\_TIYQB3Eq.Vxq'I>SƭnR=p&E=q/ OLEip0"'UuI]<'yX}쿶HA$/"$s?nf2_&Eq>Y898lP_D??B|,糤;<'/%XOb~cV.[&I#'/w%A<~8#\&%WX7y_W+o'ϕ?olocG1j5pqEpM+- |T߆Oc_Xqi/i>N3K2H}kONNT ýO|‡ZF~6)yEq˥?nu4%?wS 7p ubo`B #r c.#9⑊v$T|>wT_ {,4w~f\. pe`?/"ZSA/] ??zE xPJ>ŸlUmoG+ҟS(&??);#M)_9'8z (?_=עvk?_~/wy}?.( %pZ%%߿ ܯˇ60Ix;ķ_ o?_^I?aOOPeu{!O|I*|20."7^5b\v_\_pU8`\5\YE_ew e逶 _O+73yJ~Cɇ}<ȧ)'oC#_~~(?6ρB/0_>ݍyJ <~U||UqWo$%cV8[bΜ#\_]=ؓG=Y$OBmXgX~M2_3N!B#F5|Ϙkogo|}H(_]2w]Ǫ>C]6xq}<5πeUOE~HE#c\.S_s_Ⱦ5E,CY0ҟK*|1¿9cHK>E`טFA ň1OvaIq=mȐ/'˗o@|ĸecg肯nT8Kf؟q=)+pI~sy;EΠ?y>w1o?~i1n_7_+`:x4zfc>6GZ'jwKr[^zPs>gC[T/ᏘN~8F WX>qnH}PaO\ȼ O.xn3nyQo<-i/f!>N]>g;зO?#K-|E?.<>qMqYR? cj)#o4Mv/)%9_K**3e_>B̭'ϯRy_gїzP/s>M#{_K~}_n9e̺ /oQc>xzx>K]h|q4 3p7ؗQnjO5S4m/y ?_5w6?u1F|.\|×_>€o|%deh|o.ύ/-띫Q/-JypL3}E o7ѯ|UkO ѺW[oxp|݄h~-?o|k~b{g<ځ>%+?.yG0 HhŸi@OSۧ*h>w1yRcOcෆ¿KJ*[I?e~Zjw&S|o TI>KW?E&^[IpECC K o {lof/]#?o'0K%&?aaV}/ pӂ~;}+kgWOt[%|+߷_4(bS;񼦋}1jƟGzsklϚeO x~2o/zPlh4ćxTwg澿\&-سY>?B}|MSI}_x51/@}oX? R0.ڥ||Pk~0NYnǔR ,Wq9~T(u_2*H|i)\$9O;3uF{\Nۈy>ӷ%Ͽ=}A0'~]q}vȣ} Duq>^$Iɷ|&z<_- /J*K.1 /cg|ucqL{c`A pW?~|z& r~' +束"?~~ 9N$~SrHK;xvC}~v|p n/wgW<%,#?x&1i[I0zu,oNk1_? +(u\}WЧ_r?nSD+{#k]R$c=[J{`ˏ?'s"^kHe>U7Ᏸ ϯ 0S~CU4QLmn_γ2N32p?kI [ S=>Gex'e eD?W*Lk߭8T3{ޜ7阧מ&l[Xk x{^^^F( 5R?{_hw>k&]4k;3HENI~z>) iQxXw,9浚)?Ϛd9r X.YdZ)'t8!HH3?I]m;U_;%[wXN?z ;kGSkc4w7&lRߴ҂do?,Ú5f#ҽv6i~KM92:ލwݱ9%sX}Hm,sK4̞N#k=,;fOR']QNh#"z^>} 8%[F,-=S 5d(㮷FI ]k;LH]#dxэ/3 ?X`l_t]m;kR;l1>W`15cV:bkIYV~CgohS-im=e1[ ȰϞ8'5bda'$LR7؟tWE2"OI!~R2β< ܗ3[,uʒ8JwlR?=5=mdd qsLvz$IPop%Y,Y y2##ѵ8dq$j㟯>$Y֚lW]f)[7>sldrvKR.]Qg,' W~'z^/9.e'Le0:=笲9az9zXM]t[G:։D{g u֒ymuR]q,ɻ={D2s]RgE>'Tw}I~`;שf)xD?i}+zXj~RDWwҵΨo&$?XYel-SwY+ٲ"<^CB Ro-_~zG'=$^I3f~I=VsH1#}=k'C&Ca#\ Wi,|·\8 ýp?l aIhv$ V\1$]:& =WN>a;8L4<,2l/(< Ó4&!\q/)v{$$_#k-E#^p : oû ~8ǔyr3{VT"w)׳&t9a"\7—fnm.|jmBcoLen=el:!]=gclbyKf,yb͢3Sso̾is`VLG`&2I6=eTjI"x2yg==IS4-|1#sd͉95_7ݜssa~Ҍ2W$uUp2 '4!O$gz-uu揹67ܙԦkzoY3C¬ l-m^捱u~YRw%vP״:){_?_䏈_v#fBH;TX:]qN^}NS_cڿo;kZ11/R,Fkzv~(W&Q夎mP+v4>]T[-?RJT2B>/jԱ:QM:S%)vۦܜU.VaMc( E!l32WM}WQxՅ~KDRWՍUw˜sƌA2o.dwI2SV]S}5P՚j]mjSmmJVo[nS:\cҠoUz*MAT`)X I0,mE<ŷ +ojay8 Z±v"<=G:`/Bp`7x vqipƆ li![ j2F\.̅ݤyPe >_Qp'id^c1 IM%%w"JG7@)D-E#\` BiMnB^{9!zVUle֟I?p٧%vSݵ .& *P' zu zA.L(©\\xRnzw6Cf,akRwSX82?y`-/c]6#]=@^N%H& Ѷ,\cK$盙; &,B.9J&95e-"B^Xd5/m9bf ?$DLk'҅Y-6{xg?=KHv}R!r'i',<- 77#{i+s?% `~iM_Ox Y|R3kLc}>r0Xi=6|2O X g|~ ȋ;v#R ADbristol-0.60.11/bitmaps/knobs/hammondbrown.xpm.gz0000755000175000017500000001615511233572001016676 000000000000008Hhammondbrown.xpmZR|+G bFf4#lU)} G8"kZփnӳݳn` ۽?vc?2&LBw?uݽws0N&8!pq>iw8Lw$xLj} g"?+zW%?Nm+pOp|ݵNkz{7\^a6,sx-盾~^ ㍟oG?a.||O |4^%⿁7wƱwsow-_7#aLaނoq8"@?#i`c~<N+ 2_K#y{#>CK72\h/g8b g3y{~ox*} Fj,6F?_7@|'@<+s׬S?n^,淑="adwCqzȷ_U<m,7=RW~BS5Zl^FC=L韏j#]?uK!&~oKhU>gH/}V?opCo?VxO[ 8o1~lK~?ӳ2>o4d| _ɐ3{w|4ؿ7 ~?w^o1)!cڐHpgwe/ ?__gzmdsgH[)] k^ݐ)@i SP׈/Ntŋ0(_-Mgȟ[aT,ʥ>l}[ſ ~Yy?5~Xx/J9U>.??ϟu_|Yx=HM1~g^_8vxSś-߅_s{1J?5-T/:Oo]|C>+3wwn*-6.{ԟ>@zb}{ԗGK~O|/O'Ϥ7-~p1_2>o&/^'/yMOW'1yẏ7Y__o[*Y[cTLt!g W/>@^{0Y;> 'oU*&|x/>x[Qd| -͟/cRC`c=3o̗ɒ)3ƟF;OA>|v E /u~߼ǟ.y lwoW;׻N>///ϙχ)zkg?v oĊg7Sm _X~7~o|dyV~(? <O{]7|ޗRE4/S]Oɿ޿8||}1G8A}90I1O][ )鼴?ߩה?g> \|_E>~k~C q>~y|X34ɀo7Uof~b;X$.koMh/﹧Z|?n.muyTB+P^= og|w*9:=b>__8,0c5i_xc_1_YdJp/xcshm~uٯY{wQ r~?o_:bRC2woǴχO(΄y?O 7JGaڏ/g/EH{4 H3A ~I{WWLO4t*Ͽ?sg~~_K|q7W%{__SՇ=[|-pՄ@Τ7|O%t[psW`<4>s=8?=z''~ߖ^PO~)79sϤO{\Soz{AԨG>o0Mkڟm:*J/eK/y_m;\)_/[*Yo6z%{[o({D(COo!\Ř_,V~  +R7{'}魄j<o,jJIs_5#@??_w7zx"{*=03BOߩ?ȷs}/S>K)Ǭ;q]zS%of(=3ś[ʐ-^^8@#1oc \x~O7>~~kB8C~Kb@r.>};~p<|~1]@B8`O?W>S|_sxbܟG|V9W7DVT|VLJ]&?\'kK|g +J߭Tzovg.KsCoPOn.Xo+~'wo¬'a/<5#ߏ|?y.Q/O~ {zǶϗ|F}% rcghLX/cS13c1auK N0?f|!<xoT1S>} \`#w{>^z{y޶ ;ڏn]9~YZX?B_?'#B2w_CXF?DMt?~Pb|Ż%~O/O=T|5z#\_Fc12õyߟ?C5xk/iD|},8Xc|kxZĿF|{{{'x*ijqsWKs2ϰpv5~븮빾ܦ[+pܶq{Ϻ ^ ]be.w+]vݞwo;}p>ۺ/;tG}u܉uwÝ/UvS׸uwt7-wqw=w=p#=qO3m{h4&Ψ;2zh0JW | Vp8bÆJXAbG~}=sB'dِlȅ0@04h G!A 0&Kt45L sa,pf\+]KsW:pn] `Sxs/5˅z} C!,Y JX kheluΟ|n+lP ;6a/C%TC-þE%4֟9;>xd,*}-J;߶}n3$>^>sdaL}[&ۡj7ݐG>_ _LjHS~P~Ø?ԟ3[ѵ_[[sݟu}?'_oWo;-k >ۯ ~ڷrVͬY aݗR~3-}#?`y^M=sPy_}٥ASK~[%tW^uҶSDe59A=ZSSΏZy CzdvBF@4:TZ'u/L'ZISڊmЎ^^ޛ{Ю>>닾꛾kO?4 ]A ˺E] -֒iY+Z՚u_zx lZaoCh( A\d` 0a0 S0 30krN Ρmun Ѓ,B[eXUX"llC v` V*ԠЀc.HP0,pq?8Cx 8IiY1` _ ߱<."p qWq-"q7ppKe`kX7>JMDkRB"br$Pr4B4LMtHM eh/8MP&i-fhhNZԦ %^]GwC7tKwtOh^c@tZniViH&i6-Ӗei6b.Q*TF5>5l[)٣ƳZi۶Mڼ}[;JT(wR )kn= gt|M!> d-K׎Odc"exq?qIFLum[ۊ O Q>3>7LT-n[O\p/_[v~FDm~_<#~~{y_K'-[;h-.[e^2y׬"oos;2;fUEW:smc;:;1˹7݀vukQ7\ͻ.n¥ݤrnͺ97NL3w]˵\]tWݸ[w݃G݋{uo܇Gܢ+%슼VݚEѭ ܶ+kjϕ]ⷝUWu5Ww%d6[ 6K6AXE${%#2(2"eR--ҔQG/#ȁ|I_eB2ǓB<%{4%4mG5eFfeNDNL%mKY+IiԬ܊]r/vLWI~/E^ެ=~X)- !yY9Y,ɲȪ{YQ֭ ǛV-ޖĎZIY*>TQٗ>7>JBsvM ٵ9%e=ٶH$$mލ$p2|'{?739B18i&|e_uFbristol-0.60.11/bitmaps/knobs/slidergreen.xpm.gz0000755000175000017500000000270311233572001016500 000000000000008Hslidergreen.xpmRI ƀAL`\$p9c81g_EԁVk9;9]9Z͕cݭq|yHSt H~$hV~nairPgaP< n?`އ~u6{S3rd.⟁#Qp(?Ck/?I9 $88qi$[^;"pET?oy,Z.?B~8GVOzb_!n ?ʱWrf\ yp(m@V-kV_z]߰ߦFS Dc]#1I@y:0EE9׹ ?ǦwПXN9qfпs?F@KeJ_z('M^'ZSNʅr9yK}Wu#xpŁ?NgZ޴B//Ewqiχ4HCYNM3az|gbbt-Ġ]%Gb4LOin'H{(Q,PQNwZ5kӆئLE۴#k˴{Ot(vDtBt&RWr!}w GTQM ,=RVR ws[zG}O<}7⛣WbF^<4#Jý=ƓGys?5/#^IO{ |?CcN8sYx'ĠΫ=^ lyGl>#>;;S>s_ٙډ__ };wA;o6+Zy/P{3 bristol-0.60.11/bitmaps/knobs/sliderblackr.xpm.gz0000755000175000017500000000320011233572001016627 000000000000008Hsliderblackr.xpmEiWK ?_EMh]UpVTpW o)%[$=NesquyC;[4EG{G[;7gk4Os|JߛsZ9=;It\ إwҾu<ӐFvi[9!x ,'Îgm;x *~\:2虈g֋5ޟH5ޯtzSONϛUv=o|m{[@ØkMm\_Lx*)w}E|x*UX#~륺>W-p6Ctrg\4{AVezg02E9 4`8'+8Ϫ=~^Ao&׉ry矂Z_g&s7@Xs~z.}/BN_Ͽy_s}op)>'~?B@OWxXnzRqzVoqoGW/+\_ ysǕoAL%99A \^\Do=-{ID>Ϫ՛a~|k1? gY >1wvKto 8KXjd@\y!gzO|Y`G@~Qo'qW!:#KM:7rB~e"h>wFmտf$ƻyCa;-?m^6y|yrUVE \EΕ묪+O΅J4~ }e=7ˡ޶^nc}aX*Fk A^\3|U_e`_h=}euh7G  XCYOo1^@JQ\*N_E:^<4ױRĿa/?~{z,?ؿ~\Y?7k-{1%*πozF}U|z=>g߳U;rAf|c@~8O`/TN >X=xb)oX}3}/x-;_ϛ6}q=SB4B4Fbc<͈i4Z4M$?zg>mzHkt+Fɑތr*UTS-ڦڥ=L_逾ҡzNNӅz/;]] ԣ> do!-zJhV9DK/kzCoU@Iĝ1'#o~k|˿<s.J6o*b;{>+1)7> W|v?'n󢥖=%~O/ [[z/^k~oտQnJt^NPɈh2'S|2% trv{Lxbristol-0.60.11/bitmaps/knobs/knob4.xpm.gz0000755000175000017500000002301111233572001015205 000000000000008!Iknob4.xpm]i[9|W(/Ҍw;q汍m&CI$O &d#,~NIR/ff/TG_?|~_}uŧWc5?RCTU쩍X,,*Z {~iȃr\cyrS., W*R]nr^r<"j!kZVv{ՕZ%W xEז;"/kE'"i;ڜAvDܬUj^5Y޵rܠ#,D7%_%׻}W1r[~%˵N}=rE"U:WIY\!7uMs}e~|"7:{kW={Z틼RDԫRwzEwh_/^3#{>ځ]:x;u{;y@!MG$O~]ٞ_>'vl7=Oϙ_ >~t<&rG{|(6OG54M׊+R :"zjOW~\>Þ~Cg>k",?.+6 gÞ#xm*LSsޤ!o\3B~!rd϶>o"W|wkAÜ\iKS?:1ףGisJ!whXlZ~U7'rk-W~o^.ɈkSrG2?TO~U9=*UQ" bx_TGG+T?]k~ ^wDnvdmzkmC[lko D.v5:?#|gۧ/!wlgdۣ'9#{^xo ^Ƕ>? Q_k>l_A/VO؁>_m}{j![(ϭE_vL9?(їj []<;ޗ juxbvP_dw^"?L-mk߆WϦsE~5E>vj]Mw[-\DB?, O$czl_p}5._ S.{¯~/W*cE.3Ce:[G$G|FB%[hwݲ"W.?1x$6,^;Gg[3Qp]hG5mWD^VD+s}:׻4xuk]ԧ(rj$ .пjmJ{d{5mH}V oZaMWJ+hȵ >WJR}@ǃO>?3S!_k+7ٟ:w{|C1" `][t'r-r@F{*A0`^\MT%G%||l I%oZ;uZ;[)潣k=)YJCG5MN#m/ BLfjyK;|om{a^*D,3 TVRެU},ⳀZm-bIkA+^Osڸ{[O01002.:G'<cNs4Ӷ$e*\`W 7N;|E#?-oi@3H~!y$9 XWs , 87HxByOYvB B5qv>ڂgE<`B Yfx̆4.Ìe@hv00GiZ"{d.D3e<Hy O>dnnj Kx9nދe&M"#1'alfEPd~&9<笜o`Kn:K, /qA%ko).`^;9@|76<0~u_5?HFJnd˂K2g?2-○Sk죐Q9O B 7-*Y/ICD:7"rn"kZ1?C!f.l}bvyQYOgM =u@Ă|Qry"ʦ%bYEG&}A \;8:RMUWԵz@ԪS ]&&7՞Foaw{U~fZE#+!m@/kW55$>P[JJ>?'Vmm! Hɕ8hO?:Uϳ[kt\]C[zש B {6 op f-iji4X#MՉZ+![ T&QoJW6V6& ׎ath /y>ƒ3€@0ȑww~J^o̓c$qBZ֝nĎz0 ?c%F[" -m"gpg >ZE&ݎK3V/ ^gdeU#w#zEt< 7#'vc*93<QL;fxe7;bPI3hZ@Ezc൉Рo PA8sImxcARvr"}\Q.T8qn-t+Jn1XȎ(c`J gm'UuOV ^Ʌnvzqmaix/*ۺ FQ'O(>A08c==Bm/Ģ+ D,x\woA YE1́- .P0!Y \/> F~p vH:$ āEv'z^= :K)j."9je"i ,'h_5pfKA|"ҾuBS3}78Ap:WLȬBhl\4866‹BPgW/_q &l*}N[ =IeP8gF i->S]OvN`l-B⒰`DZ= #lUx 0!) lk5Q6J`)x`7bD{^q!~gAN]GڧpY=l*|ە]bHQp j2pX#Y= 3},ouskhz:О9S-p@BBMj{ / $Gr`#gU ~cޗ`SϊB[#Cr\9|@^]} (ayMo`mcoXxC hL{,6YoԇGbX0ᗹŃiQaɇ#,X4V `.5 \pF],}K!1Q|^] D? &dLfw=Uj- ҇b/B Ʀ^oIΩ x7 G@!|!^=jEw k1ps e/{s (|#,X0ByŠM[v%oM8B<(=07 5ZYL9 P3Ň#ܘ#iW1 9^Nj?6ۈ@_v7zؚ}W{eT$<.p 7fّ\y(!A@e4s X 7r&tlVwo6cGl D s^W,t+PLFqa6&${ Dc>l0`K\&o*/2x5d8:nظqm0G~GIwֿʛfq;B/H KoDw/? Hȕv"a1(c_1a0rF |J'z|%>;A EQvҚ*̄t&+#`C@l#!>< ^SB(&.3̜{9S< |F#^,IZgQzmKY !GͮaupEtM3FaE QU# S&TպzA| }B8O`s㐴=DaS 32,$=+b(Š~wz -<Ћz@Hڮ)f;oS'p>"4gE_0kG٬!w`e'5~-`P0h ž9ūKٮ l`uJΖ6UE }Cؿmyn~BzܛNrE6+99\uRAvZ&wC?!px@ϣ wdG! O/bCS򜌱.Yw@@gQgJbn t߇ơAޏ}X@!ƒbJEz9&M5OsoO/>x{F_Ig.S$j|!*O,x/(VOl.$c;9iwR7wNwJG  @S۰\C`PA|uˊPz`˰âRǦ$ZC3SʆKd;E*˪9=p i7w9LZ= Q8p8/9a q@=`.9y`S@3T+ kDZ"x B?1ƹ|i9w?qmE4GuW__ѿ\J`NB؞{hw}$,R6紃@uU3m_s,otobFAОM3^QdX3vbs01`fY`9WN}KyL{B|oS)s DFHgVTx;K/}3ͳ7*l #csQ< y}*)\"3_#?5@n#YG‚-g-8>e3f{k\lΛHW:XE4Q䱑u=99czs1AF' x)AS({eN\ǠߕBwƏS34+fapGi+ʕޥ0qjp71Z[p< 2 Ni#s~|w(UpZV@p [x.ܗ1WasƱ xO+xx&2rph< p/q~jO!'L2᲎m-qdrupo>IAG^K`*-㓗?>+w' ΁H^sSx`6,Hz d|oD%w8Zkdd#`}ž~l>sR\yu39zri(b>N wxk<||D= 1ҳ0 .+o\b,YZd; ǕAhߪ9m[, :[-9-iE!k`9)E䏖 _|ٳ->,}?Xwv^ kj[H,ZV-k-DE2_KfLd(3P . B* MwJS3nYb n-YIc='̕2ń"X5>jӬ[4|Z4[;HXxڇ7S7P.OWY91>mb적\[g:`;/Icw433~ߖ[lvd_8Ü ^t"3ϕ81;WM3X.kƘ2ؾ5#zZ|i@,!1u8P)^_GX}fA@Všw~*:Ca y6pbhgfp4/gړ仐Ly!8@DXCVxYFOsW˘R,e31>CVHx`kt~nt4ҟ%gAV ;8LjfV>gbMwl8r|Šc&帹Sړ<<}z|=(mav1gZ^ַ 0JfەYpdގe翯yjhD!#YLYXfÀ}MjС䴝fL4dK<2FvL-semкnIϓٝҞ7rKxp 6KDonĬ|m7v0 2mc䅮hv*iֺgYATxnrGE?˅F!Vɪ+pv u=Rarh|W5[X !BG\˪|W+^iTѯ4+f@&\9q!^x+bX*(A.Gd{)bqkGIg[]U=ň`Sygǟk`:~$Dr6Ku[&M1ȶ +şͼx^{)ul8 Yq&$KątlZG̏Gdh$)3e~wɼBָ_l>~c^hYos4Ltgix~$A;z8ґ#j?%9|;<|#g!Mʼnusa9oQ{K>߳woqo4F$F'ޑ5#lgwWv[%o-㿧E{FۉE{[k1?ˋxdhkٿ* )2~f&nvlft#!XL9y&nk+>JS=Y l$n ;2ۖIKsj{rvm@K6I}rdZdv.e[O?MZt:WZEvO&f zo nEQ1 -DONC^= Oܧ3ƵxzGLJ-IW{?*g i ,bA7-7Ex$M{m oF`?/-rz {Bܑl&LMi}"D~]Wdp4x3/͡\>gy+eg^A>eݙhcwoI@~`sL'mQkܮؓxhT_8n`A[8k9_eGi0> pą3X`fƑNѯ$g}{De{jwSsoބqwfиygZcu>%;u0k~Z G?/ʎ,=bristol-0.60.11/bitmaps/knobs/sliderArpGreen.xpm.gz0000755000175000017500000000747511233572001017116 000000000000008HsliderArpGreen.xpmXgW9bD&&& 4}^n۳3hlsQIᄄ' )7֗ڎ9ܺR}w\]T6/N{(P{JkG}~~e d ~W"`qKxC I!្>#>{O#®/  >;"E/!? "~NTD ![%o gGpFxW fC۳&~GB 2) #'0.~X u)|W?ׂVaJG ?0s]ܿv;e:]}q&؟VC" Jx(?<|!iw,{:'?/8f3%ﲬg_*/ $~)C]'l/-vExd= w!v!*|8C >~;?mSς#‡8 a_ }(!Z_y_cx낙ߓ+x. TׇFQG}A|l-62o= zy@Gn?~5l#X0=q*}&b=y(gyc=xA\rw8)f.Ww,wRqqWĹWr4_ȋr^Hi0OIԷBCzt>ULP5N8w=BE8lCq%*"v`y/O)>z!~?-27#8%<+8!<'8&h>C3vX a(TOÁLIHs yӥsJs\"oZK|VV!|'Uh{Z@y_Ykbπi>4e~!ie> Կ点rJ??&C 7$A3I8(8, )A>Gp|4σD'Yǐs$/1|~#0vOD|-"܇Q~?W9k1I}Ӕx?w]z+K|yX&{wH(#}п0~fo9šUT]OWjƨWݪWg1ՠQjH5uOw̸S T"UPȡAU{j_CO̤<Ա:Q?p.`mYR]kE~s lIyxVݩ{U=D2TU@[υ} Pe 1WU5aLNorL,5`L,GIM25 ? !s95"%eT.Wt,VԪ< XX \V5Fv_mY9IfFPŃ0+tgޛ3l2}' j䵛~mza腟#V31btu 6 3d>!_0[ uĬzc<#EIJ9 3 9&l,Hm0XRж heqlp (5'9 i3]gþ9Y+s$<.ab̡#slN1t \΀| 1j,}issa.ͷ5w|`ṋ3+IMd&瑙*0A,1.2%EXba13nk/V+Lf;da̘Y3<>b 7 V2 YEePN\bŬqh尧M84#rPJ_O>Yp:o q k Pjq *њ¡W4KYͬCp@+ȡ07lBDD%qñs0蜸y;P=q~~fFg#3N5?д _ƃ,vߞxaMg:ƑC3&98yA1y5fiß:,:3ĸ~SDt3W\7br cF}X^jQHя lfJ}n͉ʋ樥Na,ڋ8EKU.1S^œK3{CF|03}E]q~j CdA!XJSC~ OP4unB'1g$ɣkʽS7wl'wOM꣤h36;A=A'Z̼z(O7#KP_mo7mx1A$Z/XYotWFW{w}ʎkcػoucp0 / r6ꋾ던^qӊA5@V~?5~/u%lͶQê7qw7QY/\=O̝߳a=BeU{-V2k!?wߤ{w_U汀zX' _2{7|ĂށvyL} 11#/B@A'ɂ!(#I~7*uX7&_Q֩&/^I㊇vQ:ܶ0+Q2*:6Gs>6H04UyzB7y z']kڗɝW#;'ehAO鏚AȆ?i=gp1^KzYU cUC[ҥRQޫs7w%2bristol-0.60.11/bitmaps/knobs/sliderpointL.xpm.gz0000755000175000017500000000077411233572001016653 000000000000008HsliderpointL.xpmMo0_'4@ %m$P* ikI@A۽?߇+Q/B%xOB_oǗV,y00Z ƃt___~o2F!\2a7 =B`unԄ>kטPI1.o]F焦 ӄUF*fd@+}CFD{ǡtYAر6әϮ^]-cscaI&oy$Kh"X[&gm6kNcˡ`R6V[-78y^\EJ@\&̛"/Φ͌{uO-#:n,c_X8]8mQrQ7Fݲ?H)QˣR"]'qYn\WgKYNJ+? : 0a7DZ0ٻx g e6~u}SA Ў$i;O/Zbristol-0.60.11/bitmaps/knobs/slider1.xpm.gz0000755000175000017500000000032111233572001015532 000000000000008Hslider1.xpmRU*.I,LVHH,RR(LI-2(ȍUUR23Q!C%.%dT[V6W55qAW5Wu2AQj@f( F5cP! 3K1|,i}41Gf c3H r5͠p֚ Dgbristol-0.60.11/bitmaps/knobs/sliderblack5.xpm.gz0000755000175000017500000000111511233572001016535 000000000000008Hsliderblack5.xpmn@%YE.6_DEdRI^& O>( @t%CbCq}erP%R*҂r}$ރ]m= %Q+<4>M'Mn!=h$݄j+)ihC@O>H#MQ(F"~G>1 14/gd>ۧƠDSD^Hrn4&J-m yz@k|5Yiml Uʝ݌nU[" sOh7g'jU2.OjM}xvs!D?Gsa< ϼ(,Wu=;Q>?^OXU1bristol-0.60.11/bitmaps/knobs/slidergreen7_2.xpm.gz0000755000175000017500000000166011233572001017011 000000000000008Hslidergreen7_2.xpm[O*IǟO1(63*ľnqrQAQ>clN؇M^f~UUU}VMzx>Iԝ'd1pwXg5}n%dwH"H$?K$HQDEGi)XzYjiLZfzDfo mV\ c1AS" y-})E_EUy:pibristol-0.60.11/bitmaps/knobs/sliderblack7_1.xpm.gz0000755000175000017500000000211111233572001016754 00000000000000UHsliderblack7_1.xpmk7[[?ׯxJĖCn[(J)HQTUwg35߬,3 qo#00h.;\?nw Twsx c$IY'c6n2' s /˳>)/zL^$)yЧ5B^>JzY#%y}V }\*7 }~$k\]k\}b@p*:/,el0ҩwD`]3g 64E]өL5 ڢ~?tĐ 'Vd`[ԀX6 vE{!EVKzHN D x kTyK u5Mv>ir7Y>ZQ/>WM EMv iA_tXX`,Cp_4 VDT9MH ,c$x"ZOE ֯ngQ ~=KNڋ-WHėc{ڋw kk ~N4#n\L F>{˚fmVO4vvrMv\/\ǶF3ӺlwWWNi6|V˻o~kY Buv0K9a0ٽG~a>&AikoZxq8~i~OQ'zF]uCTT*~*z~P*RGGTU=?=c<;qMk6Z=Z\\C?t|?_;;>^- bristol-0.60.11/bitmaps/knobs/sliderArpBlue.xpm.gz0000755000175000017500000001104711233572001016733 000000000000008HsliderArpBlue.xpmXkWI+ih]z<Dh@hFFdt33{Ξ]ɑZU7n܈ʑ!ܜC#]^m]숝vi<;|~&o(/~]숹]Tq?kq'qfp qE܇w(( GF~:b'=?7xKO '-xK9W=^v zw}?#~W׿0 =_nNzqh=i o0GCz2\q8@=\^1vLg8%!#ƞ08fz|BuciPQ>m~Xxq?|z^c{gNd\Q>- '_ȿnjs W8ߩA#Dg|9,x/x2%yeyuozD|&{n!B.d[+Ӟ?>2'#[[ZzTaO2B5mM"qJxqbc ;a~k# 3B>[4"B=-zi[z8+ơ_0c+/l)>AakWF3.#׈}uh ;_(4X<18=c;81q<ƍY NKPpelaHX D48~-'"~یm;K}>j~a c$G' o;d܈1Gs~.S/u铸1sfC|.|g2AE~Xߒ358ASC7zg :ku ןc:ߚgW.Lb ދqE.Y)V/>!wv83So'?nx:`HߌBZ즨KQf:q}i~iO+e15._aƶ^JWG>y{θȰޞ12426>k}~ec%}rx}T4*ߟ;{#c@]a\Կ-xhp> G$C>1d8z%9o0 xY~ݵ;>x俏}'=$=lPOo~xQX' )"+3 qTPؿ UY[ {I'%MgyY/|MyøʩF|! ˑ߭+us2g߂q%U/?w :8j$%׈zM^yfy//Ko\8ބޟd 7exaؿ)[fC n^Nl_Կoi mb/-nƫnWO8c|u{?|N|C8Ψ WԿ ǥW!?-qXb8¡7ϟ흶UeumVTUX#*/ɟcUqt8?Y>z}/2!ܥgQQ?C*'Զ%omOJt|'v2pv-%mwoOFߥRop&h}G3QCÿGW"> ?eTgzi?C~s&oǬz&%S:}8vPV/~}뉃߲vɡXsg(?*^yDw֗P{mg<սw|^4C؃s#Gy_t֤]A|C|BCnJ~[|xK%qDw/0~W!-S?u|etBr:/ܴ3EBW5{Fapwͮgϋk5Ǟ!]>/Y%|ȿ0~f_~q5'E] q1,^x%^\<_ŝXqX#bPlQ1&VEGp= WxpE$b7r;{Pcq"N8g\\2i#Kq%'q/s,|"3(E%&Ĥx-Ĵ1+<9&#M $ފw{ 4a=o)RJ* T?Rj1Hx^\UWx2 F!ۇSkj]AFaUՁq*LSȌQÇX*Pwy|CaabuP[j[jƞaC`s<nj8V'3%q,NwX|\]T"B :ՕS>/V*S*T*5&k5Lj@Nh5fԬ:WOsS+u2נ@_PZRo;^-ZQP@^cr3y0^!IQWu9$KJ|&¸&1"WdZ5$^`>0&W*P̊!з#rp}Wzҗ e$cȆܒrxlr+ isX{ܗr8pD !Ё:;VGXSy&a\ȶWZ~7"oe*3xA_sgqe(QJ&z:NrcZY9'eS. \5Z*WW Go#orYV,P#}JA%!6\ơ_a e1,q ;C %L8px0'2q!^)zsA,2SFMun3U3;=hp(.qNуzƨӫhv4cn6L48[.(P!ƙz_O³1۶Kp8tFDz4aoZQwPy)d% Q0J(!tGoA66!눇MLC*a\SPi.pE![SK #Π>ٕA[gβ,zW=A:0>>Pr(Wne\  ?vGrCIG:'=tu*Lc6~.pT{`4;]U-T ,Z:Xԫ[Lu:z?xOܫCX`6ƗdyoLpd~'wtw'NI`%0bx@}! 1o 0: v %me^2f=a,Rd B.f tTf{SOl>Fɻr_|Prnx€pM}UVק7}kr&~} 돕: F5"aUݵyçS(ln}u۰ouixlê<[I YW(ꘅ|}uV8k}Rfg?Y/9O;_]O,vAcFYه[cxKofT%L6Ʈm2f #UPP3& 4z& Yfd:F rf{,ԩ} q{Ы!(?I݅>_=0!ªf)߇g &F雏XP#F ãjc=r@#T1.u{4ө *T_?COjbJVDiC x>w+s|Gx'^kS#A<:л. ڳi{:x̹ܔ~j9zFx:0\:HUIRyԔ|#mWYA/7zo;^/^ѷM!j&kVk?pn/8pퟐ$8bristol-0.60.11/bitmaps/knobs/sliderblack6.xpm.gz0000755000175000017500000000104111233572001016534 000000000000008Hsliderblack6.xpmrPu TDٵegdM0M&ɢ3F_LHfs2p+_>TQi^?(x6_-/D9:4^؝a|O?8lV3Y S`WhTlz't䌠'D(M`$`ʮEP݀@lùG$s ! \{MT.M0^3nvNT4f4͢(us;iv=H(Ih֓fb5.(JL9Z-S-yGڴ,y9$?Lo$C+_o|j[m3X۪^onz_.oV_c bristol-0.60.11/bitmaps/knobs/extend.xpm.gz0000755000175000017500000000021611233572001015461 000000000000008Hextend.xpmRU*.I,LVHH,RRH(IK(ȍUUR24S"SC%.%dT[V64W50q@$0qA\CsІeeQ1j7gÿbristol-0.60.11/bitmaps/knobs/knobrednew.xpm.gz0000755000175000017500000002466711233572001016350 000000000000008Hknobrednew.xpm]{8_!Jq$m Lnfe 2yf:uz P@]-vZ8;I#{~} ?͍Ny:3ks<q>qpbm{NML;Mt:&n}o7fɋXjV ףV?p"_zZ1֯qRq}X(j~Q;FmQQ{q=( ʰ=ׇ8b}h;a}VDkPjG6֯p=jw$g6z;Xq;iw{zi;kS7o]ۣ6qvVݦMt:'w:qw^'^N֡uׇq^1ջQ%-iG@?OY;J[>շ\?ŭQCqèsY%_ߍz,swN|4/>'T 4/>R_Rk~|;Oo!-owi{`3n'vO@c\#¯8nuCoQm_6Sv> ?sR(tSR=t?v܍i<1~Ǡq4^hp{hWGE"yvnDŽCacX 76O >:':ܽA7ދӘW>Hc7zgķ5/:o n/6';[@|o~2`~?oCW,23cC6ZHy@l2}dA< ]cx ~ y?'Xs>.kNw1ށ/h<neܿkt,8:#g;c;xo^Qc|.snt c^G`|՟p)ԟ>%|D̿|j{b:G?>ɿ;sDUn3-x E]~_cnK{׶W|Ƌ#I?R?D !~GS3q} |$y~:AgADxLDޯ|}7Qp{]𨤿;?0r?E?~޸G)ސ o`@\]zoztk\wJ#\O30m!`}Gt҇->S=_W7Ə$qBj/+\Oуe xbjwn/Noxɟ'Ixmp X&>HF ƒz4QPι>N[ /zJ O4NI]R?z&)z/MS$R/m4>a:N{\gS=@} Y7ށp=Βw^fԿ#Y?#̹>FgtgV^Ϲ{}gI\}їvoC'}x%k}Tt[{p{H G^a\#Gǭg{w$8C1oDod;ۦ뷹>m+~,?Pj;e͆9L$&C-¿ivͧؿ0`CDS̹Y~νς5a҇ iS݅2 ʫ_ |wnWc_Q_Ш*`g*y .ȿbYq 37W<s~!rr_×cp1n(w~XP ~UfUKi BĀ2$uKpx{XbA Ϸ>RE&`:0@ Hi['> tck\eTm<@:WR 2abvзoAe} X-} ^-7.n 6Я-M1`Tme)g:[U:a5l PuVpɞiĞĶi`YE̅ )JJ "Xe}$z$z4!;A[Tbn*rDu9V*.Gr H 7v:Rf0=zF~.(S/4ൄҠ4F,bAʸ2mhAqk.0@OEB6Pգҟ9ȅ( zs0. yY4j_8FDІυU8\jZ@YwW9ɾ,{JHu&8<'.Ī^.jb C15C []6IM9? FP47fE\ᡢ<1 |.@-a\HDg#}RY' ߆2b+|.rAFLŽYmH\ s";;pg731xߝ}ZJvԳMPh\FD7F+Q3"Z9v̔f9NYNgj6A1POy!.€EUlḢOcJ ]ob,=H+(X x>59EU H91`}4(0w.dA&}Cw}`ZGVv nz0rlſwC,~nA3ڃCh) 3Ŷ,K&_~0`KrLТs=_{.9v|(0 B!.Yz,4~`6s`U@QxkLsGÀ1],lCMKj3ln5bTV 0,pW"4 g!VM{dk"xi6e6{^1^YVas%(􄷻1rweD.c3Cl#`#p-gEUI6謳%,z}XAu{`Vd'.zd@FoȜU؃1ZPk\;-Nd7B.L5J)$b Vdž Nᾊf p8n|1{PZb[; rh! E{֔,p8mX{]Y1,X%QHA}YH_V-1avKV%[aF}qF~NR.drPEaஒ,H_ Z]ߥ#Bk}f4(D$qJ^ tT$x jn\dcM߹(x6W\XRmAz<)5Q'!!qH倮J,L>: U?\uP\Xw&YhpOwIOm„C–Cf_0C[Q^VsΝwF :ݾ=TYqj'qVgGxC88O^ӿ3bCυU '3ɆÄz.<3-2DCsP8kJڏm%ǀ?O:Y#dcW0!%{تrr@0BШ␋f ~-mfa@QpmBk c4̡u7Z,ìv=-!_0`q8/.DY+H`;{0.bk~5 | mgv/̩iH}*꾕TkN{!3Vwa/hsj)^5gYkzHDse 8 Q̸d9!B*-!3b41$$9ێeeS?Qa'20' DWhlo4O3-A#*5L` \ٹՅDB3aG?72k/C~gZ;(p_bK =g6K`N.ި``a&p|'pK#`*ۀeJ^2 IjCC`cb#"Z}6 -f!5, uMr1,AɝN)6%])>WBcīg)ȁC0ܡ w$|f3s2u4oG$BRN,> |LQ ֮EPϠ!zr@Bs zRp@$ >E>2rѵ58+o+,QSgaa77aDK$τ2#=*. bœ9[$v\DO0/"%`.Q?xXtN3wdKί-r`r &[:ڄzT#c.j-b^E>z`FsØ=L?@xG#BC;(s,@y*/y|]A ;e5R1HdqVsihWtʃ€#cF38E a<"x7q lvW\N<&Ӫ7dVqs~`*ZE{b"е? űd7;Z!X=&DşOst \8hQ؆AsM;<L(Vk8H )D+?=,{Q`,Q5'ooI~$ ;w}\xNR}^%ˈڀ}(lxv0~0+7N|᜼o5W\HO^!zfˁ.'TX  (Nq1|(AA.%c.~ˏc5^滶gNl'YI) LHyisD,>1'KPXCSd An0*< L*LZ,P xmuyXnW<[d gdp^\ viQ|. Z`¬DlJ̼pr8%7켴hS|& :VPmSa@鷀FQx`L>1˰(& n:Ofh鎿ݙGzX6` ܇,9WȖa,p@_,3[103#^qAW#JFѐ U &U1hNlJH(&ܢY!귕>)01` n w<܌ ă}nYڐ.?Y*G5%kْY;24ƠVb.aД2ߕ-#|4A0C pxOdtH+:zR>nw6?(iǙCO0Xݮ*C x=}n w`+DO <@xC d']} 8=TsaX{ޡFgvŮ)%ktv'D]"0@&<4 fױ,.@A]# ?_  )J#f"!3G`^D!&.=P" ྐྵE3@D?u|3ޡ" 8'<8 NK~!+t 6-;sy`#п! vuEw@;!BeB76{VrM /Y%`$ր#3iE|QgElRiAaT fsd-b]+ ex)`L0" walhB\ . V̀NR,)~3.q‚rSN+2Yc+"e;’pl}g=>Ը:pJ{8,xg / X<0{+B+rB˾w̋sәY19q!*4ynCVx͇u-`oCLP6/ToxC҄=B`,ûY<:9i&iΚ:|2 B/,{Db&XmP}xlH1+^,=v`F@g<GGk M%)W;ohecஷ:9z"PEAAwEU״zo` )gN{Ɩ}C3='-X Y0!8Yӡp]:ov4Q\4>b`";,?ߢyи2\"źs%eAO"̊F 0mG~3Ê3(6>=@^?P[xO(Mt|ُrf}֧^$+̄EMNODIٳ pPm|LYB8p8GG_XXϭ\YE*)mFϤ ]} 0(< #uĂeg pTԃ_%Xß+Bi#ZH2F̽M-l R G5CKrʄcᯩ5Љil Q!2c"ԁ*`#`cĜ>j;-;U9An5&2PX` =_x ,Gw_P/IQ96fBv@@ 17e{h2k4p3:̫ni]"0މ3W0b[!g9*Wၲ?|/{N0 i?Љ7Sc+Syz]u>F0夠+v>vu<(vTYr m`ӛSd&b;cCbFs'ZD 0>YwU_O( >)]{ZUR;K[h&{ߪzZ8ύ-kznHw3Cq>iXF/ֈ>:P_ 2+;y? C5=Y8g kaǵ^Fs1HJWN<}X֬6 0s.s.npwZ-2bf&ȁY%~Xpp%a$ka/ͷ.3'n1A؛8vU8@DaDHϹµ nٯĆvŞGӮbb̥nJl.Ϫ6j2C.'\;sa_(zDR sCȀX{޺bn 3j. Ħz]y_]Krm[3`t@| _X;VzW€}]*ڃIe<.h >)a/V"<ԉ?B w% ߑw{|+8t8U%+aUK`Y珉xF},>gWш=={ (S ۆ%WQÌ`H~,"_c7H* tU%2cY> j?(r@+6cX f} OYO5gD= yҼ4va~͂?8g sč5l8p2#q,u:ҁ3lAyFkVOUqTYP=;ècC\òxdpӍ ixM1GH9{\y)OX({|"i'fK8f}BTHsHǕ~)2ĮA%)4os^kQAOVQ_,t΃ S߼ ݋cw%ŝ+lR 4kK|D :N%걗v%?M;ϬU蓀rآl~!0rZ1ȝYI"k4=4u=7'!z.}dB,g"XkOf_?A2sO'Up1H^ڕUJ}4s䁬O{Şpקrky򄻺.zPo ʝ][AYTZaWf̋'6y4ЧaI$l8yTfļn?sHGZ$4׷%f-gj }(nܦ,YC٪idT=+`1FhHN/$11nNc-1H!.Zswva),m8y;~$p;ٓO>b9k.I6?cZ…tN j<ՖgˣqA bA'8=t+vtQ{owrf.OO kXeH!YYuv}uGj4,f0 |[S+s g]F͋(GܣWbZLj|"F2 46/\TSVŀ#Ћ97 EjRWr* v{:}z80ni5֧۔s 2#t Z.kvӍkVi{Ʌq b-|f؋'?{bW^QpnOThz OUq^0ȍ}T1FZF U84BD`^gv+9 WZuO=u$<ѯ  zؐo\v5?۾_V?S"z+i3E1e¯`*?vTT5[ c=uF}b'=\\4KvaWj?Q*kgLhrKYB܀\}`$]L\-1EpG D!+j`T\zaG퀏z)Z~}е E}T@ԃYHt hCp,jzW1MMg$E }'}m.<%X5nMP/#xͺXw!xSmN<+k>B?HR+m/߉_o|X_ߛϿ-rQVGWtkHd'*tFvbh0[NpI'Z,ޯgz4 nJesR 'nfhLl;\~$`rx{7Urٌr]2zL^4Ch:vQ<{l>u{ =6ke10O?(+t0Y[/Um<\}1XuaկC{'e)oѠ,eη*ke}Gڻ\-?9(d9?_֟C}8=ȏWX]kU߄ᰬzϨw eKOqYi(/`<8~?88!7ʝ9\,G>rQBY ,r)ڻ9}ןo]xh8*ߢG٪8c5v?=&n|G`!n\~}ߟOϞ?qsi?y +0b /`4:~?ڛx|8)NF?a|w \{/h |?[c8hWQAO>'C7x;ޥAǣ#1=(}w /㶫$s \Nx~c8_ aOPO ;E AW ۧQs8~2tpAB`gGy~ Pl?A =W D] I!@׭I{3쯠g>tހ㏊ٷc l/|z{ݟ(߼ ;9l?L_^ ۋo,φξ{Пe_g߬ڿ}Ϗ/a{!`KoMCп|]_8ԇP3ǏճE6\FTw폡~-aO&#sdP_ep8kx~kWuw]}A/y#*43{>By>Cb<?~{> ?)Zp пṁb0;Wo?ȷ%/P8ǟ /?"v_>@ai'}A{^^[?M]>t|{ǧhx?#~0p5Qn'~ȧ;ψ8x~A7[^OB~z^8Dƚ^QJ(-ﱶ{K'u j9{3 siKۼȫ~ QvX{`HZk[emƂN*AY=JEۅRc/xE8O֢//#Bo P2(qUs6 `9@9\RVЦ~ߌ1]g9E8tquǶu`|ُCA+"a^icw+`F(r8#.ZHпGB]˼¹0 Q^hi۞E?cQb.y~ȁu\m'a?gc =伱Dޯ5`>+5  ΁Ճr(MH1'?W\cǡi1 ,:d8A<:@,hUsKGBlO՚xD|!,P tԋm![~ԅW'΋84-T\Ԃâp#8\ʞRf:- 1ຯd9@KS2s\5o{fVYV|yYl=FRyU\9C+ b|:f`&ʨR~6.)Lu~Q_ͷ8#rCG/c5~df]1t|[~eVX'QgIu; 8 R<yX WsCɵ{QtP¹a\gBgȜ;F f=G0(q^9/m$W Qh-2w\'oHm~QWk2[Mh&X on({F4gnf CΔaT1`SkZBPFhJ~ H@\y0+ؕ t5;^/ԭs?baSĔgHݐ>bc2_Bt v:7 sTٿ,XG4G`Ql82˝ dԮ,"Gج 6)$HKVE|!ĂVx@hw*ú:Ÿmkk@h=W 8gcϕ}AZGs|,l}c<(y=c'Gػ[Eo8k!g耙Sߌ%Hk?ć~Tkx(HN-8@Gp]9 R5>vq& ttH͝u1L+18+';3!Ńa¢m>Jx8_C]V1uJgWlE@^Rmf? >~t XΠJ$B1eF9N,2 \1~^ Gb-?#*9?tL)í9RG _oJ.YqhH *L\hoE!sbZ0XW^s < ?>0x@J<سzn>mq61/p $0Ft K)=BC1!DAp#9햵2SihqqbMxSw+ׁsõ cpJ#&2f|mkAnz3! p^e $SzC̓}ïj)f`39(~]2aR5N f`a͎E2 v +xȫs5Q96 Y"z-%/$oW5VwAdQh&f4~1МKW 6wc[i/*\[o˂#˯k*vhSוĤOޕr`lOQM7vްL@GBk=r{0oJ o Px`2fyGFA WG L๑T3Vmlf|[:6rnB @\hL^u sBsg:$3%/oضmL H➀Y\X,ޫ c'^?sםc,kL<54G f} gryXng]f=M&h x(7 3A3upJyW<$&<. bG-q>x֕*Y\b!'V*8 4.\(uz{ ÀiNíJ,,Ol yq[ uj4aBaBj6n~CmhGjoG,U 6+j :O iZޯf@1 'ߧF>Bl # s(ݧ+sfXol Cc= (x< I#ClOE0GBRbَAb99sS_ @.S˨@uyf̱\ENJ}&"\Vd@?4}G=8~jf~*řk9)]ʟ6{:Ll==̎8Қ9e{m*_/M#}"YC~zf:pf% {T@?O.Oق|"JW(K{l1s1Wf,f_ؕUHGHr9 ʲ'ZӦDj^)3"Z(ǾkqZ#^B4.DV/u0+|`oZ:ҧji&ğZOG,whq˯Ҋ n$ZLweom3ۥFng/^φkCO3ѾGն0b s1E 5q~&A%dv;-diXj|;^+>/|<0M ַk7:葖|J$5Iۤqt<딞3jk1[BE[/">P:bȁ=+PtXt$mr%ioIH`,֪8)5u4fe:ބx͉0 ߡ ":}52ykRXKiv {Jr? -uev'whr7 Vl(mA=t*kkYJ+h4.6_{b C8'm83&j3e_eQN *a)'fdW-N} hW;5:o7VߒJخ2?h{jhYͫ~<|*&bristol-0.60.11/bitmaps/knobs/modwheel.xpm.gz0000755000175000017500000000731511233572001016005 00000000000000VHmodwheel.xpmXnˮ}+-[a:)5=AV-APV9}ar-t lcrX s046lo^ߟ$ky,xE[^<~r/?~cE\rDQDu$8 7coCq;~4bWKŅ'_>8'R#Ug3-mW'ɷ]oTxOq+aW?r&?!?T&FC=|OD}|8Qbixl7zސx^(N_}[RUF폼x|ӈRם,-RѿWN"?(nz|TpPA Vm5Wcq7x<)UC' ɧ !Y]<# S՟ [&/)3ߢ"2sO[t'}USK[.| 8$˂Y;Şﶞu2Ǐ'O?/qrgu" d|Jy"Z[j`-S_3w{'-8cߐG$#d?㊫@v&ŧzxPqW=_F[p~+\8gTכ?o5+xCGaE>jϋf׳`^U$+n_:#/Ue} o2>7sCoIֿU"zmfonZa{ػKǕ^g3^_~5&{ǡcY? 40zo|xꧣuFV_my[?]ZB弫_Z2NRɗ[~k.?x[H~ڍG~yyV+pOGqNjww)O'{:o?Z_?j%nȏ|8k!c;x-)տm/z^+䂿Y~-\w۟ۋCq&T ȯ6lh~T^Q1 N"fl:{~N׻Ŀ<}}au'9Rq'?D3'Ϳh:56{sۼIp^c篆u{XS"6 OCk_h`~yh,Y\!h,A6_hgC".$>ڟ";!^`~aF/u$o*Σl)nFHڑk'"V^>FG_V?TJoOs[?? 5˲lrޅ[ƥR[RsioGS[/gƐyN{1h#~ϡhW+[h[xV")ӥgZE! i͆|1:~Ryr9GW?}}AqU|YEp_wS͞a9P}?gl~ym Y' AꫩPON0s];g|o{g5~s_-]r'L*BqqgK4>8ˏD߰z|{Ġ3{t=kO? O[0gSnM퓁TT꿁RX?#g_5VX^_o7"m"Xo_ˋfۋ>"mcUϢfSq(rB㵣wدk;wY??rS;r֯Z:?e_/o9+s7/KKgXFUؿR|::oJN3;LߧBǀeŻ?>CO~S!LȇDA/20 R0= O k,0*``BtV!Rh@9PTOIn l6.og9`!(kppr. Ftn 5Z]y}iYLG|y9љX7e?{ "j?⨗k$9wyK=2-M~d>x>Vi( 7uZ1;& )R (Bt`o_REmmqvvEh~Etr߼ OXt#|:3: Kⓜn葚TSrhGctil)йDung}l$}9h-YZϢ} Xv'b6l=;@{{Iq(5BЏCϤ'\+gDg}8|> zCMڳ/ %g1?O4F[j`cuј 5ΎC8 wTam|g]ߨ:>}sds%X>&#YgR q2Fl6qn=|@z.qp=qgč;ϰe^2X^C`t1yow\=^]N:=7d]f,g`&ӹn·مgX'sC4,,:+.Y^܋rw}swN嚅k3{왠sM>!{x[{9fO:O{=ܳ_칶ˮwt[Ͻo+/?.oo\\O\{coZ^?{^o=l{/νvt{{c@jHUz@H5/գ{moJJUC:Vi=ґJ#*}@TmHTz@zcҙz1.)]#n"GOHT\s`z Q˟H_<;C~6pg c!ׁėp (1ߡ>Q up[ >: JFok7ڍ~4Կe +-NA+cmYIÜaPSm5 :Uh`B_ !0rL)ox upah \j !Qc`\ae[5|Apt>2:ƊEw#ֵ~AA.bļkI_hpᚚ:qىkN=pbNvÁ]%) U `6|*V"Cz!אf'$5"t %9|G<Ѷl2wM0418}#y拥?iC7O_5薸h>=}R CY$c /qV~Xe0V ʬKd؆J֮@_ǭg헔|jDZ E>5OoLd8Dbristol-0.60.11/bitmaps/knobs/knoborange.xpm.gz0000755000175000017500000001362711233572001016331 000000000000008Hknoborange.xpm[]oHv} P,2K$ǰ)==o nlXdwCS[{%-ĺs?ۿ;_}ӟ_sܼ|FӻOw}O_^7ϏN?r,??iӏt'o=~~|}z:Ar㏏'9໏ǟN?>́&|t;x~:[9}|~<$鍜:UN?ENx{BF|O nWI[8wOroNhӏ|:}ӫwO0QN?߿{=R{Ƈ<}ĥϟ?&Ou1:$|EN9YeH1b};C$ 4bUubXAdܿkho7n~aHhPҕNW 8.y$)"A>/ T0ӵ_}VM'*Dv5L G6dHWLbQX2s4}ItA"dErt:v,à4t# t"I!Y!&Gh!`3CĠDQۣ%Jĭ *j~QK2@@jqQ2ƒ;hRz-Z ?ly "W=/ޠ^~AǃeJMW 6bפ69Z߻'$TcDC UAzn;jLV öWwo0#䈵b(sm0eGFPZsۮx R(5 #FR9 ߰oZ1Fr;]=Br"D|4]岻|xhc *^QQPh'/ICB.1 ZU~KpՁW!R뗯}9yq(> 9@~ d=u.aP+%N#/L.%g׆.>f.M 7q(?X$<'}L"ʔFi+wfȐT))SuΘ1('/gA8BQd:.9Ai3t۸iLhï_,c"LAD %*U}HDN}DJC^)a dXy\WI8O&Td(MYvQn{`/~X?=Ch2o7-UMS2 /2Hmp|ɻ!vPTE o\>1 $)_ࡊ8҄ _ oa{,~L+N ;t&s)iXd3DýA(Ws?s$@(~G=O~ׄQ|T*GiMPִLˮ҃ ']ٯ"AMHa,w{,@_.4v8# KyF4r_'eeZ`Y  e+q kCGesܳY$ An%6QIP"dTn&!5@8ƽ<˘^'7AV ͶaX哹R,S!qp qree*mTC*n)1 OnRSI2$وAa38(xp-ZK"0B1ǼBS$ݭ+ D:yM׵^o2|'1,aت03X5=Z}UPZM%D!/13!Boظ5ӂPoh SwʞFL$H#u`xffLlB3CtՖzI(bHj08kӂ5Om\"!I&B"G f^m v]>!hyqKTgPD|M *pe2|ҙJ!ю\ ;H&&p!]_¢U,Gz"$Q~@!EǼZRz :"_FX-hQ 1'ZmӠ^b%3m҃/ aA |'SC?gH"Oa *2Kd1g&ȡ&(>"ÄJ!nRF-zWl0x1􅺧R࣬$D`1 : 8CA?S_񏤗:Z]G3ted"BZ7-$ ?JjJD ZWupI\HҵaȔ7(ȼl0+=F3"hh=R Re1=iDEKa8 ~L2k9F8DFu <- c" GJ (αUdKf系g`a\G~*p[| !YDO!5n1欮gb*H\`@((.QĞoAD˘ ؽ~/'t@F@1 &(CbfL:]L;H}1.5GYm!큶@#'h!q=@`ݥUF\!uh $7[w~/:KQCrdefKi4Rq"2ڴE[W Ĵkc>VS ??Yuk "CJn BD- 3.0v?*LvH :vߣ֜,Vx(ƥC T%`ēD[`_HiCg1 =6n=J'IbʄCVd&ozb*,T[xL&t: gQڢ3&|rJc\Vf# Ҥȹ sa>d`)IIÜKr5ڄyJ+YcOmɫ%eV]m c[ȡ: js.q2`O,9=h&Ž6RQ4y ``sϻ fmrP<IQv:"'7ckAD3N_v&+c"Ċc  d҃" jFEZ%XJP{M %ܣM!(rS$Hwl- fuUS09XuirQu+z6os\:ȓ$kmUw뼿kOI28gbf%<!'!G7#/rCLv]M3f~$dUOY`YrD;*.TCW 3zacH64Xѧm DE+:1E5hs.ӝ -PXtafCfoeR&V}Zeq}8LIf+JKD.ZpzK[i)=.: Z>[kE[ZEٙ_زk}k }HѳSMWOt* E׆4 ad^%n9 w$E5;{aF QA6$G|KY̯')2xR\6>s1c8^Ai =i{]-b1]` ]EF59%q A6x8̓HeVC^ekۥ҃aQ>0+ m.61m`R*Y$e olfU )-4,:]amyk+%dHf륲qqB|plf8 9Vb(Zk#&LR ^)̒'x 2V`yN'9eYT;ds*e{^V b4 pHŖ$/:ޫ,Op0D? 6 IlBQ SaG]uxH|nowu$fʟ ,1iawh,W@pQa6 DBmP})p80H0igDE&PM0HWl1*O7x+Rm$]$h(JTp 'eN+ӈmG0b"#4Zִϊ·8ETbU&Ԛ_:vVPOMp @tܜa|˴E[=Tn!dmRX(}Lxl<'1ҁ48PPdkˢY9S8k#;R00SsC`rDXkޖ]I@2r P;5j󃊑 D AV/1ŃNdŶUXPO5z+X3TAjiMZԨrE#:Kp㣮ZOaO=$JnH`*1泛=5A2\VNp'˻I5:ۛMֆ Ζ9<4X d$ޕz9<61nbۺ©pNB`4S ?ZOTpK2y.0F9h-ӴL,jGzcw%m%D7:eTZFVP6H8ճ&=S}-'@bh`<:ېV΍7`؂dVo9JU'^Am {o2\?|w{.Dbristol-0.60.11/bitmaps/knobs/sliderbrown.xpm.gz0000755000175000017500000000033711233572001016530 000000000000008Hsliderbrown.xpmRU*.I,LVHH,RR(LI-2(ȍUUR23Q"SC%.%dT[V65AWĵ00BM20BWM60B^  m p  {3f1f㇂%LGf N 3K18,f 05cԌQ36D0 P .jxbristol-0.60.11/bitmaps/knobs/knob.xpm.gz0000755000175000017500000001015211233572001015123 000000000000008Hknob.xpm[Kܶ^׿b&$TƱc pv-,PEjhQ4), )(lqR.`C"B}WRȆ90NV"/"Tdk[] j[C `I#yJO3}0dLŀz`AKDUBaSBLi?^(چw Y#Tι@'TtmSFׇ(&_ Zx.p@IbDݱ>6⑌*MCUn6nv-y(6QQ-D ;#YbAn7&΍>[I`ؠ`HWB;qKQC&]@i x |(ۡj(F zQHDblb<6oX1IPyY0hEyIFI;P`;%*H&>W7iL L/ BY0'шmD8Lx@ |@d<'(`V%I mO0v,c ҰRrcC%W|\T6 K xH⦒ ?nQkDȃU <QWK 'L(?Y²Z!D6S5eA@_IJB^z at~ Յ +R1!i" "V#(.B+ˣHMN14fXQތ`4,i^1sT|.U, #Q.XSبX JX/ӪcA Y5Jf2` xRkǧkCdf;ưԷ}8XLfQ7N1@'=fQ1F$*iX& 1 XF;JV TT9#b<3E" VN[`eFGxŁvgD L/A<ԑhԃh64IT 9 1)_wzfԵ! ΉQ4ᇾ}Da0AGg8l! gG_퓖iBDy 0P aА @.zab0Z\ERf)?р` ˎ>X%'"KXe $uBڀ*bl D1 L"IE1<`6+ ^*k? It<4Ud'}&sG]_T &-lX'DGuHha$zSl]70T I0p;6a=@_K% 航 23>G7. pBDNM>e9Ŭf3)!)$<$9[ΦĒtx)P.)n ~ 2f~ijʆ:j;211I&{)Wgp~ &)_E+ B4>!%6Hr:ԾOwjvN8눡ܙZ k(LEYS}k3,%Z{1c~BQcqenWsm( ^q`}EMm6*}fBA@Eamcnu#80ns4GM `Ia5Q""C4nGy1`VNO#_,'Vj 9OyVΧOhђϝ+si{E}=g #T%]XA0 %RX'YN*(0p-(Z/,XXRѵIfH!l䯦1-Z:1- 70봃Iݞ%UR2@)ᡢL?9Fİ!Jj ,ÍՇS񸞃*e!7]!F٧i+ !gZ m`d1 0*KZAFgtL[ }-%s$,5(Lۇ-$^2 ]`KP45Y,iMIЙh4ÄJ XW@i UNguu{]wVImT6:ISHt ^d03*Z=JۚBvk ֫S16+nqp-$`.wmIA&ݶrρ*z8\`yPՊ1Pڤ-EIC|bHUq]2hA7XtwYj,G@^N~8"j7yZC)h1pϚѸl 1y` <_w]7XT1'"k{hB<< zh`"" Mcu取\t1I2mgG3If3!1wJq/0a2¬xz IAea{Z|,.R :Z@X'-fzh7 x0/d@? ҽaEG{πUWh.u:15v:;4+;/Hש1XI`YJtNjw2M '.xG\ݖ$Pb$0e,ZE6vyu \hŌ ˍ Ed1c?j g" 1:sLvF) L"5.ڽkR-C.9j=_'Qi!FIOgU skn. u&(%lO-V4i= YIeizp:Ne(A !.LWZ*]vgِŸTRWy$ljH|].8CTp :~&Ÿ,b۪Pgv0AJ!yI!]z>MDD7˧E.m6{,ݗgel~z=@)z-r6(c!rKq/c~X>sG| ۸|d~QdjL-ec|q}& 귩%]~./0FOs#Iľos)_ [?}_z:O)'P<[E>=7v"q^7*c\zr`l"?t?26߳\֏qb\? dgeeƟqSwW72&[NٱvZD"Aβ?Cb{I/I<> dۮJAT#I슽\~gTq~?HJSc{?O #g+z*Jo7Nbg9IJ2xPOnx:/*SwS]c}\71~vIK:kX/H_ G';ǎ d3tN-_zEC=:o'67WFxh[?ÁG;r}2e+[Xs޲;ȗn.o/I|q+D=sxQR|_\|{y?#%kw_Bԟǰ/ x+6~i#=sC~?I޶9$§*/ߌȼ_@S^6}w;_~1@ [{se,B"Rx y:A}X7(e]ׁ7 u.Y(S7o/ 1C?zX> P븞a?0˦m6#qIU1\7d`]"pVf΍fm Z!Y0sbSPd'̏.̖A,L8&!XS+kن,/eåAM`lFh|8xFٿA(55;0iD$WDlf1\D0Z28HMfWq{dW<<{xttL4bx)u;^M!Wo2aX(vͩ3MLc'( G?fፁ}6kmacňѻ % 8!U>dzeN#0|f0@badyx !M ?ᓉanjiL2zcNh<5A^0 4rql&C'}c:^B5342Xg49d⡆`qx8"NE?BA'';wΈHrWs`d4GB6` B[O.XeG+k䝄͉!8پ A=l#g`폚&WmyS϶.j/Kt*}]sVz؜ы*zj6g|=ggm/gzs[c}6Ã뉳6;V&x., ׅRw~`TWb(>ћ虯0dәD}+9'>QWwA@qC6#7g8rvbTrqU=yq&0 (82W͸-s{* 6 v-)dڝMmw9mU0,cݢݢ;3j SObÇ"rf8*t_F㛏?Fo~}w<]~QsDX2]Z+ :_LfBӅ|ZS(ZE((;kQrӤ@eL*RZtB %GgElBEYB1R{}:\pҀPהY1MU(w;EuT1]pØ4oroB8<><>o /M*] ׮ d_ĵ_% ȒPE?%uA{c.);iP9ȒYCkI3Kc2c@3ֺRZ^Β':IY]uH\3R&ofam DzA{h(]9! tY5#ffFzB>-_- $.H9<Z[gGp(/3-Orʳaoy zz:- ߋiy.]d/ޱ>3.DOcp-y5_Пc}-e_/wAO(o6=._U}u~۲w=2O/\4;ϐo9}B9ISܤe_.1i򮲘=p|`ԁ̯~}K6z z_=c2~S<˕OY)L?w*SUEiL*piKo^0=n_o8\$:U'E~աGI*^ϯ \z] Ʃ=R>XӻxKn8~ z^k׍Uk^.Y-zHJEy[CXx.e?w5K܏JEYM̠!p6>qWdz~;?S"p;8/ُ~?Ķ~~`?#;8 65~ީp*Jk;d| e7OW=v=;S?l3IOOZ6%}ȉCO,vӗTrYHhore ʪI2A =yׁ_՟ zӤ3O^vmUl|`'s`xa8 O NގOhJkVa4[>9gVS%{P߃Ʃ?WX*RZ9߄MP/dWvw֯ λf{z=П.?{9O17a8k_`߁3*Wf?ayWǿ~%};[]W^W tq?? } >o}GSBGVEV/棰R}̯п:~ܴ{'Skzf"8v'}5`yϡ)yaQˬN34G4FXbCv>ӴSڦg6޲Yvb<%j6\TQLGt@E_HMNܲtEtC?'[?TKC u%zԧZҲ$hKb wJkbM6$>'!bv JL,O $cw[6xΛ|/{SƫK+wy=I)9_%#^5)oy~MUr /%צj [w*xT} ȟxGU1"uS5 G#h4FSL4MFcx~Nbristol-0.60.11/bitmaps/knobs/knobhollownew.xpm.gz0000755000175000017500000000532611233572001017071 000000000000008Hknobhollownew.xpmy[F~)nYM'Xai'Mn 5M?{\Lc[D>N4f~h<,+s3ZcwC6vN׎w.j[/oKࡗ̉K>-ɇO<߆ն(F(t'=:+9:# :stT?Щ.ѩ_Щtz1Hڻ'( QepRCy }h2.Lj.C9;Si4ص9g0"gr.r)W`Wk DJU4Jٞ"TO 2pxVP&e,chuƷ Rh eB&eʧ :P6"bֹĺ2kgƷ`vr1HClOc¹}~PG;0`#b?Ȃ,v;? uVτcẈ#(}h zn WϣĤ|;y7u)lvǚp*K`j;fN!39ÎA Ep4/zo{i1>\AV t;^P 5m|Vqk3¤4'д%I‘@/ƜϬRJsPtAl heU(`Dbv <3Ϣם Ӂ SGLI'2H5Y8gX}SHwU1:cZJl~X˲3jH3v#2xL7md2* }+_"}ޔ5Ø. ٹlvS # )alY9}\/Jl֔cY>-#3ՆSqf >};jl `a|18R>T6Jwq?H! &ΞvbUSQߘgak:Hy:Jڈa9YDOl4ڃa'+.}a5t \ b` bÀ;b1ZA]rpW.ٰe}:k,=$aG>0kqٿkM{?b1x3 b0n S31^ ~ ҵ^`^䍬I%tif^rLS{ٍ'r!a'KۗqYb P!D)!5LjYLE3/`f7^$w'dyJvog@K yjga;͙3[!(ZV f3\oƳݭٜi4nf忆j`ʬsf 3mik7KgoN\Hc0ͺ%Im㕩 ]WFS{fūox SQR y3٬s$Qive`pa0k}Śxf .y?Ⱥ9d׬|Oγhv}Z p?39fP&A5;p_Utm(ɸ_`C.vnm~g;)]k?>os؉#L__[ʹ ]eA{9ŮOQ`ࡴn[/h.v v /h`Ĭvf_p 07E y[/€- SVn R g3S_Wlfd +~w\?)ܽ}y L}eŃe"bristol-0.60.11/bitmaps/knobs/sliderwhite.xpm.gz0000755000175000017500000000032711233572001016520 000000000000008Hsliderwhite.xpmRU*.I,LVHH,RR(LI-2(ȍUUR23Q!C%.%dT[V65AW57AM4AWMWu2AQj@f( F5cP! 3K1|,i}41Gf c3H r5͠p֚ bristol-0.60.11/bitmaps/knobs/knob1.xpm.gz0000755000175000017500000002023411233572001015206 000000000000008Hknob1.xpm[yWO.B\Ŵ.qqDd "- 2}{rv*4 뽷{WRI>''Px?=)mqcI,/6E,}ٙ(ɿ+G׿%1ҠV8+q-w2v2dw1|=X~a5Bn?8ɂF,LRqGnƓ?k b~!/O<:AT<9 q%IiqQixYR ux z}2^aoF#p8z/C5/ \sܟf 1mZh%EN w#oOOԴϋ?C! {>"|&zE4B{5 bq%az8 $|q흸&KE4;?)ǟ|F^ra7wc?f>>_JX(OF<8B27p!7c?NOs \$(/ 8ؾ1Q-rC 5"#S'+2^q(o1yCPcza_EB/d=v;Aߌҭ9>ٯrǟN ?Tէק¿#'vx<|zx3y9Y^>Bw_La;pOCEhy}c'klo nrB|Rό,aM{ KJ7kbm|9ެ `?,#ƛW{1{U Vx]{V/~p87 >}ml!y 0z1q3`;~nZŒ_hT1nT_VyIg#oȃ^T? >zD֞W*īӄ20ߕ3&T=s+gXџ]Q$yz3[>Na|z>##n?DXس'_|-^|=1kƳ|-+^:cu[6ƷlE/ӄoK}3h8>^!ƳY|Z?'0cg $ q7`/1cg2:=| :  {r||ΘeD<4%M|wCΗ^>^K!76+77:<#ަaꈇx]҂pFN9~ so oA#cxHz >JE}8<2Do7(b pL Q >>ֱ? +uĻ y=paާ90Ox~ڇ0~Fwkt9σ,b/Ct|1TxRq"džG|I*~L>R΂]|r٬_X->yV0> \cJg-K|l; I1^)8|lN[x ߸;qWO My,->J)͌?nX^#Uv RR.,][碯vQƟ@^G11(F)=W\9`}/-! Z3`CsGHX' eo_m1*D9va9wlgǥq2ߢDoyh'zf"0![;#J,Bs zӪ+}<@3!z}asE+e]lgmR мQ/ZGse!hAe5ٵ)s>;-:*6j1#V=O.tmB<#{Ǣxny aj]* X~Jj}N`7`I1E6k˟bZly_Fe.Q1L0[+F{\(guk{SO,YA|B)%U]uRӣ՘TQĸ4QA; ̳#|kvS*z \jq3VISgkb0ql5>`4iG UtpG,+Oy]N9<+I\֩5o鿺we>#F@l\05b$񠕆8zfvˁրBU>+`#wGd$^},lUfbC+ Z$tTD 0!KZ@8_01`EO翦_V+}dbO2ʶh]ÚZWjSAS4+"ΡC XR.PscrGKBk/YsRjG=E}UMMSF߾ҕ=١[ S6|RVDHH AW(Am5WuF:R?cL媠ӷSض>mh6|* D?aLM1}pW* lY $ VۿIW쐍 U͏ՄzgTҷ QMZ(e{@23NeṚdxG,tdtԙf`cU[ͧh#].tI>^iRRotejJj~^Ż#?&oSo+ު'4~;p.k`̓( lPԪM#gdzf}+3TQw?qPw >1^YI#j@{ # )Ҁuo.IKv/ 1CWd|Lq.WBLn 3lp?-΁ }"FX2sƥf`@\vWKb~V^Hvs*X jѸ22Eʢi8U-r)d\iՉ02r@b]{My9Dv9Le=+%fS<&?RBk¤OiU[-~&{(>ӹ3*1>t٧7'_3y*JOT<Е39E{NY/' 2Ypxā$XJ_ #GE{Nɘ|>5HkY.e*KԨZDƃf8sb:'N M3> sUd@D+L/֣U&ܔ[r6}ۢ+TF-VKI:Ņ9%t|qap~?!;b?ѱa`8ؕ{*oTWG5wR4qj_Ni}F.q?C:g$Cf7XH+@O'qˊ<`w98bU=8@F NH J:cxLkSl+Xޢ#g6 o;|1hb1wum!9! ?Z9~e_Lcw鿏2F)L9:A_ '&5?lo*j c ,WuhSňjS~p y;8Tfd'qL^Ak/xrxrouS{]St]0HQq>X_RUD#hnwƷ۫|w<=JsGK:hg'}Ab6?w(Kng4hIs'I-?]SZCcpMWakK- 5AԿ}t\PQX!9M8aPx%9S8Miԡ<d'2P :Ixp(D~xL=RoYT1߰& g<3c7uniye-q4Bsds oR34;VʼnŠ.ўA +,P Թ^|5<ïnz92(#?̃%Za&emߍRjU5"ex{&GmUnͳoz@dÆ%\b>. fמ FrvGK0gLWumUf)>X1\BEt@7(]ӭI>ほp -ҺyBl Y M*vW%f>kxT z ^jXseH:tyǚ G„mf0ijvĮBg}A6 LFϮ"'mj̭`B#۪[`tpiߛh?ɉ][? PƺY=jXtzwg9c^2WVb& : d-$O @`Z|7cCYӰ~g}|ld0w]M>1-l.}2eҙlwcK Yi>&̺P[c||\ Vn}jw;Ԣ]7sK6ӝ]wȅY9Y4>tv0zquU>ߴ\p H"G"*вhyf5fH3IVF7XRZ`%z{֧+l0gs.]] .,D,v7 g=|1Y(NMs:0+'~3.us_1ȹ /=ĜGF!\ w ;XoVyf|0DLo,Pl*?#DHͳ馇V'JWe0\LXe<p T?:> Tᄃl΍'(Ku%{2KluTztɸ?,1szӴ4ͳM|c6|'z,X}4#0ϺcπfZvg6lYDQ(ZXܴ̚H('\>=xmhP,Ƽ 鮳c1d}a4a[{FM:g4wߵB H mh\>w³/H1pP>?DNib866T-ӐڇgXhA>uboZR kW+x,A+;%Vql-0`+QDZ5nX}Fxj]<˳c3%l:ǫY,y0sLfbSʙ֤8wd6{>i=LF|Y.hT x>ˍ>ᾶpKFFmڐ{87 8H:j]xQ%*⦬u$! Q4jӹu#/̹& #Ω"LؑzU^K0s]_M7LOUg$1siI? #b״^)V3!t>?;Nee,(gh&<' |Dr*?{m%_ 4Qc&M>ЈHcXo/wzXp%|;~go#4,3; tB:K]9#3o32OϷޝ<1'YqaRtԿD$ vsͰb޺}*t// A̗bristol-0.60.11/bitmaps/knobs/knob9.xpm.gz0000755000175000017500000001454011233572001015221 00000000000000UHknob9.xpm\i[ίE %}QA`FP6}AiU[5;/ăVUVɈYY5;M/izS/ߎewݦ9h,C$(~'ѷ(,h?Nh%Eϩ裪'r x2M/$KɼdQiS8_ۛKJ\ |$S;sST2Hl"˦D2=l%ݘ=D>V=]IW2YѷUϗ gGb-j^?iz-*~^Iz(_:=3<*hRzP._W*Ѳiz(GD^)U 6~1˕qKR& (%M$)'eFi>^ʖt3~h{YT<,'K|-Moxd%kfĬ)M =IO$t,U{h}5=MSOl<" ď触DD?3=!"y~<)y6=Ϥֿ|,|gn?DŽ_0=""zK~1=lzRDjzADy+"/_ihNj"/Eї Ok{g՞u{;?-")_%_.}OazADzٛM? (of Qeo;^Qf!SaBu1Dxo";c;:(*>?%DM/(["ߦC*[*"ߦkߦEُڿˁ(O:T^`|2z/k$mMo#"foAD[uk=~Gϔ?ǃ埌)lo^Q#"vd罵WQf_cg+(GQv>+ޟJg'=`/_CioGw0~߱'%>?`< |fn*J}YCwV3z`"_ƣT(򷵯SV{sZWa?F?D>ϔBpEОE;~>h{v?M?)=2ڳRT}ί[ƴ7u߿BNWD]oOQɹ`|v}JDq5!);p_sgƮ/(;oscHu??#AoﮝSڟmWZ(ΏǴ/=q~>NjH yzh_|dY~>)uuꁴ,Q#Eo?]}F9KjhZ4EZ?;~u0:_M~ϧf^% 7JV9??^VORϿ ηzk?Uo}IA R{eՍc{U_ciygko!?OkQ_Q^/ _[N2/WLG51vA~U/muw6[s~ΪwNjo@3/H? >- g>뭞fեzΙj󹜟/oGsxZ>U|s~s~(iL[{8(8d9y`<d?{`5mB&6ғ3,_*?#`0 CO<0 D ( b 0|~==n|`~b=8@?HC`c ؜n |0͓-~Fx(P>)'D=  ΨĠF_鐾N$bQ/7.??A~@E*Q*Tyʒm @/ bq~o >П\ +zMk{6`TQl0X'ҿD#-|װ^m`X'F?20,\I.3p.?oŘ_ۦ` (~c|Lq>O;//$8`PIA8wq} ~qVK!͙0| X^"`0fkI //w=o.oP >Sjްv8D'ޞBgQ'^̉v*W7 :OCa,|  n[DDy} hFu j矂 -wbIx}P <V7Dqb` ̼~y>XTۼaٳ>k֑B qe⡐s@g7sbX}8 /d9 ^jON>\PU!aA("Qdw8c`>*~183fG2#R1C !arTK! >P I=hB0ύB=;ڙo%2<|qz9e?9/4sB)fIE$7tBܺXb`"mѨ 6 e!UO 5]~#cn6tn :G4~XPm*2ATA 3WWc]+F!k~LieqʊOrC ]@;HL.,& X>P7rOez`Ν!rr /{D^4Vd7`]zB/%@T#O[bDsHЍcEXֲwn6 **ӤfεL\a}zMgv1qW Sn\t,99R >6>w?*62<9!cP} od[}(Wz <>bf@]K/X҈› o_~;H` 'S ]-vG#֎;ܷ~ F7 |JiբEDb0,Zt</WMnP# "o-a>Dw{ $QJneF n"Fyx:5n1tޮk`?Mdy7^# b/@z+<94 vݜ>덢y VN:g7w_7oP ΁%w'vO{W}XpOD[yYWRɒiW]1`dhuKPuTi{Y7=I{M7PVvhl*q"|1pOEP;#*=x)E!w77=fr00pMMC&74G?V f0:w) Ozel,A,!rbL^sMaʒVHg$skeq⮻y`4 XnLz{3s9g-W׆HRƆA{u2^mJL4qbh̺YG.oΨUNjuFEca|8xݽa^UZcdaz@ڼuǚE:'y`xsgYC=#,Y+ɽcH95 #+ ǧSo;@*r/(:[#i^ZSPaPVˆ!qF+v&MfkYgQ}hz=G(u]@ޓgA$3~~9A)xhXI 19p]{pں?4,ߴN.8~16wFkﰼ+dm"!&D?oП;˳]Dhu5 4`w`ތyxqe)E mxfq3#t6c۝fθEz{0d/)m҅)ovo<0x~h fܴ{qZg۝(Ou/BZkE*nM uxyT#2w ߀ , nۍ+/yoy{{~>Mo])C?hE?+F ~XCO; 5qwB4&Ww{ݯɬaBFn߳}av7fЍ7$->w >t0}v90Y6nۭS]|;'Z';`{޻ϔ%zMl_ =USߔ5P1".i `؟.5{Bg]}XAm kO^;]N9}0lj'ݣԝJE y cvTû}^q YkEo\{_ @#Ox.lk+V C`Y`Q9ڛӏv:L deZxR;>D% N;c|ڳ ؎ ֈT}KU@wƠFgΟ^D_Lȴ2B{vhB?xd˙1`p5C@R7 VG+}_ް-Њy} -)o=.6EXX` >'ߜ٠  Q7""߄MqL_PƇ_a W:?7Y2BA]@xa /ݲ:; ̵s,+`pqo."kɓ}hN'ۭ[Qՠ|OP^跁A|q_ȷJG,llZ1q{_։Y!βRPv'}`TqUgGg,yu|W/X%>ַ2bJi„O'gSW/3|GFki.1~]98m M-C/C@&_;Z­/y?AO@5RE (Z $~.dN2_gg;OwTQ1yc7 ˊP{z̞ e$".A,U>lߝ &2^+dc.5"T^ݓ< #/{ߖ#_Ԝ^3c` 10c` 129xFbristol-0.60.11/bitmaps/knobs/sliderblack7_2.xpm.gz0000755000175000017500000000214511233572001016764 00000000000000UHsliderblack7_2.xpmݕRIEFYK%dhk  f B`Yb0۷;o!&=y]U]F}Wn%Fqu?;iw6xFGDEd?:Xއ/;GWۉµ]_~:/JJoYcYJnY,VlJrbeV,mJlGvlJ~rjgv˥c8+1d7p#Ͱ93pS%?b,7W8dlT$ˮ{˞x{)Dz9st3%c9O`ˡ'؞)rDYΜ܁z.27k{6y|I?ˉz˅~Or~}ifC^& OVn܆=g9 wYz{ g,a$BUyJyX,_?g>yoCE_Fv/A eȍ GAV߉F~_EAX0Xlȯ?xsa6yxƔR`Mȉ rY {Bάܟe[*9;rQVېKKܟyC& ͊ }AgǗX΢">Ic2'XoGQw<,MqH0'"ʡ,Aޒzp=˓2אS+SgYn .ϟbc|"{^ؿ!~PwS&|EߚmY.(b`h_CA]{ۚOwOb,?k,|]h+ȨO ?>ϴu8ε5_]9 7I^kkPFAn:|{lgSm/2#.;.f ^9۷9pBn?$56ϗ|봫|]H}|Η>5`LAN4H^cxZ_voό/R?!iӉh>5^X?X<-Sbߧ~691|pY<>"w#ǀ=+w<[g&"/|˟m);g9I _@j*ˀ%![31)dJiwY̠aO[iR}*xg,}$EI~,/rķgEBPUX&_X/ _tmZ6᱿ q2mni7O_d}4Mo7zwo.C oT;\Y q;By{^3?浽~CDeo1S!G~Js=19_syo1~!v7qmkFkS~y ϿyyÞiQf|lW7ޘ[f?yEY?wq>yCA#g/?o1&x"1'q1)'oJL1-fb@پ%nrlMh<߾P==20Gd{,,+ǎPSvr{Om~@׿V#~g`#w,w,< USH0"4O-x"_|Oe 68-xޮXͷ}͌QaO J??l1='xN9gߧskL RMۏCX{O9Ɯ>ދϗ)~ŀA+`;˗?&]Q%OF5v|ִ)|kA>'kUKv&N.3[tS/` ~)mOEF-G+ƲaDj,8jlDjk΀&OuDk QR[@{Z5U#i$ 'NG(.tŞT| xLjs{^h"ap`Fݖ#k P:gb``j}hg2|YP[mH3N|Q'#0*&:Y"~s>7r_j_QS/:ٚCj uÉ-Nc(26!uP#Қg߳ݯYi)p_wG{)L}RL`.4y?àf88+h+ ].Z3n,ifj iܾuvd2?`1CsabeKSX]l 7诮+. f{C>}_9YQhD]8F@E&r`ٿJB7aj-EMx+~BzĎ pc 5sxGBF5T^7\ď1Py0h ?ܗkj=?c!| KdZgzѰ4#z:~Ԏ NP#q7C'S<: tH_;G 뇛E8VK>!rޜ RPH,Qp84w+Hv# nhMZ/0XSTe=b5Vg쒮3dyk{@w*;̅.u wa碙>~:ʇ0>›M,ܸxb#9.]DUabCõȍ#;n0P\n,S\@UhCoyk0c=أwcwO[Q 13 L< @3`w(­x<F_?Ir4C \ST{ߺS:w7w̓ܤ΁35ž:6+gΊ>Ja}XgE g; \)e^ O\]HF .iꖼkzx uCjG8oA,8M!}v^8j'bKyJyt~Y0 h\¬oϦjr$u`BQmt5kc>`$4A 1m{qU:kdD#( vVhKs6.{# 8ӏ:;!008hS9g<7Ѩw ߿8mY/L4+J9my @XFa1ؒW#Xp\4cCܘ }Mi{2)ԙr[A~~ɸgvyr'lU:&˯bp<7] n3 7՝B\u@t񍻭:WVnӣx`wK ČIU)scJxk=+Z; M %GaЬ:2'{7 eOk͙$'g5lyߧZ$)\ՏBbD79NG`]WuM'3uc 3ގg*¥8`[pH"ݨ%}o6{)eBމw 9Q>4vW?wٿVl AϦw$!,&+v9^tL"k,Y}Ws;aw̃S̓nS7l*ngoacSӒrz0ybwTE |fxe@nމWЬP5Րz ^V73ʛuOWPi^⛵sj`$jN`BuG₃*UU7FЩPP0A>A9wjŮ>r-.,軔Q ɾ9`1Lj\7 ;k[AgfP7o`po.ໞ>6+V 84fu;9jhPK*跩*LQtPKV):ͨPl}VqaQW+Swl7 tᛮQw"КnbWZbR}y ?ȏ+!,ȯHKKR4d9BAsAgĠY4M;wL<+gʄ;V-k_ˣ*BSL~.ѧ+HXblwPjEee7p'o:b\6+ ׸׬;{uХ*H j7 p=ʿPi_=W4sgl^ijDm/ "å|;N(pnu)fG}{gs4~*El50h#μbu+0~PԣG<*_R[$} kbC&_u =bBjg¤>O,3#ʙqWvT1h 靉nTaH><>#7ȫ&^WE13Ek)8oZRu?sb >+J[;TAlxOt)2H+E WRo|Y% (; BAW(GǂsDi0a7* XmW1:NSপ'_E5MA㠞*& jJ8+ AZ  $baYȱC.q&+^L6}ht ЈA]4 B[|“⊻bGA+Huً"rI?_.kưd /# [CƬ [j##Pr^PMBCĕ W,BƝDWR_Gxo;nYy5 7`#B_jfLM+Y΁Q}X(. ׮A\gj~ , u^q>yD@ޒxCW}\l˟aWb,j%g2;7AXa$v3}*)ƶ`e V`B" P ^Oy] 9($G}&tx|=!)V)n?5ǚfN(Nڀd 'p/wl$@aV@> ܅gMaj4T0rfE81R:!:U|ǃԄz׉5~x%a?QXjNP`e(VǾ5U8:F EJ:J|13 B^GqG/sDuzKW۠_r!|<1-p-A`P6;u#{ȱc~3>,^3-^H0 "uA[mBv0bQ5 4R('pQ&E ,{uzg9v*I쾫*u+)T,#xo̦AL("oA?J#BxEVC B]<$yMܟ)4\-1%q̌R}"4CdaL;i=Q: e+W1 oFa50 wPr%8Je-ΠiodI-ǃ qJQwaP_} z-zI(xO:В#;ơ0aԴqpaئAEX5''q*E( #8^N [CI|tH;V\svh✦\@ >ezNhSSX=Q nVHcbĨ%?Sϩv 1lhPϚ1PZ4yEɔ+X㚸6X`"3Po q5.)w讖D]r % NhZ ĉ$ZzIƖpf~|{p&`I9Q/55lR[2߉% /6]<'^JxB߇YT@c(#19G͛'4v5__G13b&޿qYăMS&X[ě!8F)VЯN\ސi=%l$}gj&e"2F6:@ˢ q?m; ϗ} t"ؒA1'\(җj„XvaV$'e1.Xb_ :99%M\8"ݠ8gu =/Q̶dhȼ6\gԊn:};=t~w~DѲ9S0iUx,+ǃ=ByIA?[R1⟩$I~y=-{i욋=ۿs9!B|iؒ8QQX 2܍S7q[L~N#ĉZEܠJb|V z-'҃WP:׆Օeo⛰h|Ay\cU:V' "u>|3a2ǁӄ܊ׂ`*=zqcWfb(y%wCZpF2G^Y6jW=֤{itFW2qNotzRKe0դK\} ܍\?-`|Qb)5'>8y\׋lUT+ʄŸq %[=X" nƑ5+/>y0tSGM¶Q7[ds] YjC=kA |{ #1DH5dh:`0HZ"%U|E(CP5!>-< E,D+MN wTD Kx~V*[:KPw0GN& 0Мx hg:g=괢~a-aA"%SJ] 5xcpsY*B< ̢sH{H_XI0:IcS1?ezKTAqDWt6s ~؀3F3 g*"{5 p-sEp(GTKڴ:q[K5{ =qxMpW~&Rvh9]}V!Nf.A+hS <ŃpVлIXO.a%;'7<=sGpO&z!i9! ib! MӀx*>$'qgCO2n΍ߌJgX?" 5=s$}V<6xX_7>ZI`e~;o>:v\eK|E][e1J >~]ԐGёbX"vKaNE%yixŠk :V E?vjt_| zw#ĸ1x)BUEx(HO&DJcb†خd:k W6Pe?o8*ޥO۝'fWĎ{MQ\WTym$v֐_ 8xW^fAO d1„Tb8bq&5+' 9/M umu;m sM/n-ஐ]<)/O($V08v5,w43낳 4{xFq8L)j*^6 hUw=AF4?=*ȼפa\aը4>g^iݦ=ʅdQާZ]/^^WAwItԔO }wũaϲ goڐ0lD. O\?'گ{3 #_sS7xV؂kKZ{:M-۔˵gM:aq\eA ҌE\=ހԝ(|&xzJ:š.f̆-Q/-:CFրLՑY x6ZYVzEb*S us2}j$l]ڐӺ0`ݶiOHlMa&/*$ ǴC+-@CR Q6|/'971jG3Fv `MՆM/#ٺ8Dg4bp-{bpKGګĽwhnu?svp"_w~Oq+dwxlJ`pYB]cЕN|7G.7*tv2)e:?4ō&{݊TLsq3LAyJa0_NY8ZCUN>ظP"{}n¡LD3(=1PLD¨6:d9\&p9m9(3FxsY"}d7p7s€!!tpD뻡2f%d_$xLՐ|Z(|N T2gl PgǩCL^:gZq>_?sgdm|>+\/:Mq%'6GD|*P5 lrČS*mÕ:<p'., hk#)RÔe<=RؑhHV[bŭ޳YY)|I9+ړ}4=}L0,``X-'Zem:>7OzΡL6\-Z8"/fjt>r[oQʔ"բs²jK:iO; Na Qtc3IOܘɂ1ե4*;Ne^~8I2Ws9hw}~GĀQ*-eIEXF5xA|7&3kL,X ܙr`Hv0=[. Q!< ^ٝ8 7iPgw2@9*sl .^gf7tpXŎAyGl;|+3g-""x7M~0 (x >9s|7zR[N7v bbuerߏP\J“ Yf}>e.TBtV <. su~Q!kh]S94\?=`qNtMh[/BAF,ƹϊG) ʥ=C y_wgatO)7仟&X^u0 ._GUB*ѓ:7iRr(+shV4ԐG/oJDt|/5B]W',c6̪NrUTM%cY0_ AQ1y| 31xZSa}W֢(3m`loB_5(,?l]X1 <5@q8HV(b 븞Ejf,`6N [z¼,bdCcXD Czmx4:w[IhglEYߏ*C ^].~pWgDW .f{pSбb4C9 Cgów v6ƀ qwvµsV! W#`cZ?{oY=3^Pl]]0).yFaz#cSɲ:tD϶//TSo߸kK~yJ;JWhOoXUC9a%j5e/T(?זbristol-0.60.11/bitmaps/knobs/knob2.xpm.gz0000755000175000017500000001761611233572001015221 000000000000008Hknob2.xpm\iWɶ$0̬Xcacckj (߉}" S1 ĘX16Õïkbʾ;%1-~7خ'la~jzݮ׵,YM]G6}ciyHC,uhyz1z^< ٲek)˞UB-?cٱ\a9zg9l [iI1^,4s^YrbA%sneZF mcye톖!;uv-Oږ)n_,ڻec;zZXixgR簜R=ˁ;sq\-{60rN30sb/1~D< ׇ~89_3?Avmu1:uwf}د/\Q Yk6~n6B^ߖY/ofFÅI#;==kz>p2xFB>K kX;fsz1nxh?XN\캡1˖[}\d,{4#g,i.~b|4(!إy,tC imߏ wF1߆YOޡ_forbQ7y8C;^߸><6g{”&s ƃ><~QG,>c? 7ANx8#/Fܞ؝! Nބ4HRQeIOrw\-șƟYXg9ۡ¾~(M9^ aSc/qٟ8K/-CRgq|^~'_qQ3o!~X;0Qo7qo/H)|YI~^z"+xJ2I49kJ$MZџ"74 q=/[2I|z;Jr7IHO!gIlgI;(,z>zJ҈xnƋ7דXϟVڃOܿ)OrC 7x!ˬ'3-nOݹEIa~hg,FN=^ٯoe |eIn/M^o=K3ο3kfe7k|<F75|6RsMho^_S 9,0Yo쿹}BAmy;b\S̷繕?fY;4yh֓񎌽u}~r}g9a֛\ܠ{ GԬ!gh$Lq|x8ͮouZ}W-$הmc0X0+ΉYCmQ OAi7AA;xDF4?*<ro٦SP$vƁ0icC0 :?O̾gХ%rʲ>^)v LN-XǎKtt(^< Š`@iC>2e?%ͷG:k߫H}RjO۔MX$ m>Ԉw~tR߱{zM[jBbVm}@cid0TJ%' >:`6k=_V63wm1*O1@?QKb\LEK|KđMAbx >Ya(&*Ͼ콒/H{ﻤs@<I?kBAѵMSgF+ABsb|᠙~ҕ5Æ@ԀbgS~ ޿mJf9~ &0ub6#CX&FvѦ}P\M΃4@Jվkb iSIV͋Bbp8Pˆͥ 9T\ ́3A7OɗiOKvkJKܘ&6iFl9bD 4oD<76qw.)" bUŀֈ?}!kNנATk=hjnh40M6~ۄ밉rHJY iByTFK]Fbt fA[K" +ĂU$Oi3ܝ àu&Z%^|=_3wݘäKlms{k9zgKER~nA/~y)yBfTm@;iu~Zj0aB?t|xqQo1怎g/]Qf5 ĤհՔjӷa  PX1n\2@g+t9c`&ϣXWզܣ j8>|c0eRu2H#%.<*o@I:(^MP>|zӄAx0Ikȶ" TD\8h7drp!,<2/A`zcC7Ҕw*澠%@'0\Ha~XkO|B\]ޠ]?|mABĪG`jlဘM}G[A\doomD@}ס\xТV;szE3nЍG꜔9AlB q?A?\b_4ߌW%lopZy~;wqTx26Loj<.h Y""]9WvsP? IGQ-ܩ|SlWȃi @gEvTB»d&*y208Q^1H-gJbcx=\y^˸Pe~PD&ng ;`|fU͜ q~ b<KP7UM<V?7)QՅJ_ vsfܕoԴHqhٚ gﳺ= SܳLZO04d YZ 3V̒FX$ ǭ#sYNI+>[]k iő (=*\/fgMĄ1eI+F}k*17]t~x5cXpb[jf01O^F?Əs@$ _[7}Q[ϐ? 46o^ dzW!  RVapOtc"t8<-#iA.H}"-ϔzG_ĮʉK62O. y>O#a/a -3pȕB/Y!m Bk$ɒ3 zECD ( aP{H9@^ɻ;@!@.QOp!se*?'\r?Up7^ b 1(#BpauyC7}Xy ody.j0Ɓw; oW-6p,Yh0j>y nTaNSd@lmA*~x# p@lش˶D8X7t՘GCzI`ֿ( 4ҝ,c+tٲ<)V&>0[u 84ꏢ zg"eYOOT2[C1p  +qu킄14LyZ\>(ȿt2խ;q{Mˆw@\(T\A;X Utmɬ+ӳ15^ݒ!{qg 8(q"m uw!~kF2;4t_@',ʫUrvɶ,s[̾5f^g2Uqzɜ^d0kލq87qAurBfmWor9ݫjw<bristol-0.60.11/bitmaps/knobs/sliderpointR.xpm.gz0000755000175000017500000000100211233572001016642 000000000000008HsliderpointR.xpmEMo@s+6]1r US%QF6"ae^lu/쳳3̤|:w!ǟӯGZ41)A q8/G܊3- f&C9a(3Dw*V;DT4g1Snu1Ś]H S12V >QȽët!ؠf藒 yd"t4C45{ژGf}-c7.Q rM Ze(PF R'ΙO1"MRPC/ =`f˞8[r=]9͖Mf3Xt;6?eYҖRZA/v9F{_5VliٶpvcZ㗫U_꺃]a6x] m}oo93,qZbristol-0.60.11/bitmaps/knobs/knob5.xpm.gz0000755000175000017500000000517611233572001015222 000000000000008Hknob5.xpmWiSZW#Dd:C@o*)d>'ro+zOެdgk1'k0zO7vr\]{"N:'_ D8'믓OZNy "d8.3=KXe *]\ Peځ'`d; AyWgxxIMPX.߽ą - O8O:"HEH\\7N`3t ~3gఒ&AvJ qCw{7 )A\#" C.Fޙ ^0<6-/|G*Z =!?E@]+`_^]f'h\>+9a]Vc~vv;(7C/ C;tB蜡!薡Ⱦc8/ʻ #;.F^pɰbxٷ#jM>o0 >wKLg]@p Ͱ? Gs=1_/‹w\ 9iIYp8qbD!pجdo-'= ۑJWr< o#H;^웣.2ëa%ق҄.Wϯ/[?YR IYafD>i\lIGp#M* xym"yoq)\AYk4jGS! p i||ܤZCQw` k޸ۭnvq+{aǻ2bȚ'٨n$ Ra=u$o®5end9l.]MS^jd"5ʧSxv42@d YViC}D`i ? p4{֩uz w;5~0q J&z&X]f76!*=?*$"*n&xX۬^ށG8A0L-⺆w=vk8ډT#~PŶ=QkکzG% ,c^Nݔw5E&_SQ)a(޺q~Y THWZz_Qy:=$\;Kl+_we\?"vn#ɉDhw af}['A:Bv@?T4TC+d뇒 2&",ݮV=(Iԟ.rZ.uC~S^SCnMD#I|6rSstѨKGB=Xᇳ[rd뇦Ô<E6jvX-|>xx5tJ*>懀qG䑬>L=oIJkꘁ=JݓC=uѴ&(:Uk(A9ٛ (>c!Ӆzv?#^zHHT~s5^*#?X+jB$Hr)7}`xN6pA{)?j!e=tZHՒHyvG^JJ{=q1g . ɔA?d? bristol-0.60.11/bitmaps/knobs/hammondbar.xpm.gz0000755000175000017500000000120411233572001016300 00000000000000_Hhammondbar.xpm[@ebyK*X /fR Im{zo_?3U~߰cOu',bY,PWmVӆ}y~Y^y\.g8K @ ky-֤5v3 {!)lRSXTN|hP \3ԃ a)v[ZT+FxT6$-WE | _E`S^y[M0-pW2 6DB]s} &ASL:U`RZhA )&`[M]-vE b$x-Ip js#x  xy##x/ǢЅMT)S-֥3] [8NIgg]+*E-?@006#3;z6<]%x(Dh,Tqb&S1F*&6sQkbW/.jco.߯F0g/: onnow63z͋V+Ok+r z6"܌1shEA=BtҲT4rl+N4zENwu}}v.HSV27~2ٺSnauwx|?;"?t']{CϽӻgtsf-=㩇y|Hzƶr$gοY/]es_}-~'-zك@ttT*^Q| ^699d^u{v^uӊZ\8Tj5Dz?5kK;}/EfD  bristol-0.60.11/bitmaps/knobs/sliderwhite2.xpm.gz0000755000175000017500000000065211233572001016603 000000000000008Hsliderwhite2.xpmkPWߒbvI#֪wH" F+߾|0XmWxq>'pk|h\u6fs{sg\smu{v߆_WMꄾacm̧?_gg"p*~+)Oa_6B.k7p$f:jL^/(jwA} 6)<BQX =B^atEa*^ \8c uOa CE}FcqFa"S yu~6>ɴ$Vydi>z66 Ӂ=qUU *5m=:MyIvt4Ua]4G BqcFyv*m(% tItDx:o^_(<(bristol-0.60.11/bitmaps/knobs/slidergrey7_2.xpm.gz0000755000175000017500000000232511233572001016656 000000000000008Hslidergrey7_2.xpmՖRIEH(Z;2R`L f,7/8CqtUjUgI⼥3=WWG;sݶ]{wxt}&/,Y6[o[8?ۣJOGsMBv_^$yS"BOcB}\''!)1yBC_! B~/ }C5Bo)zF^'ayB,OcBC_7Q5 A ='s/DŽ˄^:T'FyB{%GrA_ꄾ5 }WU}OcBߗ7$H^$oZ?c'yB觚~&Oܽ# ow ?|Яg"B!~ ߪDwrBF^z27'r EyBcB7+ &oЗt}7 K˽!x [[oG{ߪr? -[5o#[ߪ [NkDM[ XqO8hd-eS!?d#kFGfU9*ȶ,cöi` "ў:s_:`Y-gy(#2Hu+`llD)"S@ŤW;k{ovhG}Dv@W9N.9F#SDEt>Z{]ڕW9A|; 0A2*27n3ְ%$5#SCŰ\[Y{ksmc4,2 [=dK}+-#"*ޛ϶Z/eB[` 5dVQunC7Ϸ߭>fv^tuO*z@H~0pF:$_V "BEPOQ\m*LqBu0cG D֏(XP%8n!9f C&f'xve7j&̩O+'X\վ΀πUcTĭmbristol-0.60.11/bitmaps/knobs/sliderred7_2.xpm.gz0000755000175000017500000000161411233572001016462 000000000000008Hsliderred7_2.xpm]o8H ivء5Nݮr%BK[Ga({_c'sZߝJlgCg8/Fr(u1Q! h]qol$61l)%xV>"9W>FPXhMmg̬Mj˥ +FC{q68F̈*Z!.1N\F\3 O245qT;P?LO481&sĪ{_(.+ Rp_6 FꛍfXנhxl N~׶qWuZ %_KOC@uwT:d,Jwc9h8`}:(h0>LF#j.ld{)F3%{鏘 Aup3OE?g6Wl_O^>oyXr~ g麫uay{l .3,[.\׽Ynbe[=>#޷ζ١݆0(81cq@ KT_w}3Kuޞ :bristol-0.60.11/bitmaps/knobs/grotary.xpm.gz0000755000175000017500000004101611233572001015664 000000000000008Hgrotary.xpmz뺒-SHM4,14Q9gsٖg?Egݻ=[=WQb兊9//G/W'ˣYx9zkzMcožQH|wlOXo$Bo ~l&[`~(IV#10D~$V,9Aa|>O!}NӤILA1WF  Q$}N,wF"3XHBP!#ɇ/=7GjHCD+;|hϧu| %{aN]wBK+&s]x" I&녽Xߣ?&@y?b'b3 h"~9W(F"ynQ,!D'pE_%16G|u俢~y A~}؛fkڰ4pH[wYoXAGy7hB ("4Kme1VoPG:Ɨx}+K7/]ch!^=[}u\`t"!sMX@')FCi'ě؋%||c||D 2~ۢE~GktE{˒_ sE+ L!k"~C$lb_#haۄ>-KnC?0I!E[!7Qn &[/RAgUZB> }ݨymOo:ʣrC`}U`Jzأ?ð< ,m<a-DC\NSɂB=-pkث)pB kS=6QG_aI" C/>=aE.pH>5`Ssixw"q E|;wo\_Ο/_kۓvc<7 {ޢL_w?⛰=0y?C{d>& OoLNYGA FXQZp(; 7SW'& ;罐gCKgUNxFG O L^Begq'ƠUhIIeOE{?[4 7vB.p@Oў.c_a1ז|'4_c^"7X^or]øxw| >))C8N0͏mg/}%pH>!O7OC[OTwrZY#O>oEG yZWػ"Wum ܌cj_ۂ=)h/LdJz(gO)ߴ,o>ϲE|CXOͳrq _?nI~11h$}Px&; 'kc'y>n# .Kz&_}](/ka'}Fo ycozB7a}Ro~t81JLS[ Og5w]ğs_XԞkMt%?҇g r-c$ yQ\o ~<$,[d$ yP-?ӂLw;I*q]"Z.#~y^(om!&QE-WDgO21|Jо%0iυ(l"$MPȿ`G^r2Qߗ 'yrS9*ۓ׻6pGOU1# `O "T;8O0DMybxOn>gϷ1/H@e )D?b>c(>}YT[]طI|n?/ !O$?"؟ ' I>g ?bO woN1r ˉo8.`RG|b}5%?0_ S|Ugo̷G<#=16Qޢ|Sh7[+p]7ox~ˉBOOt-9Ej! 1tٟ~OK>?bP|LÞ^+[g%v總Vx ^|}v e+_x CWcՄ?mHl6!B6[)wa#?x(|b>hOkO1p[w=sMC*Bq#f_?McZ|-pF8_ܕ x\ő'G/_5Z?/|-?x8?# yX>xGc~1c/O_L|Cr_>q>p$7ZǒohGD ?(>#nӿPϷQGQjG~#`N39#"β=$}ޛ~kX ן7#oRI}؞E_ο4iudt?׳>p*/0y |Lp7r1E ojdi#\_#?nK k𹴯 \IKw __xH![q[|%|hraz|goU |e$On]c!~K~/[o#_ģG󁐯+>=r'&?}OϴY>>tyYg^Ι_]i[%%vOe}wW50l:|au {}G'aDGvX_2ڕuO5'3\ w=[dh?烘kߠrFF0 %l,x`b|2>,a|_1>˓j<?h! <2w"/~C|Hې^G\?1;j'nϨ30;ߟ]woS Ll?|}.@|nJq| 䧏|! K7oywG؁>>$:?Y^G8"ciSV&gO=Aؗ|JoX<4W}{`;xp.<ׁ|"/b~/I2;x"Ռ&5oy[/|G_ ܋<׏}¶_i>/C'~pl|鱾)' [fe4gY {?恛>ǂCO,wbgyʯ+x zWƘ Ƴ|y{CƇ6ixS pD|>e3GR9\N"P)~Q^_W:o~ooH~i(o?q}2hA9;M/goo1X~y^=pyC7D1Ai ~/8G h'~"F@ΏR6<؃}G7l/AMGx) o}_KKi. M>~'KY~"7\|xrsܔT7)Fr|.l/޺n;l }H~DoQE oֿQ'2^<|6zo,\(Ki^~Z!חGĜ?w_SGp~0).)ϯ|=||_XQ2~Tίx_|#KlO/7ۈ]˕Kև<_P<3_n ɟM34{lxzgAF{C[w%?x ;p""+<Ry~˜/%.cyb^:9o|^)%ϙMF{ 3_b/_ejm e_ys|X>J}'xQhKHg`.Oߐ׊l%\I#/g7[Ü#~%_[X_\xwI| `F|mG{Xϟ0$OG9I.φ<};8JBį?9{ O擷0=#fy?z< <3ix?@󷈇o,1Xn,_|޷%hh}#a} eLMس]/S9f}LkFڳg%ckIKX-0NE?^e\ﮰ=*5pl'ϘgnJyO#f};<+-WY^Jfuu׆-~Ias|k`Kyl/ϮZ/5/#1e|~+xl>">wy`fy: SMUň'3e>/0lq~_2fsv>=|L|19^zrذ'mz|~\m?sQ{xEIČ$߬yp>zDb?fr$x K}#z,oaDV껏|N{)/$|?r_:ms<`_(}??_Bb}=|ma>@v?}z?>߰~M}d?gY/ ;G^?7o/??xB+w:'RuWl^O:WUt >&| t}3aAo`G|/psl]C~^gG#9C?8ݾO|j\Ot<?: NҾ{:ϟ_~&ʻ|)%ȯ}/"wu6֯5d}H3~1A;2N}Y3_{ |KϷ1_^}"LxI~y> j޹\̷~J}LjW_>]أkOcm߼>җOI'4G~-f}yf#:7ۧBFo3e&+_#׀{1J{mp}6a e|˿ϋo~PߋV KGqA>nֳpc q>f=*@ȧ\2el~aLKϛCgmH[7؞1KG_Iu  dj\[!pOg@{\/N'O`O͏ǟoM?ƅ~~x^}ڰO`|`> 鯘#`"Y>?'/C_9߿K}xO'^xv y(y g.Y_J<<?R꧉|%[<_~/$ڿC?^_Bfޔ!~w)AD{/~~GIܣ _PUJEoW7 UrO~O/?2oXf}8 ܔmSt9dO!^$y>5<ڣI|sU|;nSpjQ~A?y^[<>?/{%B|!_O O"/q ӡ41a]7p,1߷~ReS|<y*y> i>_}g<q /cp`>t=SÇ*|Q统P!|o//ʸ/~ށ>o[ O~cy>A^"[0<*ǫLw>)Gy!7ߌg|9/?rcGG MG>ɑ_>=b !ψa~F<הrԞ(Ix|!?G=ě/o@P?~C_Wa)ig}s}~y ^o/E? |߻Ow֗/VY~|"=2ܿ|? Ο]9~C}sewց}y?5K1d{fe/j7:&=S;C+{| n?7>pۣ/xD|>~8py*/8#>jB3&Cy?|0JU|<C඼0;f췐_'CG^?4d9}G\NP8v<#=c}S:=x!/e_q}'x[dn|nywB'yĝļ}RQǃؾ^RR ,M">!R_ܓ><ο%8w}ׅ|yxh))/߷=-0i/!k ~}cIƳxYگ'qKY_y)ޔ_!kOpOvJ$Ke| < =b`eHۋgUeyՀ=y߯9|?8'~KC>g Lv|U}8?=y__إ8xx8W+| | Aħ 9^ur7{?~d{-k߿+1zl>U;}Z`{|jO,[x9)qŕ;Zanx<冢8?>{?o/>_QM<cd;>=|(o6d?o]?M'== lӦe{2|{h]:"~K~5!ļ mQ;,AQobD'x<.7/p兙"~ޟlg#|(a}{[JCɞjUЇq>nȿ?_~V(ZEhUJZgbTQeXT+㕱Aem#deS4[*~%WJrT9TN+gErUTnpW+_ڕN[Ute2[W*OdX,WV*$ZeQ٬lU+;!^EUQz\QZݬgu]FZ+è>X>Qշ+?zֽ_a=ިՏ'Y~Q_կ7D^]PS}\g~zީwQWקl}>__/֗RNZ}Q߬oշ;!FݲRZeZX[Uu2uPYCk`[֘u`MX {֏m5-, Њzl%kaYB:N3ܺ.+qmn[κGz^ oֻa}Z_Vjk5eM[3֬5g[ ZekZ֬ukڴmkڵ) *+PcD9UΔs](RI?ߍrϬu<zTg$xUޔwCTV:JW)}eJVfH&ì2+ ʢ,++ʪ+$EoӟeW9IbͪXEMjjMZ^kzͨUk+ʨ6 jX6Q*&kA+^][4knͫfa-ŵ֨Վk'RYJ9].kWg_nj}X{=^j{YjZGHѭ[H^_Mfj|mX[-VjzmZ߬mնSj1&ʲ!M껵j1)HU5T3QSZUGa}u\S uSonߡjxKz_V[*٭j6#jz^zQo[NWQ}Rտ2~RjG=ڔ:ΐgN.:+$[*ZS uSRuW=4Ej)ZJQKL--r kVFPhڸ6hڲ:ͪ+۞6h\ͣڏJ8P[S#-khGڡzEdP3\ 9.+Zhݯ ڃ=iڋiڇ}i-M]ꯣ?oQmj=To˷6bmV0 k_5U[%mY[V5m] ڦmk;ڮvH*P"bmmA-Ll㩦`i阩hUsdC9n$×v`Of^h{yMz6kzoX0cy|AaK;ʏeg:O3p%Ujv_+os>Iڣ_5Gd rN<}!vW--E{?#3[Bv7oNv^?sř"9|:\>/<]̗h4T4J迬&o;fo/Jy<+V-ԃ'PPr&q*5vcIsR۶Sî#$ڍt`1b.e(91f;=aO{ |ξmEkڮپԋjvdvb}R>OHS~ZO9SmY]wK$쒗a.}$L}cw`?O]^W~'5[>/!"^fnuZ.[fSJZ1R{8=OR,؋N"꒽B eثno؛mؗA]۷+z)-DTtJuU%^ʐgyes8sٺ_e穡U}Ū> ~n:O{M=\Y# Hu%zC?")~'z P(6)tq~W5#~sl>ezj^z͜SR2tKk),4o, lU_# }Sҷ}WIC}V1d[bԌR T)%ˌRrlX#KkSv_ s>Rðm P mZfK4T14F)1n418\j,b8椱Gh |#0Ј^Fxˎ~629H/82N(Po p}c/?6NI=NI3TOsB@mQۗxvetkǸ1J-d:El;V-,֨fwƽuGɘx3ލ4lhmc\/iQ1J>d3F:eLgYcΘ78#vpDqsXNOiGSl5ow̰fOcMHnl4[mZmƎQ{.Ijqܥd!FTU-J51JJNBQzhVOS-nJsZV˜IFծիoeTŨ:~"}UXozX4''du-4_9tQKM'EOڬܪWN+Wt>̖jIVkQ5BT'׎U=٧8WOe\޲cauu95)SVY HH24'!AZq^<̗kڿޫ12Y.9ѴOZwԯjڮv#֍.Iѫ^gfG0թ괐a N)9:ֲѩ錜Ogg|ړ=Z0A?G4 )ʟ2*'lctL/bvWGh82d0*mT'F3g7h#٣7Gr+՟Y2|氅yKUuG?vs6 nxOr`QuIx4v2hNF7XG"~9*}jt=W?QSv}Z1vtG2γ ߒ~^Ft3Fj:i= VUӟGG uo2Tr(gctFvٓDS{T2ClUorWӺH̹?S#JnRO sfFeətn4?Z3_ZആvΰKewjoN i03lekZJg=G6[kVvq4<peJ2 ׇp"C9Uw;IoIňA}` eQ/ij-U@\ 85sٱt@ ^oo@lo]L}0oNZc (0`0> &f ~$]s#ł[*Wk5h`N_߾O9Я:M,K V~K*Cx~I?M+~yE}*R[^% KvmG߅˩?|]~TG~~ G^'iN$cƱ0k1p/bdv̏1gџ4b|'0; qe2SGmb7<.Mv HDod. Rd!>چrӚBG⋉=t7_]bwb|+Ǒo8 nb`~Եg@ &Zx(wb/\,a/0_˦E<5V[3+f$x[WXOFuo { bristol-0.60.11/bitmaps/knobs/sliderred2.xpm.gz0000755000175000017500000000144111233572001016232 000000000000008Hsliderred2.xpmu]S@ ~lBegdiEQPQ=oEsvy&}[Gě\r9?2o/g?޾e}?`VUEƥBvPB"&\a@&bs%bPRI TBP*+D)Wh UJcԡF`f[`.:FXH#QD!aag<9ap]josK #^rDU V0G Mn,-(l"[D,B!&2QFO dR&aLjgF10E8jKtTDcVSXU)Xh'Ex++iubDׄaEx8xD8& $U\sV9ƼH@"m'`.apƑh ,g8Grg` $7H/h0ty_ wXΑs (~"ăt' zNjn񆟵Zy:iljfLn+2Zj.QY˷wYө{4φCD.'086'?u5X๺nno7׳j~\׏OpX yy}wz7ya[HXy(wfc8'nիz]\w^ӽߠBbristol-0.60.11/bitmaps/knobs/sliderblackl.xpm.gz0000755000175000017500000000325311233572001016631 000000000000008Hsliderblackl.xpmEVM ^EUۈpqQQ *r_:oS8;E+K45jpv/h./vwO>m<ZSv4qp-z=?iC[˷pHkWalyTynv>-?YQ82{1V_pGi엩=Q`DkP H{-Oݏp !NuZN368A KƷ{g/wijoE_,~?gE^"[>"ZOwxڄީ/g/˚\\dLYi\Ɨ$4V/=~!>\ Wu˿o)#=jp߮U3}k_k qSX?p%=3}~n{yPW+/x5epWL+>~ %Nϯ"Sw{{0밗[,z~z7؏1c>%_;̱1U?Fq|kOqW'A>Co9vJo<7L; k}&8cokX> 8 c)=*Wwy=xPUʝT:ϙq q+4BY *9c~8鱿&<=w^:Lo4!5{Z9G G z5Sدg|w;N8x.ϥ5+Zi{a?$_>~پ}y7q AOp__?Y<۾)/3x8l`ΧnW|^s瘷7v@o|W!{gdv^ >O&F ψIZ_Jb}s7'I~zp!E=G"˄iF^;KM}ޟIsL_!ip*߉O~#a,6/np?7bbOΔ, Ҙ?h^d4zZ8M mlv&D%'GɿM֫6@TPڊ:.>}QW:Cv'GtL'"13:"tIW~/ߪC5u'ҧ3zN/%-Ѳ+Z*}OA#}&byG1yq!e|97xgE&xK?V'w/;"A$ =%ᔷEvxxW^G|,r§|/'kkr~D ~K̯x_G~˫"x:YZN.&ɚhGd,J3\ 2'Pr$f܃܋dbristol-0.60.11/bitmaps/knobs/knob6.xpm.gz0000755000175000017500000000511011233572001015207 000000000000008Hknob6.xpmrJ'O6$u#*JKd ijϿVIi@:te˨ևyu~6UQ3je/e-ڸv帥>bn HI;&3_ɬDql9s.M;i𯟜3's=2 y!dNt.؝ C;<)ܹx98d^? KU=)r"S:كGf9Θ$3;eGx)bsAoI/cue;LAp(ݷYF0NtȜ\r6{d{SWdx89C2?=@4uSb'IwҗC27,aHv! XQS9$Oؓ3ɟٴ!q_g 9 ̆=nR6}곿v *"sK2.pm ̌ʡ0*Wɿ*݁9'xL>3E|ȕzRpV%jlN7&{~뛑YG޽x7acmt ØL&GMzÌ"=&F aRF30&uc#ϐwzclFfЏZ?@a28%k3>{5'4EÀ~ 'XoQ$2jJ `@7r1iдKrA<.qiaVԟ&8e- 15C3wvF۱X,˥s\ײ,8ż yezMeabn_H%\Kaٸ\ bHNE%HB.W۲.xF"q$׃# @s)WAeAHyS0le).=V3JiMM:w_ a< 1N@#!B\e)lB(3ϝT4DX{^*:,M ;&aPX!bXCZ6*C !VC՗fu ,@45c 7쑊HhV&97'݉E4;b` k i t ȟvGa AFq4T0,l,^jYW+۵+%,ĸǣٚL6j\RҶB,S\(ƕAi)9!&譊Go"@%k^/r^E IAlO3Q3ӨA遁7-X.?ܮF Ǵٌ&z}:ĠZ7^wg)<.b#|ܦ\F oaTO'+Z۫b|^`@8)4̊Ѽ* dJ Vb|^!YQbzXT tȄ^+4CQXNm*!PlE_UL_z}ȡ֫dne2,Kp;:^bE;Oף{u%IoVA b ۡ.vb;쒢ȸI`z19=6_v@]wyѹHC8PPu|> !LjxÁB%x$2WJ*S)|#MEq3w`(7 IG,hA lNy1 tJD12tYwɲ :d\21t(R\$$١;z`Dʬt+-"K gx!%ɀP6gx*ᄡt"(|!I CرD@܌ֲj!9Sn4_ȃ[f @\37͙Py(2Yy}Gc <Zu8t(kR&߽UЩXOU#T|԰oCv&s}Ux4&sIy[o^ yFMY/kfJCoDу}Jaɉ ̪i==<^5~iadE.߶{`-/iDթ 1xEYzZ񭫿 9Ř}2[aF͓l:_hsgq{>ŗǯ~dnl"뇚64v2E"%O4wo8}tƇ?~}y=!?L,퐦61stim1γiCg[` d4BUJx?"hyڎޠi^4EAcj =eT8bristol-0.60.11/bitmaps/knobs/sliderwhite7_2.xpm.gz0000755000175000017500000000157011233572001017031 00000000000000UHsliderwhite7_2.xpmYO"YWEm.RQ\N:!BD[[>1s1ɜBPI%ge#Zx4'7x3tImQo Kfڰ҆%[8vy1{IF${p3C0"ZG0& .|~o&g >5}&"WE (?Ā 밐&K!pK=5MN!.3G0[-kEC. ,`Z6ŀ`KmQv`$mWK'fEm8C04 E&nN k׭6 >h>j5Mv>irOY>kMvd&kü& zϠ/:QO,,X0S&/D,VYGMX $x*ZD๨+b`j:/ƖH,Ǣ EZn7/{وoXDN=^gL3>;[1q;نe;鹎m5;99FjwWWNL7o:|VVRPnnv4Z]sc}ۙ\zt; :c\Mg6S~]߿ڿm>w[y?5;o??I=~PLÃ~,zJG~P(&dG%='S?;nxBk[o^OۙY=fy :7 n£vwYrNJ ߨ?*#%)M=߃gE9ͯE~Ԟ~LU_^'YaY .>ph~uh{ "K=}/X/zvmw䶰]=ow] Y\U.λyw>w"?uC}$#Sؐc?Dv|^. PBY܍+?_< \^u3TXQ׿Zoe׶gMK}zڎٶ|<(7T_iޫ"J>IՁ~>?;j`3&U.q7?¹!o8śa.r_BkcqOm%`<㈰-cE0yp#맰(}QQ2>GⁿY$n'[9X xy}SWgS??ƩZWNs !Ht<\Kw "KGs摇<'$y}пpW**?RVc~UYI|[X mث^]ՃoNzZ˨ P vQACm:Rw?18;d>>>y#矁w9L N&R}W|~?[A<1[V:?'ay[^z0~/==e8oKo+?c~{'fDz[p|{{s{-/}P跏_|Re~k|9x/}M%F )#yeg$`k̓!Y{ǰI8D9?a~$[)v=܋}]I5_qo%^7}v? ߴIcޏa}6~Fg4>sDOw)衜 ^Di~*+mT}dhii$g`54K 4I4NtO7FNm ѭ<)hS\lXKNOF[M;=~ItD9)9]%]/M?jMR zIuq)Y [zG}O9V7"f6ȃ<<<֘Q^ f;ƛk5bristol-0.60.11/bitmaps/knobs/hammondwhite.xpm.gz0000755000175000017500000001775711233572001016700 000000000000008Hhammondwhite.xpm{r:[aْ%ϤdY.9÷Vt7ka$0A#0#y|:?4[;ۿ9z=;:}R?ڭ(:5jz A~Tq~N8aLA\G/6Ѿ+nba˧)p!p]2l/N /a@>Z!};^8۰w[ڗ/!\t~L|}3}(Eo E/'EMq/W.(Lt{_SDmLyъi.zh~1k L؞Gy?NNB'Z~Gs ;$EL#zs.>%p;//"Úꯁ~"{o:(>n;uX~w{uYܿ_q] [%3y.ڿI}z!O~|"{s߮i귀KPKUZ_ުa>p\w`$?5OGAo/` kYnߪ9V_yƒ/‹_OeyI_U߃>R:?쟲xd{y_E|xO+1u8F'I5ɧF.Ẩ;%';|iqU4C')/eP7;AOrqT%䉏15o-|y|oCROw[U{ xq4%~Xk:o_Ws?zwĸ cƲ-TS3s^Kt0s0+IkO??27#ǏlOT{g?q?gNA&sJ[+{ ?Kyv>ӆ?&8KX״Oƛ ϲ?J?/_ xW?̗gK/X>ˊo^UL5m7F^? 9Oϑ0GSgʡ.|0e-n_NS#_NX?qEa?8|R" 'ø>Gi'GאS04KKKV;]՞?wz#\/ןq}=䳘-\4~=4;0Sx?S?goYƿf>O7 ?n4W~`VQrs_2?~޾qwN,_@>W S`4/WNi'X?9?&_鯩&19~ڈrxm9滏Gf+/1_ΫU~Wf= 2>|C q o|+xZ&%5|xNsϲ&iY4q<ߦl/0oq?vK|Y/ſ5L%Y$IY6ӟLWPg/'#v v2p.?|v.coFv}[aRfd0|mo/ko!#Q&WkKGAs '||/*L-)~VYa>d})^ofI7U pt…ȇ=YO֙?ؓ _/]o"lo._Oٌ%Kz'D|2DZw9p7#Iz>|eH0ֿdUqTagLEn~oo7e$1_]zoPo+x3?ro(3?2|o|{1'+O&27g,/Λx__|]룿ky^iUN'\@wS'3c@_*Go*=$~?}Y>zP(L*_T쫹 <j|Tp$'>=cU}fuq=e+`?/0"+pXUȯX?a[!,]k XdaNrXDle X~Ҍȓ} 8zy{ \eN( /ץvՂ]f~pp*$_Cy)~%܆bt!.6?xO=(pT={ Uu76}5ceø/Ⱦpߪ4A_A#Kń{/E8!XG?(b|<([?/3C_r~!篜o^'8*kCFoOs|ސOxTo+r|~?QюiRWۋESFw8.DG{JJ3W2!Y|gېē̿\O_Ӎ yV3/Gz%GZS`>/JػW^^!~ U4 łLBךցCo w E[3x&}|Q\d'<Ǐ)`mgGb)~FLASW55|FM3fK[>?~_6O*5x|3eGg$)Q 7>bcĦ1ޛgKI([b\}ϡ)/ߟׂ?19 NT|l %| .KSRoU p W;S=[)s}- W/zL|b=URC(cтxqyZ['Ih)mR?{%fߜ~W<_žSxpD-[ߡ˖_Za~qՔ[֠b?Dm~{fwOKGǢ/B-gO Avߖ=/-KwsxGK_}d=xH7A>1~/%_bE } K(~H+@/~}7pȏEXa~Nq|!KD6a_C!_ y?a>K={LGb+1۪⻣9X>q|F3Pa[Os}/'6{@2^#u$ [17>%Ǐ9.`u%pߕ'|ZB [r~¸?Q?QDKό |e}$~||-c3q-`ǗdW=Ϛ+Oo 1X F֯Ge/'ROqʸ/ SsS]_6d_0`KOr}ӔZ!ޟ(  Ic/[b}|?槃eg+>Wa#|l{ue?},_ἴa4x?X)_d ķ [U=oRS`_Wq-.E8p%v%C z!~q8oo+C~PO|'}plp1oy ~Gaҷ [=^Wn3w>J_W=g8ϡx \=É.yʼn`?̇ސPN8ހwc# '&^]3%SRD |j3CB?ߞIO\-Tx?\`(ˇ>qNgЧs`a?sA/~?\ }܍+0w QOKkW#Q ^ wݼK\u.;p ;x?\zo½Xq0 ='jCO]x p)uD%p(%4G4]34S4[K5WKqmX iڏmk;ڈ6jܘ6miڗ:ZWihiP;ҎT;ε 䮴+Zn;^{'Y{^7]rJjMhڔ6Mr3ڌ6iymA[Ԗڲjkںmj{s=3=ˣ^^{o~OoFAoƼ-^z== Ћkyށwyމwyޅw]yލwyރHrOޓxޛ}xWxWy&IoʛfYo{ ޢDrs¶ޢxޚmxޞp8Nᘎ\x:8yg 9Ώl;;Έ3:Θ|;_N8]NN$rZξs:Gαs:gιs\:Wεs:wν<:Oγ:o$;NNTNlx}g™tigƙu朿μ,:KB쬐ܪ9ΰl:{"UNezfdffevfndp'2Z3vvh6meW6洳NzYEYHn?(;N䩐<6-!+w]K!y] f]v=dSLck[}d*2\MrMdٔt:f9Q^|-,eĘWrJl-[6lOLAOwLuC7uKuIuWO_<ׇ?:!}@o{?#cmwN~[~Y~ c\/+Zo;^C'Y_7]sKk/ʄ>O>y}A_$%}I/+'Rg8T2C7 4,6R5cܠ6?Ɛ1`ƶcƮ(Ƙe|_F]gF`FDr2E90#81N\?3΍ Ҹ2 Ƹ5{x4g{1^7Qލ#7 4*6Ƅ1iLƌ1k̉Ƃh,HnX1VEY3֍ cI333u0M2msHMLqsc2OQs4wQs2/-̎5{ofhFflHn<0E6c!wbgya^W_6o[μ7GU70s0K2kI}sœ4isƜ5̿漹`.ܒ\e\5us42YYeX}aeVjVb[7!k@ڶvkڵF1kձV Ȋ[֡(GֱubZgֹua]RֺzެwC*Ҫ[֤(Sִ5cZs_kZ%럵lܪfamZ{bl6lӶlNmNq{ciޱGDwQ{޲/mwtپءٱݲ>"c>>/KʾoξG~_W~? +QjoO1'){ڞgEDk d{u{CM{O,^Y" S+Sc I:ҡ3I?ENw![t)X~N%^꧁(aI[,azO,=O/ӛV>}Hӧ9}I_eyKEyM?<-2:\nOLL:Ke.Ke>]hbKӕtҵt=H7ӽ(+U7SkktrwvCT*vSvwuG1w&/md1r#=qO3*Kp/+ڽqoIνs}r+꾹\nVn~}wY;N3;%yw]p%쮈_e]w7Mwx N%:#1B;K(!ƓO2 $? Σv$ػhcVM:NMz ma%qJ*TO(9NN,9Op>H.+QEo[U.O)yN^C^=HI)UJꤟL$T2$pz Pbristol-0.60.11/bitmaps/knobs/alpharotary.xpm.gz0000755000175000017500000001410511233572001016522 000000000000008Halpharotary.xpmiWHӆ?+a倍gL&Bd(i93 %QGae'`wWߓ G@CaMUaOğ?&2  .~R|Wsr|?/`e{ !~y lW3P?e2 ~Io ,( K"*~<&۫0/e +0#Y+`vp? ^|`;\0OeO/௉? .8 gY`oiV`,ޚǃ[2}y._~r#K0o0oL >.3T->'$뷼?`f c-2Qc0o0o<W`|.hoyYf[|to-~ -_~v.HoW`W`3o0oK0o--~>O쏭X0o8l/Xe{-yYe; 뷼[Wa\oO@ZRd=lo{w5jDͩE50"Y'!`t 6i\{Ֆz63϶؄IbY(71(A/l='3!",=]TL1覽%nD.b!"4VFp},忳3眗%_dc-G0,dDC!]ΕATF_%q I&<6!bX[" jYȑC^ 6iC%)iߦ=öIFˌ3.lXlG+a㗱bQdSlMym3q?'C & F|[Hb`B!LЧ0=& ߘ"DF=QRȆB [Nh~&o%v{$7Po(}D@pmǧ{ӻ0J1ߌ}776@@8 xU1 _}epQ8PȠ߫;_$Ǡ7&v酿83'(i~KdD'g f,.#0Xw+ Q?y]=/s!XO = B zPTkɀEeH[ڈ޶S{=BPPhA`L(PЄm}yޚ#}UaŊhAo* y2BdUa[`P$i7v(aDLN!+%z'{6 X]-0vqF t;L90?]ol~GBdB6 YC̆`O'l;H{y sM>&:g(̆B Z3`5i2τt3.p)]a7TGNPCApv?0}pfWAxNOK wAtv2(pDՠ~1 ~Y%HfPj PDCxK!n/] a#Es=ZOM"Wk7{  PNdP Π:k 䪽פz(P#S}`ev2'2u0cG_B5dys+/_G>}n#hP.EHbpy9vjN"7xkQ!R3qؠy(n'/%]M6a8R|T]egJUKFѻ tW vpex$`U丱 aMus'|q?ňcN< zpK+>q-[VGNh˶Zu"cpBUuʘ! W%W' 0䜑yiU>0, R*g(@;9t@pu>\ͻ `f0У{5ί")̐gl!'\)1#@p}Vز8dL. }c )Ū:4cPB]9Yu`yD?͕t$pF@!YaA9欆_ k@T!@z$[^ o 2C +W>I\UiհIհ@A͑Q.:͵r28*#Ta q5h\ 27;`붟V|Uú_k\8G"c`k ꘕ>^ zt20`)ڊHy%@ SCE R]^Oԓmǵ%5a%R -Bv"؛18<$c7Bi%,kMxWyFM YA:%̏C~1F>*aP\Y dfjC *+֠jZ?yO0W2>kQ-SݻTbqV_ /ҿKQw_Z`F5tRTK  AfurVb]J袑'sz ׻gU#@ סEU j>:= ]Ax8^p3C`I JYYWtS'j03yb yAgPfj͕AZ?;pǔ̠kH5t *>3(eftPZ lEhGʇAaE0zpªhg,u\ y0@Ќ E6r`)<8 ?7zKlJ°Os@;AWgLдAPCIc@z(dmGBX[9t GI |<88JSAteqvLY%d땥On@ǫ@·ApvazsߦBUSp< /dfpk[eJ'e9X7,h zQGBڨܓ?c( ݏ/ ~ $SpK;QE7xde9>:+q eXZ%V }NmO(Qfj`f*ǗϹL;F h(bRDAb 9uڝ3hB@zJH:*91ʜ q '] QH'`)ΰ7JW{VVKt23)d?JtS;ޠGXfP 1z N3!ե$ >!J\ KVDA 1LS8Q)BDRQ?\& +쬄Ð# L5z(N&%SjQd[s? j1 u訇msCSx}_ 3ߕuzS \ `3(gfqGMu XQVJH+ש< z8ȠYiC7ku}5#4LpfPz8+Λb ?|A#|N$<7'jzߌk}@+'91~$~=#Zg_c4Z}!0?թ̸H઼Zb&2|@E$Pf {`_٪pRV$!̼p+_YL0pa| @\MH^2 D_\t`A FK%ZP . /N\^۟xCW5ьHq_qDIJ]&`|L$tEܧppuxQg+ϒE$rFz$YqgK.xڹ̽!}Dhm {@4Γ'7jT,8}Jc 9%ǧ ՜J2FH$z|VkM!EIP>C A)k[ùo@LWIt$}i2%-j^J3{jG'aJIZ~]@҆E/]={mxOxnO?J;l@(,R5.*YGS^lzã^I&p9j*)*|{:A(g97(3iU^*@Z4k:.BtV6?Oխ{}CK]2RJ.,V% ߵ.G|{v @O묪JUd^8(T?-Lp}S[שHj(#sD&invvH{S@TjJHF h{])\#z:HYq: ~W,־o…Wh/T*2ßYw,↪⌿?m>l[l2UźGY?U}% k[k |jz 3(yTA{ *"A2J gW=C +BA#Kz91UU= d́H( /@#I#z(٬;ÑHX[#c19%rBfhRowX 5=\=pa@E]Em1`BjdFPg,s?i[#PN>S5&3"$8W^od[A0f̤&nڊ׶T8֣NR(;ɀh^画 ȓ=lTs V+Hy%[N"Fq치ǟow}d:>JFvn[Hz%>nw4rXԬ\^nޥ ѳ m1naUAL{?-ݞo[Z cbristol-0.60.11/bitmaps/knobs/sliderpoint.xpm.gz0000755000175000017500000000100011233572001016516 000000000000008Hsliderpoint.xpmEoo0_/āC w6?JɻM{9 *-Vm_LD; q?#%~|*T4|ӻP۟[LVBkp2_3}.>G€=;Q<uj.W50ިQ*^%4E&\^zO8&/ CBLtbx; &UDT 䍚/KmቫY?>F%ιZ SkvT&Yah -\uLU=#`\a|}`?ԄiW j:x.ߍ9svލût 3"rYixguy\R(X{Z~$o ktϩcѶ-X*GoH9~g:DF8Uc\{7@>oX^d807f~Ybristol-0.60.11/bitmaps/knobs/slidergreen7_1.xpm.gz0000755000175000017500000000164711233572001017015 000000000000008Hslidergreen7_1.xpmYO#9ǟOс! $v_oǕMr>Ռ+^UpojYAwY`5ߟ6mof+ȂqH88?!NW`) ='~٣Sd@,TsCjWCo_CP=TC:8z<>yvsKơU?T^vY0,\ҿe 9Fr-ʘ"{e!D3?H$Ezo('"uTF)d/CBu|2{瘏i-^{/1_vB⹋eq|{Wgek(7.H@YWx[Js$rUi%މ$YXDO cv%? rFC"q!ORW4 )dT8KD&$SB]W~V֕Q w%"Wq2?ܭ*3/rÁ[9d,/b}QGbWe <]+le\"WL_I/~D@%r]RƉOxE8B ݮ"'4Fߕ!qxnVa 0D?=aWrgl>Z{-~_'rCP31y,Ka?~"3ԛ:>CScIá?/?+Kqc/E<&};yx(AQ[zƸ~|;e] ߧzG~]/{7F}?tA{ǖϲq} ޯ:-ScA?E [x_6Vq7#_ 9 ϯd~y@[wF* d[wQesj/_P&[(Ԣ קeQaC!'3Yv-y0ҿv/W/.)s{ITξ A">C  ]žѶo4L sȔuUlP8]΃e(} c O$Dt}:bﶳgwNz"@Xoy+n_d8_#RtEy보NeGO~:>HT`}Amjƾ')KԈ7_(8_nmyXʨCoXuP;vL%fr}lLp twف/|>oۥ>^ѷ"2JE?ڷ|f^7: {BB#]?KY Ozx~^O%~rxi˒~U#>"_p=u+_CN? Bߝj/pq>*!I^Q %Obat COb6R1(\pP6f-D8 #{H1?jgyk CXC⾽P/ rpΨ]%aN`9_&e-Hp]a=%[ڳbا+:2ƌFИJG`oi;d~ Hc`F}RRo-_NS2~`dK} %å}xJUZ PͫtO<' >:`xh9:tpF|eԒzر,ՊHKDaC= u0?U)c cy͘ j~a=#u0c?Wim&#qA]1d*pF2pcϕ)Zfyr!ibMP$&̏K\ܖ^0̙"jFe<2ïPlDc`6v?3f8x:B,eɄe;2%(<Zpńaײ\dAdb?ώYhxXh$dmRzL̉ ܙmZc `Q?o5E|Q/ 8DGI {GmNeA`XB!dmuÅcl7'(){ joOhe0PrcyxB:v7<2;oȆIc\m8Gf3OY4 AڦuB1'~=*`@OD"cFL,j 3Xh4$=Wb!U'81c85g$6 C'H%wƃ+aa!8BM1 aˠ&s?yKhY\VCsDLYcaA29\Y4w Gi:n=_R}>#GӌebPuUb@u Y'_rgVq.L`A'@D1KR{>˔+bpU<5H^Ic Բyȃ-Xך*#5†~  ? `8#Ba4^jl;ݰZph֫\\k/m幉9p7|d&C_Eʉ W-Uks`&'0p|` ..к\p6Υ.N;I6=[Wap m}(IǿK$$b^b3<Ԇ3'6LSe[j9plQ|H R8O%Y\4d[F*V:S=NqD6uû=`Y}s}u:voӼO#׈xe[̎vw=rۨT[qCr\6F8R1MQ[Լ[l79O򼁙@\k1>ޣZ'^30i&!;=}9; S=b·^ .wUp1ivaX0M4Nl4.40|2uc:3d'}j#g֞:?hȾuaGO>;Vm{&]bFq)1QLdB.vt!(O`[~\%iِ}bFUgςFx<6P#)M͎?Z.Oy 3' > L>gb/yOd%@쯚hyˤɔo qX…Lz+9|]9 nQweQ9`{v;s_߶uK=m__'fp<ԕ1Gzi_|?OD{V-yOW} oE,Otm`?3J>.+<||:}AY>[ {v>P|͵ڗ B3<^ʨ :V-ߒ+"p?#a}߳ls-EOKO߳r~}#N^kdI_ξ|By=_2`[ om4䘰N^qG8tؗ3ܡ&HɺnWal\{C~f.|Z ,++f1;6K6~p_uW!a8V?G$OFs7>=-: CW,O",πkпbauX_+/Xk%>K{ѷO+zװ/caq-tH9`6_ _p/W{5羋 ~zox}{d%_ {9Y0~|0~ ,_=gaB_#~-_%K|A8 k L0_?QF)^<Ş)݋b[Ϟ7Co7-͗@;$7K8$w ֽ#;ɡϴh1I|Qˇ?}5h!2ԖbKdG>X/ؗi_5km-em ͇M:Lp>li˟1ڻ]'}8pcGڞ_àO48E>Q|gڞGm'a8I {%7HNiGkm ɍv%ֻƷ]~.|J4 }Ҹ% N}ᯮ|m1ͼYQ`Eힶ|h}mϿ:@NN?vJR >bfoeϻwϟwE%$?y ?/\U,c{\ K;nO7([Dλgw e {J,ܟ+E|V;Ч-3Ӆ}f8)Um?*c]UD`O˦2A%"s W pA'+c,p]Gc?T)7b,ҁ,mϰ܁_AxLA<'4agU0w}axo19PYI'cGEM~ _O|;G?'Gx.7ςmo meξ]O>Dz@0UC!C6yr" Cj[,+XÞvGAz)7p"ݰ|j'o0.2pOa_ħhL0_yÞ>r{%+_P},_7,n?*⑻Tݢ^+qt{,=5}ׅs_bsw^E==Ei??q~-aNfW<"ǏOОEmsa߰/rK( Dn,775'|;|w_`*lh"k?޿'GG{/iZ~/3w Qze!K-G_ K>i$}҆wE{ ̟pwb* I[f3V?/ix2M~ ab?](`}߽_ Y~1"d|\T1vwώ_څF}4ʬ2' y?=O~[?j@cఴ38zy)~f]9 _Mw{kcoZu+`M˞C=~)7Odzge'e˾ ~j^B HoԽ׎`W0F =M˞)ooE" kwZuʤ`'kgyo'~Ƿbɏ7G>G,> w`__p?:ڃ/#{eݾ7ma~~~ǽl[~}?޿a_;h/]>ݟewTI|`w-%s؟CGPO+ k;n亮QȏEX> ?xn@ykxMmyި7K|0Mͳdo_ƨ!owVF%>{d;v8?f-ǡWL0K8CɞLlO;{Ym{1#=`K;Ds1L}WIodF~>zPt ȋWS/#KƼkWumߠ}ށwH2}>=}kO;!r':'9.s/Kʻn[eSAr{E7jZ=6ޜ7-x={="O<&ۗ'S.P9Y/:'6xNmz/yҞodny_dkDmg_{kVnԣzF)=4lz>싋zN*|"[!dժzEH:ѩtz]oM ԫ4jXO%J|W>p2@$cc׻zOPcD3NB_+}o ]J$qJ=7i<ּ}kW_-~; lڛ zQP?ҏ~g~_WzYktJ)1zHӨE=O2h }?jUԠU3jJͪ15FԀVMa&մZQG嫀B1B=hĔ34(բ9GO.koVG*V:QTj]mMՎU{j_CuՉ:Ug:WՅTWczn҈u ͓|,7TȞ,7II2|0@;azq;LitHr#ͻbiIZkPy;{k;}{`ޛEi-mf\QF/]}8ѻ$41ͻmhMZ3fJcO$j2K>ءj+/c't~}s`Ruh|ud͎?ڋ}pM '8+F;O3k׼|%[/y`3 :ޙsl si(v_>xFR~e g0yEs_| n(h3S]%/}2/N;x,>g<[55sf8p2`Ѽ$cu1H/O.zڻq&B UfmrKqn˽%( Dꅤٹ9RC`v|Oi9fOHo;sa* 1b=b27GzXi?:m&mަڥ=g{?X̪:$mJϖ=CL9-G&_4υ$*юkgu20.`xo/ 0Ǻ&>8ULQhΆ+Z`pĿsaL6Pö'So-9Y{֩.y0^ɢ8F8)ަG Qq8-NxlE<=kۇڙz: x3cugj0pQx1̰s>34Ⱦg{ߛѪh{'cj Y,Vk%Fhhdc}Gc!ʽz^kM~`0yL׬x'<,KЧ[)[`q^uz\]G*:X 1H]1st=VX*Ʊ$\Sw)<#&ab^SMτV0Ȉkڴ9ۥWI1qx9:sFa`ᾸKH]wta1zH%XSU(?d/JjL B[?1τfB.q=GQdH'ms`0Q+ -{fBYpGE9J=h")=:3VHY AhA)Xگ$D }͂p103a="jA_L սj\i3 ΄ 5zy7k1=&ԌP 3E+foiiqZ d8FKzN!%}>:!Ts;y>10r!U~Ag00~¼U*fܢjh^ ?'7S;q~@<菼) Gvp&G:/bCLs=1fJs5\GfR *6 ?yy`ۯy8GX%TD,)I/"\( `ԥQDO>ȗby ^,{BgT#c jVyy}L%YR qIh}_R@tuVǮ;zvXE?c՚cz`pEa&4kR >bL|WUX[B#vhǽ_ۓgyhak6a n`}3?iy; E`znu [L؃+'}Ua7",֡A%FO`\ tA\i4WD~hd:8  !$enk?xI\fռDUmt I)ݍtw4 '[ 09!1 :תHxXKS NU+u9q%.o^^yHWV>y/p֭Gd9h\;ceekNLtۑ~S p@XI ;l9H2Ӽ ^euT@Z 4#}O{?}G J I>(ݙp̫E !9ʾ_YkaY5yb-4 2GL6f@g}Z0{@V|[;^1e{4"-Ffy0K%ƈ<Е< T4A}|(dPZC? ;Cf(19o*8G7ˋ#O.Y^](Hi3{)^Ya0FxR1e&em~(nm))ǗVɚaa@~e˓n-d5'~9v4|iyy*dT!# ϥ? 욊R.KJ×/y00e=gp) oۭ48\Irix.%ǭFy2H'^K˟x#SOƠh9 lnO'A'ˣy ShJEl4y̆G3 G3I1#双êq{)} y4ԩr46/]#>tOuϩB% eTM3m|ֶW 4{ÐtxuԝWAfxv= YJeAf{y'f$c\MKë{_OziFpT+0=88x7[?æ!_dh &gU/o\ o}dG >wމ=N0g*Y[SĒ(ݿԚa<[.oɸ܁uTμHU9bTn+wWAY LG P.Hs*{BT 8E*# (O/զ9!#O:fj#΃zpGҜño>C7m8nC^isBm!K( y^}0QʪBYI겥2=7=;lu,eקGA}_lͻ˳/6c=}rqѲ}=}fy($g+>'zF:>$O=><&,/H˄(F;g "BocBO E^"gyПBuBϺ#Bg ='Fs^| _&F؆}h#dM}i[v/ -Dk=Է%~X a Ch 2-2LuaѦlnja 5zȘ A/1v 0a4 Gdn>tsynnY78Vrz~wJQmbristol-0.60.11/bitmaps/newkeys/0000755000175000017500000000000011471263532013466 500000000000000bristol-0.60.11/bitmaps/newkeys/WhiteHUp.xpm.gz0000755000175000017500000000026211233572002016242 00000000000000fHWhiteHUp.xpmRU*.I,LVHH,RRHK -(ȍUUR22P01P0W0TRRLVKleKqA\Wq@\70qn ⪀ ⪂N`6Yqe 5&8Tk`bristol-0.60.11/bitmaps/newkeys/WhiteDown.xpm.gz0000755000175000017500000000033011233572002016451 00000000000000fHWhiteDown.xpmӿ @+k8#2(s+ "BD! =ERC{yiZع,8Nife|=;tc@PPz.3Ӳ{:  *pGA |@AG3DA:՟Ắ2-Gyº bristol-0.60.11/bitmaps/newkeys/WhiteFDownNSB.xpm.gz0000755000175000017500000000036511233572002017132 00000000000000fHWhiteFDownNSB.xpm; 0Fg+.&XB"8(H)B|/v9Jηs3G1OuJi4[+9؝<7tl"$ jTJ)mWkvV\!%49uAОB2cPĠ>Tj *w)9TV&uߒ'fI&dטd/Iyuk׺$@` bristol-0.60.11/bitmaps/newkeys/WhiteDFDown.xpm.gz0000755000175000017500000000035711233572002016674 00000000000000fHWhiteDFDown.xpm햹 @Ek,cfDQhL)HX{s911W;a(J1%4wڮbI]4]H48 ABi:U"1hr jCڇ95]AM@BeǠ:@"UK%(JfN2ⴇ~'#YؿAc*z~p|"A= jؿNpeE;pcïaN&N*O4" d= >q( q7`o<~QĄ`< bGi|"Ÿ'=)~)pt~{6%O~. /?o X?Hȇ=_z~8t'$eNU1?: tnP)&>?΀Csp% WֿvB|n4)oYP>y7߽OQ|$JCK?wts~{-zR'm4yvHw'AJOz~ *?뭋zC p,Sʏ9_wimW?g-e'w*AT_k #::_11_OM8+4z %$rB+_B_[!;H8|}ON$ O'|Jm_tb_?wL8|#2M/^{Ӱ[Da.ޟ6tޏ ;n8cgp>F=>zohXO# 8;I|H +Cq f_zy<.J_~v 'yXq`6 hX/ۨ#ϯA |]S3wo~yRB_w>_Cϝa| ?ރaf}~[OTO>?u.*۰^ʰ^qSw|i?M׎χz5)1W\_S}ou3%YO眯6p`2#~/!_^8WK|Cן(<u_9aoGw{~(4 ]oZsvVs+YOSi" 8֛,֬ߚ󵄿& ;QCO?p&:g0#QUs}Ss[i]&ο Ũ7>Coީ> BGs=GWY/kkp)_#H?EEL?f=Ja/Ə^_YOم.f}}zv 2#X/wx=?ݤ azm9yLu\~A7knY߻<G|K rgw-5݃Ljv,+ѡ_z?ˏ}7F~ZzpW9n^%g+_&[<ߗ({x ~Y/ /g Є+^j|>m_5>0t}~r|7ON'< y`(f?sOs+)繞8gl[l?p\ܟ+J7ACׯz&jBߒ d}oY d|'o8d= qaoC]'W|<?'w`_Y;< η\dofyt@p>n{G}8pwcC-c. aGwg8u09܄$\ŅIaor?r~o8-a7#Ġ[>x{X/ 4w7s|8?:>ؿ]>7:, >CS7gӔ?vُ9Ϗ|AHޱ-|ggw W2︂VovG׀"aDݰP!N0uooomRE aT\_?lBr +ԗ08Fp= o=b=/ۻ_^_7?t=8-\?_lK8UG7_=x|k<|2羶/Rm x q7/\>Lq9pQtS8*T\%[;9.m=MB|@q>* -P'%ǩ?O|{ %~޿7>9?n9?zI}4з{_p]G<}Rogø_|7b~\#SޟyNnvND|)ӌ N|QL}4 |7ag~3CWqU87p:g#=ZE'%e'=@p> )G>"> ~ZQ ׏@[#ߟ 8r WaIص ò}vW'wГ>WA>p1 ޏB.}$o\}v?ZX!-'ńcbRг_|ĻxbK-F6.6ě#BX$"EARbW}q ő8'T\\Kq%ōw^4*R\vPc}O>dt]5w^?Gqg*sJ׺]qW=la۬әق^$ے~zҬzUuӽC6a?cVUn>;hcv~~ݾmn;`l7dždllvFݵ{d۷vh=+bÞ3{N K{e퍽w>gH'l_/Vm؎/djfg쬝y{aȶh]?]qb$飴RJ%[O 9,䨘$ې엟'._ܒ&ۨMd,Lde!K]'w6ٶFԀVj\m7G-PaUR\TUbOa~;PHuԹPJa6QNݫԳzQORZU:jʱQjN}WjԲZQ?ԪZSq´lKTk &Zídk?+f9)bristol-0.60.11/bitmaps/newkeys/WhiteLDown.xpm.gz0000755000175000017500000000035711233572002016576 00000000000000fHWhiteLDown.xpm] `W<j13JG(ܯf?Vuq&#vV6p:f_^jJaJW_X 4{k/Zoz%o_Min^c[à>igaV8߁i!N :^fڵ,ʘc˒z?U~YW_u$q>SHjGa0 ։;ON:im]C=RckNC}:p= 2u^U;oľa7WOTi =_[t_붻\?\? !ÃU|w}z\h]z%SY%0Oտ <^K \볚S걣xf$_co!,m֩KZ߲N$`:V vZgi*[Z_x>zӺGI#|Vz"ؿu>zz_zP1#뱯vT5\g[~0"ޡ><VO)4"jY\:kpZQr뵊n=WM`{i> 0$ZX='Z jbcbxՖsNWG<>JF2 XsGx Ijd*gqO#{ 0+;J| V</enAew&b>kt LDy_eQzVӉgʳ=\ O$*2\ju<K(%2[^8^e4v=%WUzlq-. K^ \O^Z\CE95 e`- GJ,>Xp(h\ jݹv+Kxz-. $Ҿ,>'7G՟VwB3m9lfM k9ڹE*[o?k KY˭juk[G;?޶M73o]~:0+ǟ 1iϟ^aŘ7 ^!ڵWk QXŞTzޟJ>{J|#tb烚DWhͨEڑ#O% Q^B)$,m/gNa1$ +a-,}vaAQSĎb;TQb?ڱWTe"x^k-JVdy_%|1iWJ.UJj7+~j^?xkPŮޫ{ uK_(勬PXRD~'jmڵzZ/?/Wʧ5=kjB-1>h" ۿW8^ut>$obXFYv5U@;@5w6k5kl?eU_״2oB޿5Xh]W՟%|y笶AoHjRhv\@>f7=2#i]>8n>T)&bяɧXL粶Xi9%c3+oyxl|O㡠_C'~𐯈%xxooo;E NyIs~eLlq_7?Y1}ǒY5YWfJ<Ĺ2an-!Ț\Sqs,9BeeKhxm̸{_C&|i%ϜPfM +6E((-S29ơ{t{"ؼ4pY kbF>8`jto'6oPfM݌yKvo;ԫТX'WN?|E 6_$G.W w_g9J| ~u}t4LLԠ4VpU_5 vG}>BbTXtF4ˢvVXM%y`U' ^kl83?M-ψE-64^W}]Eycߐpiݮ[1Kρy4^uRDQYӾ}K!4t~՝2@Em#ׅIJEy_37—sFW+A ̞y^b#S`5DV(ۨ#cⰫ+G5~Wb-XO#e,χK^՛z=tX>}Xx;xՁzq\kUQrM6FuL}z}eLd8`X>$3}۸a=d| @1x{qb4Q,إ5 E;#s`dNfХ=sn\%eUq +]|Mj].Q/pNf%9|üTҌ̑Ck ̋.֙Jxe1ƛbaFN[5>^qk v%Ϋ99J%YEl tD扵l9ͶV:^]so}f;.`/>Fp"#-T=zf͒ 9׃;{Qz h /=,^ñ&QEp8^Uū0rn[H]4K|,5뼏9j[11Ρb)|+= klzE.~k1!*?K(}l:֦zǧQj Rc(~O8gn=gigl2/vkrzU\?sOk^RqPd#b`el|P5vd/) ;s{85i~jK~,;X,K^h3oɊԗGu OyyFs Ubk+s{ 3i縊 {e{zfNyjh<ۧuAۧh=mQ[VJ+{k@Y38w7%Z62@[9SfvL}qXu@5ݐp|ٻ;Шq>D[%,lkTOW,,:ƈ{L^si[f| 28xel3@uHn㑽p^ρDb 4]Ty:/_x(xR#XDŽh0^ujs.K5^bnKux ѩą+m8Ɲkj.Z,Q`|׫;/^Yw^ެ]u~>&x ^hy@2bk` 5*We7c ؒ<E/[yI?^-j6 \ ֢qXF@y`++6з%ǜXM6~XQlv`sc ^0ey`%?E[s^v{f^'sz`sv TQru+#Wcz^b/cusCnGXy^_'hG[ë^֡úr~pg+>'˭cTv: $Ӣ+|,Y;fȱY؁-%^s|g5jʠ^yeqaYLjEKTdYHS^k`$OΡ{Ix<1U#I ʚ!^6KnhU^O5r1Ythtmb=fhܑVI`-s-3砏<~ q=FP82(/Xz^uf8 v"o0 )E.@vs2=֡aO߈K_lUhN1sz2IJ~28nY-+Pvn>1z:z=s>v0JTIWuHy͂WNV )rc킙`S.6>5m#sƽ^ f(Ǯ{isxSGa]MM8=zye.˩~m&X&.> W+zM4ĖmC<)_{:]gXv6cܿIE6y=7kcǼV7<#O`졇2k78 FN?yN{cj؁1!f~!gy+^'i }Gо7rs?s̵ NV1{ >t?<=KM,ΛCVcSɯ򦜴^@OVX ގC \{U©My`2bristol-0.60.11/bitmaps/newkeys/BlackRDown.xpm.gz0000755000175000017500000000034511233572002016535 00000000000000fHBlackRDown.xpm퓱 0Eg&SV $CLm*7HiA=9%i9K!349h_LOjMc1/H # .DJU q$rI@{1X*ݠ4j׼Kt5UoʽtTyBU7Z[u.mo{jƼ= xM 5C|OsǾߧO@4?71OmJL79/躠/:W2WMozh3Moozh@ouOQzhujuhujuhu´zZz/)GGi%k,ܯՓ<~EW/|I[R3yx~^.p?HgR}'O-loAȠJyI>_-JS[)_F ;z2Oct/yJOq:ky|ӱ6xB|?>~ݒvw|73Com||M/|M+z]z) 'ߠI/ ߢMO|.=zS?~]G1y>ˀ.CO<Kz 7xɆߤ{~s=6C_G~.|瓗s#\1?ϳ{!Ÿq0+TaouV>WJuCa_ \mE(kWa_[h-(֟غ[un-2اs{Kww<%Kky{Tz\-=֒{枻n5k:ޜkh7GfDn*1bristol-0.60.11/bitmaps/newkeys/kbg.xpm.gz0000755000175000017500000000037011233572002015310 00000000000000fHkbg.xpmڱ 0>ťnEh*JqQpġIVܴA|w9!s/y)16Չr"[yeyjngY88d08Etȵ![CvH!=r!{CLC g(-*-qNikNiJK\ JK(9rȑ#G9rȑ#G9rȑ#G9rȑ#G2y4&)#%bristol-0.60.11/bitmaps/newkeys/PedalWUp.xpm.gz0000755000175000017500000001125311233572002016230 00000000000000fHPedalWUp.xpmZV}+đ= 69 `0ۯviw-a 5 ?GN ル۽_;bRopb;ϿBH\@Ak?~>+_/t^O7ZZ <|Ͳ{#DiH?|)??>ݤB<~_EK/UB[yN# ~U iD޿] Ȑ_8߰_œ.zf~yޟn;5#gr@1:>-x}c ,{M{I]|0_g=.Ⱦ΃g k't~ad SΊ4i?k^`I8\p7 ̐__;D8|}ON$O'|p~0=?H8|#&cXr]\2_x|:^ m01γm8ͰeNR!z¿ׁ^|O~^~c|q^'Oo86O bX/[Sϯ|=3\?ǻ ɟ?MOKϏ?b }Xo|=Es~ 7[8 5g=Q}~nzz_"ϿB(~/*Ge|% KӤ||hB2<k|SW1|\ <9볅0/3Up?p gϫuHYe'ʿ ϯ}2zOf~!ܿMkjz%5ix*U <_40D8N<&5/ (G4e|m_SUatPo?_5ww4z{N돂O7xWt=/Ƽ= i:>6p ($o9BBzYa^~^=S$G@?f=Ja/>GW/Ь'm9Z.f}#zv N2SL;_`n<&.}=xЄ^{FsK뷅fi;{DYHQsy?io ~{ooY/b xV䟖'_o>W|iu#i9 xܼOWN/1c}7-¿~{=} {[U_~\r:?߆7>%~pϾ&%>Mwbzv݉eVkv?x>V%Cܟ^}S~^}S"#!y~yvm9xx|Ї;?,Mz~%ccv}ŸI?`%Xϲ~gn Tۖ977zp١ߖ|[/I_9S'?N=|K}F^3C/q#or5Q履(g[rVЃ>{++?,{DwD@8|?%w>?߽_x-_}#[bz ~/oo='<y`ޘz_s'Ŕ \O{γ }-|Y?Z%_נz~WN]~[>Cߒ[d|))E}[2O"o8d= qoA ]'W|< ?[O?>50WnΎ?O.7JE3<: Y8[uő~{|9ܭolH%wE7p~!c7O"$1_ޞ![qd=`%7oߏM`hn7p龘0G/O|Su_{>pvֻ8u0%܄E 7ѓ~߄|y& wtP_>Koo#_(H'݄E:3p_~şJq߂2"-A׿8~¢ʠS:>i(oß3aJy=M)Q.q:1_ߢwK~F|?pO`+HZo7HN};B #z/>w߳Bq?zVLV/ W節q굁nB )o{/#M+GlJ>s}+ԣ_q|/g>COo}A*۟|)7{視gxEocu:zy2ߜֿ8~^Aٟ.q\Ϸ6ɡb ?oǟ?0~| Nq?SOy}Q#?n;/ 2w"ʗ+؋fA?wK_VF-u'Vܟ;ov/y/ttI 9E'=s8T_}=tp}y$뫥X6:/Lߜ_ӺÓ~> :`}9}%_R7o4H{_%a|ߵy%,~n1[35]|m>_7Y/q|j-{> O4x3aR{En¡Z?֓IQoqv^> /|onwqvHvq?9q_qۯ_~yÿ w);xND%sQ#pqc~}֧m஋(߀~,mhd`wR(_Đ#b\L O|W#vŨ{blb[7H"D. 5E ġ8D3q..O]+K\q+~;q/ģC1$_"J^%Z-:˶@|Ĵn9]̋dv(IJXbM6ȶl[b_c6ii=3d&͈fLaoM ۫q]3j̞3fۼ7&2ILLli-0csbN͙[\d4WYܚܛH?<Ŕ2-65_ͭ>mf̬3ͼa̢Y"۲Y1Y7Me]P)ZkZ4=$Fҩ֥׃OWC]dFc_OmtHb}bM:ӹ.tSd;ЇH}?"/޵[FNhI?Ҝ]Jtl_ݚҭMO;یsluη(~˂^Kd[OzEOU[} gZi׵a!Kzc͈SvAgg}%ێݵv1;aٶ͆dllvNi{`vdĞ3{nWŶ?%ٮl`~k{coo{g}ҏdck_li+۲m۱]l총v~c`"ٖ]vͮ i+q#IR*ِ_䐜#r\) ~9(|;rWrlcrBnw&CX&2ɖB6e eБACcPWT(%8/oyNՂrdK^c-{ruI't(t'I^It G֞ bristol-0.60.11/bitmaps/newkeys/BlackUp4.xpm.gz0000755000175000017500000000734311233572002016161 00000000000000fHBlackUp4.xpmZiSI+@RwIA20g03Xa4 l|!1;QэRˬP`m ş|=k>;߹x~nVO?Bq~^gc5;޿Ê)|{^|xe?;v+p|>˥=/=׷K^]삎wQA+C>H;tR舽aIU_+-vbs\sj/|gԎzPvD/%EaK};o_fىWOy#Pm^C/+:_v9.VRD>ZD\qWPlv%*/݊ Z܈kb]>*:|Q4>_ 4+22o:^v3ļ3ڭr+nqV:_h7 %5* #V5iגYjg ifip&k]c_?k]_5k̗ [uF7E[a}KؿZnwt P_[޸Zvk9_ڱ_ vj?U=cq?u=6VL=)^^R}ZT2JeO둥!s6S|Aka&^SV븜oIs☿:ߔXJG3xT S;BӾT |&16Y5*nr|Wz_Uz粎Hk'+}w%|lyӎ<+}<$<<_5Oӳn^k&cn^Ϣ͚9-m8r-UH[`͘ѳ󑶏 8T"7[E[浄QzNo\]sp+gϔp 8ъ[4!ZD"Sƌ6\[Hx&d̑yKY%vgUgmug" -Ook{eޠ_}t6:4ݑv o;<mϿm|v]O g\_p}˜x95ghhjK|7嘚Ci?k:#>B~G`XtJ4[@x T#[|J)mX_A.1^5kl$XM3l7GAX [@x]btܷMԿ>C(Yjy#"zgGgD,EG"*Q>zGsuMj~C7fi J:15#zf<x3u >.-qҜs_y/+kqͼ]1k,hO/ 31Y;k쪙s]$  aDio.Y+=,ڬe.+sj_[`mr5gg͒4={;W{ź&Kōynه&3{c+'|Єe[zM9UWX%aV&C^f%xSرw?oXI,Kf5g c<;9TgC֯up؇U|=܋.@z;d*7O^Θs:Ϋ$S@ 7m!9[%v:[^ ۳;q^xǴxU5vw ~嵊 ^7J>ybU{Ɋd#}3#"}= FtZ8⛑{Oq^Mi=$dLۖ=iwVǜж OEũci.C|,ىMG6 @m3RǴy`i*=`9L>gh'yx 9-0V yb2sG}iL荌k3hGff8@/93Vn ²g rS/k%X)T3}ƟF>'lUtC%+zXeRkU^R<.H{e)rSzFY$cF?2I-;ܯY1z#TWuVYz*Y'^b)WxUZ'yd;W fWVi<õwi^sghN;-!cnկIQye9~&".qwi'O~F?+_ bowa?A<;鿿^$xPۮmvv5uޯcL v }jfJֳ=STʯ]m9rwK~{6lXi7x>;ȡɌkg3T-X;xF^="'v;~|L'W&~ǿp]~`}od%oMh_t:M'#o|~,?{yeKl7Ig_L~)'c'M_y@fx wnsR0?_/o)2bristol-0.60.11/bitmaps/newkeys/ribbonKeys.xpm.gz0000644000175000017500000001155711471263511016670 00000000000000IgLribbonKeys.xpm{ST~o@6`PD\ Eww7pBr{ͯ*E;ìs֚^sL2;n}fO|v~"L=vA;y|yC_!hsE<+3h>/s;?͗d#h^yyO4 r+-~>@rm9CܑB#h<#h'h9C~l2A ů7h';$he<e4?ye0 hAcyN:} AA3&]!h~!ϿJR'h~%~ _|e^!h~A+C|(4_r>-Ҽ"syUG<|_ h*z\4)7y~r|_ oxO/>xѼ& AAev??W?_{(Ө?_?^3}?{S+A_ ~끏xϿ#yn5Z&7+rYa!}rJvtFFkYktүSqo/K~s3aR?!w[sҧ{ 7\|~yo9e[ G$yߢ7o|ׇoC[8o22Mи|W o-?<~OpKC[f.o9_~C oy>{Hp#?r?]EV>}F9N'$&a&XJX?9V9&g 8ZM;ߞ iߞZP;l}oB'j(By*ߞZP;l}o->?N[G(ӂ.hQb ߻>?QՂ屸ѯ\6߻>} n[1q>=?pvb{ q`7AG}֯Z n#Smڂ iC]H#~5w3S؜q{fD b _߂ҽÃ0<ïq: Oa#t9N]4<;jW<^$^Wc{GVZG^7cu#p6a<x0|s[m3\ aV؁#~10? _c{G6Aj[%[:uX*|hS5Č(}JG,A4Ye)|sL[9ߪ`?]ٝa<.hW1-w 7H[Ym-h l}oK-x)ׯBo mӂ_eh_G->ߖP⽨~zG6G ZH![G-h!l}oK-x)ׯBo mB>ῥTCWG6G ZH![G<[񺠭_㿶>忥k.hWw-m}oK-^CWG6G ZH![GR NP"Um? тRG6;5 uЏߖj(^T^ kk#--mo'm:~"㿶>忥k.hWw-m}oK-8YCWG6G ZH![GR P"Um? -vduA[OmoZ U] _[R .P"Um? тRG6R 낶~z _[-h!l篏mooP"rum--}.[x\֯Bs!k#--mB>ῥ\D k#JP^ -翶>ῥsA[_[-h!l篏mo/P"rum--JPN-㿶>忥ߎwA[ OmB>ῥܨD k#--mo#\֯Cq?k#[[UCU] _[-h!l}oK?p.hס--] wA[ kk#--moP"Um? тRG6G ZH![G-h!l}oK-]CWG6G ZH![G-h!l}or~ тRG6Ԃk(By*߆hA )` #--mB>?ZB 9?߆+\֯C￲m}o\ ZH!~ -`)ׯBo mB>?ZB 9?߆hA )` #--mB>?ZB 9?߆hA )` #--mB>?ZB 9?߆hA )` #--mB>?ZB 9?߆hA )` #2WG6G ZH![GJ ~n49\J3*t߆VZp*q_M w!m)W>G6Ԃwp8=WG6тrGg|SS񤠥_x_[F x^@_;A8񧠥_x_[GWg#}2:NXq ~Wnok#[۸.|zELę8=&и꿶>^  q! Kq)^HcDby8OGhw}ok >.΅p=A>X||r\wWQZ@#jM/^jzAGXLSKN֯hw*yu[Ư[q6Ե_r ,w}_^-hM[[}-т>SGhA)` |#r?Zg 9-3lo}B>G L![[}-т>SGhA)` |#r?Zg 9-3lo}B>G L![[}-т>SGhA)` |#r?Zg 9-3lo}B>G L![[}-т>SGhA)` |#r?Zg 9-3lo}B>G L![[}-т>SGhA)` |#r?Zg 9-3lo}B>G L![[}-т>SGhA)` |#r?Zg 9-3lo}B>G L![[}-т>SGhA)` |#r?Zg 9-3lo}B>G L![[}-т>SGhA)` |#r ka#\ :c* JZѿ/E_Py]׿ǫSٻ`I[[_M-W݂[a!5v:ka/c7^`.݂v[J_y<ȿr۩Ry nggKȿ45ݍC[V\ [[k_3gf -n,;B/]ւgJ)%?4_Z1^GZo-]G[p6 b?'n:h gËf\+;vkZFH=SwVIW} UI }_Z'5FjC[p!LG^bI]+p.<ߗ^lu FG[(NG[p")ǯq|xvXiĒȿ>}陰xH R^/̻,C;!-Da[@S"ނ?ޔ7}_]\rc8p?L0bristol-0.60.11/bitmaps/newkeys/BlackRUp.xpm.gz0000755000175000017500000000035111233572002016207 00000000000000fHBlackRUp.xpmA AWiSfiCRRJC睴R4A;(6z v$_ MBD=_4DWqԘYjQj[q%Uw8"FTefPqT^׮sJeB,sz2Y]kccπw.?̫^E7|_}CzU8.cM(nbristol-0.60.11/bitmaps/newkeys/WhiteDFUp.xpm.gz0000755000175000017500000000033711233572002016347 00000000000000fHWhiteDFUp.xpm햱 0Eg(Vĭ . "m4 4~s3eK.xI]*R&yOgSy?Uz\o%sIa{𒉢BbTAfДPaP # Z@wVAlѬ gJm8er NڂSa%ӧK%\r%\dcRو/3^ bristol-0.60.11/bitmaps/newkeys/WhiteLUp.xpm.gz0000755000175000017500000000033011233572002016242 00000000000000fHWhiteLUp.xpm햱 0EgVM7Q&mBz_Ǵ\23e|ILD=ڼ-Y)r{hvЊ^*jJoAi4QQ>4i jsA-t1h5 ::àt1guop܋ew½ :H.]tҥK>tܫ= bristol-0.60.11/bitmaps/newkeys/WhiteFRDown.xpm.gz0000755000175000017500000000032411233572002016704 00000000000000fHWhiteFRDown.xpm= 0@g+4]ISD qQ)V w{~@A{G 'a5ء<$ aU.&屈Nzc833g>2fe]w78 XP!78u`pP]lzxו~ᓮũBPN:uS~ ~+>r bristol-0.60.11/bitmaps/newkeys/WhiteHLDown.xpm.gz0000755000175000017500000000036311233572002016703 00000000000000fHWhiteHLDown.xpm PE5 *D,J(LK8k#ܵFO]r>%QNy[H Ǔn.jM]5!gW4 w6RB[жĠEhO5} PbPGV# ~rg7xq7S$z)IIj wܹsΝ;ywfNϾWی~hw96Iw bristol-0.60.11/bitmaps/newkeys/BlackFUp.xpm.gz0000755000175000017500000000043511233572002016176 00000000000000fHBlackFUp.xpmMK@EW\YS+!ѝFDJ2dD]7UyPs!L3)q{ro͓ J\4y~^|_q,YT#L,75u&P %GmD-Gm':Kj+PWTWqTO8jG5z \ch.z1-ژi*RT)VU PwB]-B*BQTw>HE*R' ha{vX}G :˾JN bristol-0.60.11/bitmaps/newkeys/WhiteHFUp.xpm.gz0000755000175000017500000000045611233572002016355 00000000000000fHWhiteHFUp.xpmKPxn:q|ɘѥ!CC%C e .ѥ2xϻځ:?UAy*'Plu9ӓbqQZ:nW__uq^g/ mzMC0b4Ch_3f4cf40c(fh =24Acmk֍f mZACWF ?U5_ z Do%K7>vmvo;myۘ^W7/ }Ӗ bristol-0.60.11/bitmaps/newkeys/BlackUp3.xpm.gz0000755000175000017500000000752411233572002016161 00000000000000fHBlackUp3.xpmZiSW4Ӗdm6K5@̐$p,=W\5UeK[}ӷolwBoߏ룯futxC{߬oJq}߸^l{VRwJMծϛij9?.UK3jس]b/h{W^B?KC7,ja^_ȯ@۩:=+~)RԃjAbwiGq-S;@fD+j'߼ڑSv!mUCxNjmq5ǬRRD˔O-~.jT-WC=jVf}IV-_U՚ms=ʿE_; )@ǻ~Q^HrL~ǴkZFV/?]KpZq'ޯukmm85Wp<ߩp^q[.}p_ yg'*nx A>_o\yVC/pJ6&v+nU[lvjWk4C/tGrQU5iגYjg=߆ihfi6MR;cw?A_5kM[uF VQXZnw {Go\{Z@~>?VȯkS_/ vj?U=^cϴ}}8?NA9b5JXfUv-E5HCyuw6k-9il?cU_׬!2oUk!~&_Sgqߚ`2 ھھ)=0>G>fI{d$U;BW;>8|iESv.ϧk8v#h=S㹢7Rډv<_Rj} =2<#Rxu<+)[[͚^)4u3mnϡ̘Y-, F'fiX6kR8q~Lk{r- T"|7跂ct0\n헹;Ab~F)yU8Q,%o"XѣM81 Y"¼!g-u }ѽ8=y7ws ٽ6oQ>:Cb@9w=mm||BX_86q[sjPQ icji@Y;Qҵ'[ o>-RS ^Rto.)<}`}T R^f3j~9ق?Zzq܆r7(wmce&GLRrγgMWQ;cqtR4z/2@E`n ׹IKEGw"5N@dC}6{X)g#Savfz݅„b鹃z -?0&zz} T^W}!"ވջc^ pk3V VsV6^gCqa=8.5]Xª(BK=^c:0&rq|K*=ƀ^9e2Qv<ܽĸ?Mb4U,>e5 C;%3`dNgE{$\'u׃jr>7O{t_zZW u%9Kr "j |ͼ<=+Uoeճ|u/uAZuFFkkQelY wv 11 SkOźc&NtCO83yԦXgθgrps5J{XgPJ>ꋈcCBXk9!;gc>Kr8"}l%[5nHwYH͑ҽڟqN=N^FZ9;R"8>1ktLC9UMiU^۷H;̅ZrD EarHuIt=p.ekqZOe䵁_;=wuX}:|9n+gup';cltpuE^Y'5 ǯy^r!,yubjס};Aܫg< #^͋L畳]`&y=b-W%hZwE2剳 xaCgPx9֎u^'f:qX3PڀW@*~|wI^YX]QsjgE2^5:&xRt/$%Zc:'G}ȈV[kXqq/rh}@fgŲ!^O>^KhĖ!X-;8zY85W%֢IX]F@eh+(6ѷ%ǢXͮ6~XQ,?4E>!I/+CsHڧ{c.Kn#L_2^ cѮa^rN.ڋ*(a%+C%W6߽>D{c.b7pgȫ=W\v}*=mK.?+T~yʶLدVHI"lѴdm> y:ĸַlVnMqz]ȡ^ypfɔ&%KTo%1X/G51 yshk>0OiyOp}+|۶zf9oW4-x~K=צX 3[qH[78.|5ClmmekX+\i+y#2_ev9ԅbm兙h?@/0 9ŠWuw ݜ̡juhNo% w_l5QdznVG~׸zu)ʲ)Ңycg}z񷴬qn3c7yis9xřʱ.&&\7;8n7h>>?'>JM!+NQ eWxO3+-Ʒd b;d\VYxLj-1\yZS(зM<֋vMa=%Vָ?2-"-hh YGysg=T-XQ?aajwoqצk`Vr^5z_ٷD ;Z)׷O=NI*;#xƒg{|/7_;o>IgP97ǤDhoݍ$h^޹qrP0?D^2bristol-0.60.11/bitmaps/newkeys/BlackFDown.xpm.gz0000755000175000017500000000042411233572002016517 00000000000000fHBlackFDown.xpmj@EWns̮aR'UUfxP * BG DSǠt0ck70Ν;wܹs/z_ͫ?4M bristol-0.60.11/bitmaps/newkeys/WhiteNHDown.xpm.gz0000755000175000017500000000031411233572002016701 00000000000000^IWhiteNHDown.xpm @s?a"a).EF ѻlP:;z%I]JL6Y^EX^t);ECE.IhU)^} eH 85-p棠 > :\4P0# Wkaَ {{g^wcž%]bristol-0.60.11/bitmaps/newkeys/WhiteHFDown.xpm.gz0000755000175000017500000000037511233572002016700 00000000000000fHWhiteHFDown.xpm @EZ-~*D~6E jF ѻ睌Jems7xHje_/$hD`qmgsrluI5Q,&| J|PԻ-hSb<-1h@n hA]h_bвVAK>c=뉗;^Ltq#]͛^Ý;wܹ'p=E潚y&|Ǹm/ bristol-0.60.11/bitmaps/newkeys/WhiteNHFUp.xpm.gz0000755000175000017500000000033711233572002016471 00000000000000= P9?Ńū !!DP[DHTC%D=ύhPh8AAOr1Y"-d,JCa?'ZK,7A˖F&q^h3d9#fH煟DN429!]SR!fih㜷ξ˶rXUmm\mcVއ -tbristol-0.60.11/bitmaps/newkeys/WhiteNHLUp.xpm.gz0000755000175000017500000000034511233572002016476 00000000000000aIWhiteNHLUp.xpmQ PkoDjˍ(Ik](Opv#y^j.VJIVwQ+U,W,/rܑ$]suGU7ܹs۝6ou$n bristol-0.60.11/bitmaps/newkeys/hkbg.xpm.gz0000755000175000017500000000046611233572002015466 00000000000000fHhkbg.xpmMKQu)f|wPFmvE@Dl\ws!pm,CݍA_i֫Y<<-?B*Lљ'VK'5rLJuC|Z YXYXpCWc8d! #"/Sm \步ZUsu;Q-*ZT5rȑ#G9rȑ#G9rȑ#G9rȑ#Gqy"s]?-,*oi[&bristol-0.60.11/bitmaps/newkeys/BlackUp.xpm.gz0000755000175000017500000001002011233572002016057 00000000000000fHBlackUp.xpmZS9ۿB^ <3RL8K 8 o^3RmIOZ-´yך.qcǎ}7Ӧe_͂bdRA1bX1ƊWl=vxv)*KcjCYm_.֊j'4Ğ @;lG#?*Fsj(*DKfi{5/|sj<#)/|3jFXV0ÒWrGm;oGVًW?jЫ{OzYR/:_HGs>uv/_Ԏh7fI>ߕoQkiQ?݊ZvܮBVfKl6A/&磦a+hѮYlg#ߦijVkr-V i?"ު3^n7:]uQ}U~Mkk9s?/D $wo|ZD~`Z_TڵRCڿ6QZmcЋm*1+GvUk83a=SE0Y勈xYȶ[]^g zc?`M!s6BxmY|:i:^KF`V;(VJO3ǿr߶eC] :~ůl?i|5_*~LXo9%c3%Z7 M 8t͚Y)5E3f_gQz˴ɂ\s扙u%Sf{9 N5z);nc[`'.ƭC/='<,{}J}&h773D`J &Q |-eİbSƈe*3{t+ Mw=.kdSU mbs2Ior#OW=EMg1'+vc}sq>?93((wK$.ej=gewM/ X`*{/HJ |!zHgDYNBK5}VRx2OR#7KzfVܕ3ޏ2|ɞgD" q^F{Qx{_Ü-cCRnM@Y(ӳ]=0ρګN(3K<=c2qGaV5D jqwy- kګ=z}cLd8`UX$}۸zz8oGuqb4Q,)إ5E;#s`MdxK{$ܺXM;sk˪uWs]պ]^x-N>^tZ3|/ uj%NV9:ɯ-`m+<.|V@5˭}s>*avʈ;tXiymK|LXi }`_{ښPm/ أ ֙Jxb}a}@ox촗ԤkqF^nj3н^]l|έG`H(kqYq8tλXl ^'_xI.1w굂 I_~+cKjXi9z^%ڷKkykMXcEp8z^WЫ|Wih^qΈtErj^SM{XYkpL9s(XwgWalzE.~+ǘ'5^|zKaXvmǭC5l_@רYHgǵ?)qܳҚ;s^o5 N9\kڧcTj>K=/}J3tc^; }h͵x>#llyװrD ]Z6s\);^跋fm P>א3V~>}a>3ozۇ~N0GtgJLh3UFjj퀟dMS'n= tY lom1Xװ}(zcCALz<1~Ϊ'4΅sڌ%Y$gCcQ5ǀiXWM# lkL3%e[SYC q`&|78Qr h@ž=1m/9,VXaCϐE3O<&ϳoZƀ5l_egJe3@^< /I"s.b]i0%j>碻]g@zD6 /v<22V~!WTF mscy0^2]_Q Ky5-F[Sͣ6'X#Cda'~94p94!V%wW؇>^υ'Y(l"+wk OV1>?.Xm??<DAIcW]D;6wJ{+[sh{pP4g2bristol-0.60.11/bitmaps/newkeys/WhiteRUp.xpm.gz0000755000175000017500000000023111233572002016250 00000000000000fHWhiteRUp.xpmRU*.I,LVHH,RR,I -(ȍUUR22P01P0U0TRRLVKle0qA\CSq@\#sqA\vPF``1R5))Abristol-0.60.11/bitmaps/newkeys/PedalBUp.xpm.gz0000755000175000017500000000360311233572002016203 00000000000000fHPedalBUp.xpmEWiSKPLϵ ;{7(@.7 r]YDdOOYٳ3uM<_q&i`Z]^mn<={JSϞGUҊm&YKKz/ γpq L{^|>xx3N<I$O $s^ʷ)ē26"o{or(8隿;{oyϞo V#w|i޳,~4Uě_?ÿ7Mpa'گZ:p껾q{g8 VŗnY=s_:@Ҹ">vnڏ$د’VSf,9w?Ox.i_ZK+~^ \|*"Z߃z7#Y<_gJԧOKqe4_‡S.=wKgWį,SŗbZ|uWGۼCd>mŠxuo50D?V-ǚlu޾(X7,?7CX=`V>k4{pNx/s~EucxoVk@"xxo%kU3>4__jK~uzu~owҞp~U/+/x>̻a}o+?Ytߚ \6~Гy#p+f,mB=ϡVO0ڄug Gmo79Ϳ}v:O[tGpͩ6༞gg8mTp̊LO:Ճ&1Tϵ?O5\x WS o 8;BpQi!Vx_ytO~޹)?v8 z0\w{g~+~_b;L- |ɜINY_8Oy)~/z>~ы~=G};ߏ{_To{|*g_i=ޠoO̼Bu0%O{~v2)uiޝQ}K\;9wstܡ;rܳbristol-0.60.11/bitmaps/newkeys/tkbg.xpm.gz0000755000175000017500000000031411233572002015472 00000000000000!iItkbg.xpm̱ PukPHC[DDIVDDG|n?_j906jWsOR^~]od"oIVx]I'ŭ<߫L3ҴB3Ӝ65GVO3L^C9[9Zr%bristol-0.60.11/bitmaps/newkeys/WhiteHDown.xpm.gz0000755000175000017500000000034711233572002016571 00000000000000fHWhiteHDown.xpmA AW|9̊!e&BJҶ[wJ=s03&i2Y<1ūhKQd"I3b:ZvCQSQreS)Q.1W/LPvM@( +( (PC  5=\e 7zk a'n΁;v{?ɯz-W)_!# w}'Wyg 5}/>0>4>DH|qEMWLjw#>z%;:,;pn|WY xRK|I>?4IJw eXҟ7}2?`F[W|7#G,0&ճN-$Sk"n[>M__/釮| 6=K4KgWį,aSbW, Z~{cFkd>ڼBia${`h(?s Úg_7~xΧ&~h3<5EyK?y 0kk=G̿`Ϳx7q~#^'.o2,9$|&QO<:z+Bo>-sPu>xײַ.Sw~I=>K߰25_'q^Y.0p[ ΚYymAzrO? \|H Aڅo8;JpQi!g=K}=NO3nj>gG:yO9G~;~a~ cNCu}3|=9SrH4D4)h&ii遶h[ivh )r*Ԥh_萎+}c:SN?d"^Ok_KwtO6u+=zA/i^2ZL`Q?F?f%b|?8^E 7iyq_$hxxyo41>9^/ܤ_[8K~xt+c>S?Y|O'_u`_|wa%nmpxr/X`0/+^׼«:=Cxs˼ܰqnMY&xaFy G\v1fz4i͹f[Y*bristol-0.60.11/bitmaps/newkeys/nkbg.xpm.gz0000755000175000017500000000031311233572002015463 00000000000000S]Inkbg.xpm1 @F=ŐJl "BS,AT(Bnfs|4/e^JWS6JsX?n۝c|$XoUG.4MۮBsjNf[=GZqu\k "ە%bristol-0.60.11/bitmaps/newkeys/WhiteHLUp.xpm.gz0000755000175000017500000000036411233572002016361 00000000000000fHWhiteHLUp.xpm햹 @EkĤLD0"qBFD$.h Aw/$Vb%0礙r69uProh}8ftvG=-)P`,* -.5AЮƠt@aA](Ġt1b`:au;V| ߿ wׄgwe@tҥK.]{旼K{;g}[_=  bristol-0.60.11/bitmaps/textures/0000755000175000017500000000000011233572001013652 500000000000000bristol-0.60.11/bitmaps/textures/granular.xpm.gz0000755000175000017500000047210111233572001016562 00000000000000fHgranular.xpm{[Sۯ"l@ICN^b@Dc4¯^ `G29 _FUU5Ɯz5 gƓʻTƞ{?U>}U*>^u~خ,V~]L7'*3_R}ߝpDp?=~jbib9D6~fEV5#y6Yk1&-5'}lZmyjk/߿>~L7|OI?~bm5󽘢'z;ʯ'Sp?} x55??}w|ܿ }/L>gSSi{?>f&],lg1C?,OMLo__꿟_}?53M'g_'+S|72g?TwH?{?Q?>5;M?W{Og|i}|~]|>)צ3=]?Susqfb ~}:}K|uCVp:>5oc,_o |_}'W{)K?^i͟o迟13}O33ՠ[`.}̼s]~3 A j?9O^>}/5_mǿ'OcK]~Yi}%O'z>>?Xz~f>3~sk}IG|Tjd~t?|f=TO_c+o~ ?tz?czfrm' ?՘hZ}foMFO=|Ͽ4Ks|߬f/7Y?^玿̣[~}}MY&ן73_oQow?V_3yg:ZDo>Ӡo?dEo_mNߓ>}f>7YdsvӳF>B}!G~V>N?-^ǿj.͙%wʿVμ|~3~?~9 >/m5׿oWKX [{?K|3]x?}~l{'J3?K}7S[l"~߯Qk_˳?cV&_o{]>w)n |e6C?sſ俿C֖履 ~bſ]My1g'3>' eui_̘hp&?<~%t~ȟEKקij?s=GO>h1y>~%{o?~_n_4R_7}hOt\n,_9gyv9};~R޷/ʹ-'4 =-__ ߣ7^oNYzO>_~OKKS-7}{^&+7W{1t>yI_+>?߿7~gu|JL}f[|ﷆ\~KHJ_ǯ>?%f[f-2}?tW/O[t_L/XϿ/?-m9g9>dz:#׷yo==!9$y_ZWzg:^9J]U{\^-:}6+tMr>]忺ޫdѭG{,٦+=lwr|xw9yA{E=mH6LG 3۲-; NϿF2~p|fOyf8gJ1q:UAB¸OO=OT㝟MNv'bډjkZ##g{¥qﲿ lr4 þI+܁`q;3oPr;9M!+e!o)Ot0 Hoyd*>]}t  SxT³EyVot }aN 6(gJu.B2>3rn+"|RB8JRBLݴݓR$^ ~H߇SܩS¶H]r/J(wR]/ϮxL7^1p8_So |'uG>So'&mQU.ǝk|fA 2S&]&5Q}G#]x׿T`Ё(ZАCh3j#+op VNA*0׫w8X{Si7+LXz-Jpto^?QߞSyrЮNe=trk)鎢^uH^}W !%VD.yW z3v6l[6~>~{3 A Was;o11(}XH8-$UwU;RG ە?h(q@B&2 ЇEÿ})3pvA|Ӹk7N0Jق8X(ޔ|> ?9Dͩ}̾ݯi+K׈voaܔ\`H4'fNKGS&\w4Ro;EJpCm_Q4bj¯@g;ll"8xR<2~a~:*,b!:X: "GLH>sxa$͗x+'`g}x~Q$eG4 \ -'agGD0OG:ТcQh ë%hO}4ċ|ސh@AD#3,6 :=wsxOT+AJS0.^|X {zr0Jlܟ:&"E$GKYFT 2پ %Z Z0/02A"n+8 >Fp"a\jR`)FU'H΅!+Hl빭,l+rj2od_2Oєc! w4jk&8%52!|⪋j0&#Q|d _E] Wh (,߻i'N WzLݏyID_|b{pe3XoY%cꭉV`& 0x$ $PQ=V- {m3|a 3ՃkDNb&?VD@G"N 2Z5Ĉ$eD pGɸrQ>ʘFcJ΃+_Epv>ڥ2Wಌ`)k@ϸ"}7{Hr{(j_V>LϢ@=>G㝷kt3"7|FBА?Jn9ז D=zc>qgP3;H"Nٻ31 sGB n4ywߓP92 +Iu:^'ƺ3qDqAvr̕wN nJDWpf)KUGIL|U rp( l'Zв%߷=&">ݻ$cNjfԮOl43t^!W'9;B⋫a uXλ `ߌDF4Gu^b)&kI%t{v%[znU~g5~qЃ?P#_*jӄ 01pEI\l`¶ Y r,='9 ,3GzDJ |'¹'º~E%Yx*ǠE!`s~~@kzI,'~(Oܻ_uC9@Z|+gS{oEi?Ljt;#\\d>ǚL We׀^ }umH\.m/#-x'p(F'6-~ɤd%:n&GkQՌQ/,DtD^ЪG]%cnƪ;A Z` `LU?醋'CqpQWtg ZlDC/3ϔi_(SawA̞pZ+a`.R(&^xg]/{/*Ķ}7ns@P=Vۑo=-xx> 97y^7\+uHf<@lߕ}=uH:h88_ G ? ~ZhQ2 GeV/$& O2|-su"[vFu?i}!`K9x?GipaJ?;Ss$Wز\#K5ݽ޽׮~׉ 3Fi4dEh[\si6wycZ 8zp.O+_:𤓨QgFG hϯ$#Z5"Dv->Rq컖.stS*e\/y_ӂx^FZl?{gq 1 z2Z?uz)38?; r|l{)ш?:>.JA3h,T: D~I!MUoxߙ&F}c `7QT <ֽ!"X L1NkXE%k Yܢ+4ak /G@tpey wDu4^BDNt?Jף(A`GW ҃ky23eSe )44*UM"He>qJAS6m1tFÏ A>X"k3sF_ v!׀}L< vyW9ؕ ,ջ1]wNgq51%÷L c-R/[lGbWNws"?e1NN~x JSmЂ\ms!P-vHIߺ2_/9h;JBBf`MHP؎L2$\/(y88c.~toTg)# ,L idK)k*,_e`ҙ0m;.֋7T`WT 7ăq{QUt}G@Ӂjc/ZIk3 o?;rWv!ҁ۪S~巣Gyf[Ig5/N!`<*fUl6U:0\m\uS75/VxIH$wՂR|pMS?x$;}fMHHJIנF+q,}ƋN|$D-~T)ݓ) 3}zzV)rU`uGA_#+>Hy5c)ׄ)\+`j{`kRD=\Y5̕*+k9"w-x^t` ޲2we߲jF\!։d-FOFdV7#*pO3]]^ܼŠoxO;_M?,4:|~>-1-ު d">ʖP;vDm:PVc@T`~`xQ1]DB7ۏxTBEp01cbs7+\%jQwR3埯qM zB%UwCBp(),wGTy3H ZvL FA3 55XOtCq𓄊_XVUIgp>ڍc` #ޓ soOr<.a_z]s4R[U>VW2R9@VRw%ܭ/\['}xgz-~"IT=cY q+S*>;sE3v0tBgSK#< AZ+#Q|_iC]M3kS-hȘaWl4Wc &oE'*0SOf{AI=` @z֙/b0ߌҐgjc8MO|`߾ê |uP~Lp\vʯ~y#mӃytʼlGV2ĻMǻ)A{+v|$tLg>έԻ_@CJSg kg4 w%+m:-v1q(xiBi1d2US>p7$ r|s$m>A &ݳJ{n3E{)c_`Z +VRUB0 &?՞r,|*kG7Eh1ׄ-UW ߫cT_#tY!O,`#g bˉlh=Г? ;yn 4=ҸwR`$-ѭ*@s|/u5k 7s{NNI$d߅U2ҫܠ62O!oog'1銝WtHG=VOD! UK+B[ VA]u1?#YZ?IΒ >Ě.N|.B<x&9!8EDuZDH[ ̞W wq?lfP,{~L>Vʼʾdݑ0&"z^q?l*v{;{?ՁD4!wQEY&udo qp4nR4 \ӧܱT\ W |=% 8xx!>FnXpNDƦ =U}DUϪSu0B8bB ξoOו3xU3^ ވ`WB+}a͟it|~cǾ 9G ߀p+S>u-..Vz98_Wt3q\xk l)XE*}<Q0+?*\}tBC?(@ި F^9W{LIW<) " o5\8lgwFrLAѼ)A*$6n;^ ׄL>N>ƽ>HЫX.L=}h8JDpA">H dwAB2zMoH}+ӻ涠kzI5LjywW-Yd&M3P:m*$G(KxUR7\g}Mx H"rzͺI|/;#^ܧ.HYWȯ};ޓvpq f6!A?ck!!kUoD Vgk?O>;B8DN}!I|#yO3t{{L;^aE먐kTChQo mE}zuV(@϶oI[JU[c` 4u7 nPV0f6Y5هj3}R1\ TNc2!%ZT~%OjGIX+3%F`WZu|3௩2uOwςk96!̼t]Uz<v{p$gkǿ0%j+\_& L>dq O7PwFw~T޹DD3ykľ@92@ S';<]uP¨nnlM}or) c,H4gVs<ҺiWݨZ?̼Vf,Sx#7@% {_HX ~ex%4;Qd'*NEw*?Jh@,H\Z8ᯫc<|lo6x{d}=P~Sn>aݍy{pk!aLf.h8Я9|7H{8(YTa`^ߔķFQz?%']rC7Qks 4֞D ]o B*@f`E-w$;xhϿ)Y ~ӏ}V5eۢZ ] r W =L 98$sB?FHx#wިqZt @^s ᄫ3\ֲh0`Jńp]rEŞy 0Ց~AKf\'[Hf3K_x o\,x/n#ѯHw <8GDR k\!<Up>)p>8JwgD҂\QU8xOeLYxAc Vw_{z^7"hup}6(-Nfg⑬W'yyBDKsҖxIgڔxzd -6"9,4x"jW368wTV? Ok3,RE!GwILe0dmxAV3œt\zU׷K܃~M)?y|d8 f )n]A!Ṫ[t|YsyΟqg3NB \$}4xN^1/$gn!x!q{[7s]ԫb HGjޑ^I"ޭ}.^]!g06hcjjAl *lFkʽ!ߍ}MӅFBnccab3}L<oǩAOªM,VP[u_-|ů=g>IZ39 ,S lՀmMnq$|7ON?zߚ@Mrk8q , Oq{ggrT;ΈsyeN9QG8v=45#Up~Qs73 [Qr+ <%S]Ŧ9VE }N(og b%:bmDqq;҂eu""ƽh+o$6j¯CvL ٳՄI3]hqZBBLAw#USfl "+FSR>OB?·=[1_?hF/ / fa_x;F(o?)moE! >wY@V} StYקM=ik3a)"`|Q x!+q E+4÷r/֓д " 0՞8+Ju2pS@ԡga;ÓW57IPp+b"hC@HvZC .Rw;Q18epRu~p!;v|v,S_w?Sh7iJh?4`X.0h>-p OO灌ꆌ PY@r\ggayU~*bځt."F{ށv"|ݯM+BC2&JкK Cd:HN bw^ G cUbYn!kN\=DljM ՄVAxXשXxZXh:p.9XԂMGS$CCNЫX oT``,8_y&u½?ǻMAy$hOՁj Zp(b~  `7S¶B3b߭^䟑dhxϊsݙָ @=(!;FoW4th Wh]Ew-yIٓD/n&Zn5RU!RF*VP9ȮĦ9K˳ЂXKr**B o\,36cUG``V9:րV+3)P+z$^#b_;83.&~D6hPn\S^p~A[8F:ړgr@vx ?oJp%!t=F(wFA6jk`|H#GnTYޏ.B=:WDS&焂gʶ)bי&HWžxe!8_B8h5/+ n[q9@n)D{V/7 [LG ^mI kZbvJXnܐ%=ޔnT v1;77,Bua1Cxx=h+7sﮐs#bV^nQlGFFŦT ƎpO>O*mW 㕒4`Y\|YV1ݗa'{]^8."?5#ga{S3pT چ'̽l `9WuZWJB> ׉k3Hh;JH_yMz ]xRuIq 9=քn+{t^זݱ<*jSA6_yh#˙~! 0!L4mH g c⁜ϫ¹V{8vh‡8h5_+sl|Ⱦ#ͨVZ0)9%Uc5E|GB8Tq{T`JSY%Vgg{Û_Ihwl^VZǼ?Hӏk`0gnw ܧAgPsc{R\+HSGϘxwkz2͜+Mqpſߜ["e_56>ʭbxҨl X rwp#AДFꨱ&HkUт&sL|EAƩØYF6=ƘߨMk?󂓢CTCW; Jbf bdG:pOHƞ8s0&}*0 q?p ߧb {sHU>^WxgTB;>&KߟJH9[T-7"C6w̽po \:?| _b%x& wMm?ރG_ϔugW+z {wF?or~1r)}ay/|&J3{s9]er v_xqpCFoV+ߺ{rfU QSszbHȓ ]D ȤܕžVzIcZ7PpPf)M ZL<$,R~O *8}X?f\;7[NV*v$F(5:̽3.o2~Cẃ+g'sn11_i['6^ %k 1 w xЂBELr1.h.qWܑ]u5 VI "dQ͌uѡvfC ֚xy#чf7^WЉT|,_+u\BVG{8B9qH e.I&Q/u>S؆t󞱏@G&ߎpw#1pCT`|;sg+tcpgLZ(w$^1E %eVH +[+SEATݣlhp5I\תUّnuJRXƾ-_qS/OU}]1 ~Q_~ѨwXb`O}wn9"a8H\u`Ju}8j9xM4c~Z 5h3V~ V QD ޮ~DS.QBU|\ ׻v\w#NbᲨ$=<ᑣa';[j?W% )%᪙]5$c T஬黏wUׅ kL4J7Jc"; JVxZeApD T3W+^T d ôDʧ)xޯ~U S}MCp*"bFH~`T?<US:_}Q?U~L}' ߱ (vX P&F"2x&-`Vgו~~=ί[jw$[Q..+r>0su^*B.E8e:7JK/I[MzGRSv!1ΑOB'SBnHYB;\_T\wp]8%kGzꪭQ1kw"N+L@~0J~9Zvp( $ b[~00ǟ^ ,F>׀ʾv`< ǿЭy!D{|)3ɱhp<;@ĿR~?_pT;WY6OZu=k҉+ĵ_Y5"Wz:$"nyKs~̮ݼT)؋"K "&*\;Ok./,Xx[s$փ{.SikٽS(hq1;vǯ$+qׄGQnHt?"iq#ωGSMQЂ| ld58xX8hnfQ@|ѯ8 H8CKm H\`}=|]Su!8_*oǴcߢϹ㄂n4MiFp5j2=x(+օy+B +{:Q+.3֩]YĿ}Wsv?zuᮥc5&nQJ>nR9IJsR=XMZׅ7~W,MY3B Ƭu1miW 8UJ5NJj'kѱ11S`i9DJI+u^fQUN2,F6gXHadSHyELlsUA.3ijc2( <k,|*0D; xWL;뎃X>'=ލeddkLާu#stSjRn=8Ѓ++gEHMΗ*0{E%1o4  {NU2>*y65kJ@G5$ |#wTs!$wdLJDkk8:FpKt`[T!Greyew{G}b N& NkF1Whx1R R?Vff8XsӕWغ +09$? uA# :s?;$}! .8?gzT1hh ,ef:Ŀ>}N\cVɠp\?޺00&< :_['MN\ V~Wt.ʥ~u"xi+o?j2iNoK)xMG&]KV&갗cEPM9O٪f:CwA$4 B)P9&9DPONxhhZ w]Ul <%YԠy$1#4T5$Ӫ\GxEzɢd!A_ݰă!H j72-h 3D}|} M4[Bs6u_! LN;7o||t GFAT:uG :u[@~.f,[&:aY"#bK!ܕ~ԏϰzV-稈R-kz8Z }GqO}h5E6WQp\I0浥lu礚&P0 _T;ULwj<$1)x$"uJ֔G T2YS1\I~ X pP)8(0`L /|_E7-]UY ;$7+Cc"r|MTv9h\UXf6W.oHW韙x=2 e쒎˹W{٪ܐ@K-ՀQL=Q[Ym9$c`GӸjR4v^}tA44dN;ч4nJkyn+]G+Vr0ք v]Š` "~$@l"/W@Ƶ- L%᫟¿.?h\`GOy!W0MfH=}qCϴ o3ɕ 7qVoe*\|U1_y錄}qq8~(xSBC",uGe`|njg[25 (3qᮒPy[Uշ*GD9mZs>nK8%W-U|7mRF݋fm{I"c 6uCWt%.[}tp彈T)?Xuֵw\dGЄyi.u9HP%MjMp: ~@sIX Wx3zcǘ#InԼ#玘 NI= g&@>|#罏c<)O_b3O x?q|?w} 3F]p9u˘zׁyo}5f?_wQ;r ~WT؇l`0/x0c'po]`|`@϶b@BȘs+Q/3AjN-y},j2?07Z:ZB;8-5lccd{.e^ QňOӅD]n1𴙚DĠ!g1n4kfЃYAl󃯜lG̹%nh;T1ӡHt4]d!&9%XxGz>OQDŽ|Ђ1 8!9F~i?ׂ>h@?~xȕmǎ~aYG/) ]%=8aI4 )*ylYN>B4GE`K`URJFp(ҁ^fH Ū̟)AgDZF0"k@py*L׭d#ap]`=f![F/sSu aS4 )z̩Jy2. m)A;d[ ǶlN+JF(eޖ;6հ=,tҧ懬5W+WtP5pOėx\wlF3 Ұ#jzѳp&k+]vb'qfܕxjo= W.kD)@`[Z/ݓo.&Rg) aP5T]8;ySL)juqRUd"v^VτKꑰN:#zqL`´}_ cx Ѩ^ŋz#!f[q:UȿT ޯg  +AC#gP;Pw,y?S]Y 9'0B5;NQ0GDqJr4͙{O3Iky3xW|-WeA;AOѪgI5h?ݍ&QUZI@~@0q4](iH;AEw OJBmh>ODZ%^Pʊ(BSivI<:ܢ'B9$u).>@.^򓵜ZU"rl/ҢƾפZ%5[JA~r8˛/Ma!*\(}WK|RA<Γ dU "S5[:]c#WmynR4oW%~+1PpMb3y_Y>xw6*:pG?4"VZY'qyೈjesc鶣^#'fu>TrOcC [6{Ҏ8Dwv7v{u`;ӂYLY|(Y- qCD!GA#* +47.>8XȺꐯ 8-hLyWYgFAcEkdOsLDx-Öq I ಪoI VI*Hx!0.z1H* k:ᑼ&Xw>n'^I0VÄ^d?T[.Hb8P/=%MՃ..( n$ܑƿ\t2CQŠ>c5@2G3{?u.0*J$"m4;(L{|߅tCyj\T%fDz=@?$+UBb< ׈ {G>h/ryW!^{ uq>gE#|4d!~Qy^||ƙ?rSyEGv"01 +xQuSas;"}1`Ex Džtz=.bu;Vfxhg9.W Y=&]G48 P{ o4g>"OY)=59.ޒ>rth/E ʾ"e Y ~ޘ*\>F~yB$߲uVpW"@?jWE1poY"U|w29ZyԼfggZp1G0A|qY88~}A|vW{BސTZ @8x'`(?dA@tƍk>9?l?#*2~58SthՠEŋhxo{Ec*T`Q1x.83_q\qn1,&=N&6-OJX%W,-g:;3|oF{B@0j- aVNiY3Ad?|G3<W"wO33_ \E:ihELCYg1ȼ_"lГ*̳ۈҨ* {PD oJoK(.t[ǿJ̐ij\k:t /`BCKtеR%AbSU9F݅Ӆl;rG[َg\I+2*mu'TQDMH8oH`8ٷ.:^L^=x,IrT^Iq&o$|`YmP8+q{ľ=ʜC o)*N^{?ւ5`E΍[¬8NrTr6fۆ=b#!*}W]ꇴ-eM7Jb ^jT,JH_|uO.1)\pSrjJP/Sͱ]ձ<0oCTF_ Mg5HܳL }cX 6PiLz&l '̅ x@r';Sk,6 (dmLP {+Hmݚ|$Zn[EuOؓ~bvR{.KBԺKeݑ ȑ.*Pgg:W-Os2omஸ"pGtMG*bfz5a!с= 9:_5GO5"6mdËZ1SԂC$a)g@c?֩рqE>>T+2wJ@;y:NL+WeC|Ga+#^?#GCGçmU>͊Apu*Fā/81|ۿ%*oۭs\: Ul5 d˩ f70 CoK-ՁQNʚLHH [Zn-/ux0e;]m }}n~{G/h\ \1LG7 Jjp\jA43D I-(C&3&=bOAQ7c%qDcx8S%@Q0? }5 ;vO8#%̂">dhnG|)LۑϮ_ ͍g!@E 1Tư+RT5d&֍D {7JkHa윰VBOn:h=ij\SK>7g0vρ(yS"`Ўͨk%Bl=^7ZtFRMxtOzkUQ!Cx$E-We2%mmy Q0{ī[LMb:0&2mb^J4''D)ք[<.AE<@VDӦDa-X+I%̸T`[ 0L %wO uz-PgcA#!q0OiSL=}ҁ08G0Zؐ#o@zU*՘s< .* 5>8yS) @9cc}nq\\>w6"*G\)c5؄-_IT r_OȫjbZ̫^*zZ / Z1h*B{x (w 2F|7Fp4!vACx~'ʉӃwP\>۰,co8`^ ژG䖔 g+qW\~8mQS߉o5oaƥ$~Ё<#He #+BӃ_/88?O?OAQWW,y[ s(N 8qќs"^>Aa2_;N3o䞁{v Z|T KRǤj+/FƛoWzEyiW"eؕ!WR7s_;ź++H8:p@e 7|{&\"Eؓx+4"=x@<~x 3OHTXdA=c+Fx?~ob26keCaxm#ʌ 3RH_85=5ԛ2fܖ hbЫ?zW>A^ )郾jUMVP'3Fwd9Q_ dJ?ɪL_I8йViQ-'xPL8%5%W#8.͛;pXV%n2>h@ q/A 0ǪLƹLt`z↰< ߏ=VP}?4gy~Hj*} sN_R1XײLƼQ35|Y̙Myj[Ȯ h-z(˭8U!kYΞX|ߣGw콒+Ճ~9VE 9 36*Eo\ZB"Vouv६f'_W+%>MHvpi)9~t0Ϙ q\)f#  m}dLkސVOB:'l 0)Qp\`h6m ZpO>H$ȑ9 6_^ **,sNJ➄8]Șk6:=}Pe@q{;iօ<A0EC' zž^b\Mu߈i˪}$KYO;%ks,8h$*EM6Uxh&K9qqP_A !L9 eaM4$u:RIO%:K;t;t:w_S{@ݍ%wƿExH"&d ^Y~ Gr?yN@FS#APx";p{5c!f*̺Е .E,!dW7ON`;7h}mvkr)Ŝ k7sLb9Þ9&&[.=qtޏ|"" Wr?ӿ~7QA}L$Wxg ք{ϫ6@N J$Bf]h2aaJ/ 韷$'x)g*Z8"_bfBbM %%̠wG(y5ȳUz0KXύ}¬+6'fO|Hjo0'{C[PYD; )ׁ_Հ?p)G1tg*j{/1/h7-(caep/{[acI@[9 :3 h?D&F/~^nUcprU)mkȊ[ zz*A#""vZpJb/1誎, !&g'd< {zT@@րLO}}c1wͨϭX#ޑS&<4zJ8+ώ~dg/6/m ߒ;!fueu9ץND_B2 勞9-\s'=XxK0pkm“ rwց1a33؈g" %D|̳fo_A,fu-5fm$d빳QqYh ]ѫUuNV+BA `@Ys>OQ1e5fVrq#R"֍ItlYUQ:koF|%1q !ΟvzBQ7=C\XWY  IUೂxWd/ q2':Qʾ.D~!qPHE`_>w;,M :-hH yApO INpϴ୪o9XHgfc]bc&zB.IHnE.*hYq5! AA3ЉwK ?xy#'CEf\wqnr00oM hSTㅏnxuMyUlJ$b[;Sk9g|X9-˻WE#cq 7sfPW% ^ C kSR1Q6_ >rs j$lAD3_b=B őI?]8E E:tJ{E2FoT ^?_=G6Y/yA?P0(Sb*/ڱ!H`0#D3|!ډV]w 3 -SxAgLV;fDGr%UgXHnE3SyD>h4[sfښdgn 7[_܌u:2o)w5*fo|d̳lCiAE0_QpHQY8VU&AAMxU7;M1L()Մ_0J{R3qpJqt=o6_Zd1V?l1WG[, 7gHQ0ƿb :"7DFOBW1e$d Q0LVH8觠޿]nܻB蘂."N8.suC^G "]])w'p.B.S~NǨ$lhՅOQi@̮)pCZ>00awmS=)\ScšF[MZȷ%Z2}%WL?,GCo."Zp$8F1F\ Sb` 'D$uQ3;\:wY\h!I]f qm b]~7+F^Ͻ̚3ۮz<B8yMCbUMy[Dg ʛ;S: І -UiQUQ㉄X!=;2#qGUuE]DW3FM5C^Xdu{"Mb_ SpJ9ѩ'A+/Q"h@xP؜gθ_?&Ű DW߉00]߉I7ӀT "w,{S-oU^ƿRwP/'^8hg|#`ϻ}9 !-kh[Rj#(鸟#uA:m_VUׄ/`Naý;x+ǜ npq(qLLZۖ )pS nQW^2ko9bݽЉZrbgZ2ЁR=fZ0s. 8yW] Ve7=*n$ChjFfXfspbT ƫYvUJVؒx\7[%bp~_|+q[WHOE[S{_1_ ׁs{JA C#r*O5fODb^O$=Qgϑ\U%օ.Cމ OтЉwRU jPE,L"Tv 6]yfZ2yǙAZO13כI\q(8nShpy]aOb&Y18Xx͐:͒|cZ3168c6?OJƼ禨CppS8JbSЃ׮joGw:pB'Z>31Os2=$0 /WI4V'1 ^ϑ WWN _ut~1 ܄c_rX~"1 ~ ~!Jps2?S3;Q_P'vӀLkt}:ѵ:pEuуw,B d2gكfmPk~j5 l3 Z =hAklu!mbMuL-%/?Y:UW/rl}#>W\)]T`{!d7'z97OY)Իܭ 7iR+.W6M c2RuGu] ,JL`Xc=lP*ifaRaLr&+IXj1gk]>Jl k@ ʦ-g ƕM4irEMEI ~)A1<&aOT ?Mbx!ok'.~ Gbd35!=h5`!cDԨF*pPnU x}w: nbwG#yGc;y1Ge'pR$F-Ë1C՝Z⚬X#|eG]qK^ ]$u$R޹=x9uGl!v{I$) 1mp]kf,&~5_#r6xMB]\A òܐ?1)PCO*;u\ĬPFCu` |,_|(@p0Qp\~}e,$%w)BPB)x'ߕ+I#q;NlIDN!61o>c;Z*Vn 2 ?EИZ*q\"AGI[T`;7'g+1Ђvn砡wEb晏bDTWCZcdtVZh.<.I*(f &qTuU&,J +2Az4kY.5[ j OD1FԼ k )לyA0|ȇ54 ڶ*W1CgUԴZ:>|T1ܜT"<Ճ۴q`$lR.?$(8#~̵ U^{.X8^u󇛬Q)Ә ::DnNy"F@B>͹*0OE-ўߩӀ|5%3" 05Ž}޿10xeTW>px#<;뻸\!s%pOU%;oN~Q0I+ y5XӬKR#wuUwÎmZNB&*f|͟ Mᕛڹ#- piAd }',Ψ qMiPm56ᦸ% 83 BA^ W#5Ö4-=!!=|$ 'zpF6/ǽLUЀ'5'bɆ(WփΑWD>Q5Oֲx%;FS~:EhpE% * K`d}ML\L`C10=X" ?qmr)9Իʴ`m;(B b8# {:DL ~s$8-XYc֒W<X'ӻz5gwC'cw3\1*@öhDAVuc[-sV S6z\+Hٸ4FvcgbiI|q+Yz#5^MkttD 뻋yAQd =9¹y%dt:0Ӽj 88ѱW r>Ș>tn֏#C6uљdÎm1" S1}L%G\gF,K>0V= /K s3 ``KNpE¶ҩVp0+bsFŽSV 3d3ehڐaDB9c)(Y?敭#◌]% ,&e6NĚ7n .CזgJ;PܦS-h]ɹ jsyY%kR)Lh*p9/2#QdF7DxUԶMk\`8oSTqqp cf SѶ8/"Bh*뻏~+nEgRA )} ~vfH lV%Ifu2?3ɼq+jQQ]j;.nīj%'7,tUU*j/ >/V&"ch,L_3^sʶ{C\::T6$c3aט{Q%!Xͤs %RzW{NLT+3#pM)8#m:"6mmс1@d?= 3+pZ߈E|Z;))댘LrXXω1 '"*)Qdڝ4A>@D׮"fJC"!!D1X?+-'aKٺG# q-.:*}<՞9I}LP}tX#8ȯ!QULH;* k;_.pHٜ~p=tO1Ubwc^)Ɠ[-6K7"7ʎ׀#|p0P^ rܪYAzF,D̞= pi@nO/e.J1'dMQr ( &k>um_뎄ZicܝvIL\##}${`=CwHKa nUe L^z"q(ҁ> bER T鿕-;Ś%V,*APwhAkb`U=,i&3e+%9(26_Yv0~rCgpKjQ#CFE8aCUr3U@c5B4cmbhU!4UuJ RpFd jh{k<Ɋ%L˪ԛ7'mq2*$A̖'M_k ٭cE Jw"Vxx1[5#/C4'&CZ".J #<ҏFo*ڧD1}]LSTtd ~mג=|`_vᲁЂKd_2FBsA@ϮoU&WF̃+8v"úN#v``bMF]'6yrQ.'xj}0v 4[pN-IM?{uOhG˨+j,FP7S Z5r%q]+aE3J®>g{ ghJ<p6x$󃈇MU(u ވ;5{sVi2ܹ IێzTA VhU1- YѪ@rU1#}^&}!c^i6EV"Sm"ߔxM/H-^VJB~/[5ׂ刬>Q &OdO={66&+]2LsqpDɵ25Q|N'k2! R XaM\yuu u3\39Zq:9'EggV *}0oQF ؙgmBߕ36&Du5aw۪#r{F58#a ֵ^f&]_P]W##)2pW=b̔tL?hx?Q#3-w';}WaiA iUIlR jbh0wU\x $p*wJ1ے[I1Ѐ [i@Af ~/ !`\W~jdAӁW rpENO?~`#K]*F't7;K.ޱ6!Cd*y=L{'zLp^0r&nقլj soU)BKQxr_K;ڎVgB(Jt1[ 'P7urO]R 4#5 Ճ^ |Rl&^GZC=IJ 7Z-ce&13ҙWF);V!QpV%'42kCZoܞz?pKvAg\  _RׂS*DSٍD6*0~a)j /bZJЁ'O=s F_SVZ#VKk+zaM. '$7"10sB>CG^B) L(P)~q5p@ ו_C:zG=.]ь¼sD ٘#zGj'#Bf=x'gA2LbEe4 z"bNLwY1bո:f#eͳfZ~}*)?;Xg=W@ 71f )R)Spy±358w2_ Vi$ iDf"n;!vvFVӶcf߸R;[t kAPH.b~U+ǤJ#3g#a":ĴܼLb`44r_jNs|U̔alCPpAU1CDkeaź0 d _a)o_\d^D"9'/Y]eay ZMw3_ݕ,_MuuC:=h 截9;8 ga8,\UICb}tÙ,ӎg,xMN,hȴȨjg 恒ܻ% c gm8;=h/U WAWw@L'sD̜ª:rJt 6'BIUһmR`-TY25r Γa%V`1azLaEȱ0G<^91o~Ѽ}U/]utqj8q<|N1/*'ܒ\`+Bej2@O%>b 5E|e:'ՁA#-`E1v]Qv̷cU]ǻV;zB5+8,~ y#sw V-ESwcO}|u >& YU$<=z,C0cx T%Q*W _iT ͨBG3z]W;'Nʌ{:ΠW_#*10(mA^28ے9SgdZ⏲Qn"EYiҏ\>Q 0>tB“R5VO,z=`Sa ǺzO_$Ƽ sj%Qo= Z 8sE_\1ת{|=Ouj4o uR]z f#Ļcш]Uٱr ԅ^T;=o!ôW">(mua{/7Җj@{}@w g 7r̹ئ/Xk)Wh=b4θcM[O9bN.j% f{ds# *1qߒ7R-ُ8hsd?t jVfeBGV:S"h0^2)8$R@yRq)4ҁS2jAS0Sc H-'xmaY^a~YցZXZ\+I5`uu xB`#H6ώ|5R]oBvhzBaQ#?2"\7 c-XuBS|i#x;q ]0ZcSS?9$UwUxx[G2țxL6&I;׌8Xs;?#gfa5+YbJ֞F˜},QSUf?{) *pِhD]?3i/ \`\M`1:f/8JbrL$>f|\7`W]O(A{^#vg<u%f;7kBViGHf#zpB;!GD.cc2"AfRq;x6iԴFS|ld j61MޔJ-u xU*Do DN@S h:}+8Mn03zcA6F8DlcQy7q2 Oh??B92 kqMh0 -SxVAQOظ+?rea3IZq 1GRlWuG6#w-:xȁVEJp"iEFeqw@ty r=4Ҫ&&}eur,SgЁS e=_[Kw9pж7T `v-xMܻr@B:VMrt bٮ8pADcĺ.wNDǙʈQo8:Ĝ/`U:LZ(am=)Ǚay{3eh g6Iccx&X Q/ײfnHM,Rbw~1D6pFݓx&kW5_F 2qL'$dI҂wnUvӂa$od)b`GH88sd ϑ AA\4tƵ\>: lHM6EY sD5=V rҺ2_$[U r,Ѱi4h5U^ 9hcNH:8׵h*U SC9p8Y* x*q"]%=Ml-*P~wN>+f^\0|8Kse_!v89X /~:Twk77#5#^UW)DeAtՅC 4+ȝtY\JI3m@Flܢ*/ $ܯt 9A[mNE0e?^`UbA7ꇬh r516)!ybQ0<ᡈ2#/:pΈWz_JA1?fI/#~ap5I_kp ;N>ܕcLM4D6jHh 58:w1SaDjeiOZ/Sw>j=#gxA|2E꧹p#<2c YBxĘ1jQ%c$l9-hՂࠩ@ҝ}|OܪG") =Pp&a*w{ľmRLU'jf)U%9- \ KTJZ3.#x'wMcR-xL hi^\;䓫n}96\FUEG?h@x"RȾ'2E+t4BMVI+r:pI|uDn(+A c}:oaZ &D@ :D@w.P56]D bMx-X&dUt5Q_m U=zX͌ekmROVP\T xC`[wi@:⬠&b d /5a1ӄ՚z]W $n69gs =Yȹo(_I̥K7I`Dt4G? mO c=8x!GH/ Q_ܐ9RFode&:\4 PtA%,u`\kpHH6&M"UZpOi5X[AfhH{.v3wώ9v >Q$b$41'3TzA^{'l݂jYU 'Vg}bv [6x65^ɸ-AxůFWiȦɬC+U>.r q=b&QIŶj]'7]Gca#3tඬщҮElzD1L&hZ04FFpG*dP3 Z>л!+&:C}Vъ! aOA@CZc hgbiXǞȹku`\o[qk:0홻O 4.ԻќDH(E߄|u)"Jϻhއb|<79#'"b]=8qKy&E>#w>yNG;N몍| -!U=ZlKFL    6<'l&#_ĵH Xjn9(S7҈"kW:A pG<8Y:TjAA @_ܐVeD*b0;9"$nbd#>w@@Y"!+hUƹ8W$ژk>ЯQ ȬDȥd$/xW;cN):At#Xt!n%"f{*ǧBSe̐ i]&%y"SlÙUKuAH>0%OZ Nca2j$DZ`,w{`_ުON'.8"55}6k2慏Ey=n[HX6oqW#Idx`O}򶫗1wd@G65#sE|D`]^kmkWCa"V;8m gk-!~Xfo(VKxc3R=E"w11[uT;F~RNpr?)'}ax87HZɌ!F8(8"Hxi2@$'caWro8#h1̾}._c"= {7ت2P)]#~>x8h. GW.n`0 H,d\ݽ>/1qјNVӭHw?6]Wę2AgSh2w ye;TN*L2;t T HW-՝ d^J gzO1x4o"VO^S"agE6ވ/V{DE9A C R9#;G'00T?)SOMe 66b>WWѬ /:U1>m1XKf@=5#<}|ƱMAK6{Tc῜ 4G䴠- h:ரb&y3 9cܧ~>ckW] Rקc&2jt{Ϭm8oEVKT_y$;*9q -D.C(؎gʴ53^)#-*nBtTl*FbS >R_dၾ [B;ўfF 2;f X8` މD*}q 1G8\tS L0$Νʰ.T ϓlzzXHP/$b8|pz6Ŧf~H| rߓЊ > J0٪e#MFӄ5'\gunO>?گnJAq!>pr1r;GWq[kϳwRɴn\SQqOzF<*>S|M]ϩ?9Fh>ɥ]]_=uF: o%OdLbaMP_da[^Kr/)UT%3bb[qVbdAt*Poܛ6_b>p-ؐI17Nr.F=fk}S3hx**cG:׭RS}e@Z4thM#|"C0>> zNC].( o3=h=:'|b7boBi̦P/*U&YgJ2qM+qNp^axU҂ N{茁J~d;nj\)8-/e 3~"i< (ӭZ:DLtUxੋ64M(>3_{fq 4-87IKǙdW&)k<LU g]] 3 ȫ}5y1[cF{-6t*;.w {`a6|xmF9[{:EpMc=Ҁ gm(+xI—T) %x& 9)qVGM]n/{N AQΞFA!#vA$I2gBA*~Ђ7b# iBHKô\en RO)ofW$ݞa_ :1qLA}ްiTF:0ቘ4pgT+P,Eq |Nd{y\~b'N$B5sA{"L|1:ulF'I]G>J~رvDwa.ሐ>~SAni`Ex3ı|&d=у"$qq]Xwv " ވȄ3-k_0W  ).f%g8KE-!JHhU2%c$I.aZcH lihкCJPm}ʻ8Ifa%wdk| Mh$̫+ ac?ʫE;3AƿZ泑>"t+1ګar4PyuC[3c)4%(Ƙ9sUxدUW,.0zOX3da# g8(ֱQZj0U.a| 72Ω"F6p1rDHxQ%ޗI|;w:;]G}s tJ+gy@ϾXz7`SWBV*a੒Ti!>qyf憤1 D>2road㵚XN@N9sjqdY@.Dt%8/YX?#ճ2+ÑH} jpCצ#bdZn!#_lL ~+kʱcB]`t ${ɺ;l9#\8s" \uy%UK } "+)#M!UGЁ nIe dX]?TQbcyߕG~,LOvG4O*MFݤ343F'}Xm pm]6b?d"D]*HDʧlDaM(9ߍs5'7 #Nث#?7"agEG2i \1p#{%MzauH?2LZ}Ȭbyꦱ#b xx$>I:g0k(xT\>&+<&sRz84 ow|3ZŪQ1=JltA4#!b ?o}~*@>ȾpV hpI ȵR_Y|*Ձ}"o?"@Bb< s֑Ƽc!!泳=;p1,0z pq L"5" |ljyBa׳EyLcR>B`ޯmN(Iele&Smb[,jf,J[+/!nz+.ܠd2>l ߌ3$U:3!#mbm䌜3rb}Lq{'Qwp؇4f2$3_=y!76'ߙ(B?5 \""kRה9"y`QVFU*q j˹@$ 1Cu;jIhDtJ|Ҽ"h @ǒ9ӵ>;cqk:K&^yiW.:&M=:uӞ9$NAo$ 0jkQ.0ցX}:"Ug WU,g"kAV UX7'Qg'l9Yx HD- Xo"bpD|ELbRY 2 _\ G¾6\fS>L`8 HᝋmTwсI4"VOVg$ _#Bn@P?w  ]T(acmNjEbuO78"d-M#alw9:2V<wdF R)AlA=w,Dԃ UbwR+ȝĈ|G}~}>:[;V3shO798fԈ{T#wd`JiDmߊvF2=e!ϑ UTAsFlGс'L`K`tŽdZ K\<@?vD)h8V KFpQ{Evh*A6kEJcY&rO<fA]`OTD{ED HWc iL ࿴3d.5?|:2W0Q'-hAD=rQ] G*駑ܗcЀP9Uɀ 9N]HnJP0$4xwUWQ.\vݕEŸ;QMd;qdA=L>kD'z$|BldرkF;ES敖P:dF|yǙU뀁ED6Q5scdL*e߹ &)^Я5T`qml}tũʹ"Oq:p?h1хIG x i`G`Q) ^@gyXLQhH |.Z0T,fƿp^K hzΥFp߹ k4|Ź:+hWފRwS*q:\u;u;,IgVs_O^ ;~'2SXky}JT BRc>\dK+;ﱣ_O3v29X)q.GV]v z"_x3K4*q/93\WIZ8#@PpO5aP5#8ƾ2-!~JADkR)s&d92UG5тۨ\grAXutC_ D O8o0S@ru ^ƥ8*nEW|\GهPi5LDyxV51%T'xܐ{7b?YV:.*]8+=s/9S3_ kAp^߰!OτT ֲHO=_OPvrB۪ qpC;Y XqMjEzݗp/ i7]ḃxFruDj2C5H́Vc) !o oV ML&' #ȳdzR)xPsӂw|e3Y=iDXPGSE7xiu~2p_ca(AshZB``LVCvQ0kTZxw"w8x]gV'hz B(Z1bdWP ^k4y.2Gzj1qMcyqC3 [E͈i\d6_f$ Zc}vՉǵF.1fXfЦuӽlV]Wף!R'V`~Uh¿f #m}[६:3.}6aN֞ HM;!~% }%sqBse୲oPC<鿡! v蚻&)ȊДuBX‡ݷ]i$|%10րN`P/ց|<(d$UО~{ ʺKlH8xB_ޤ2~W$݇(42y }zgGՈ( >*rzGT™NM|#C8 >'BAVp\FsEtEǾN,&aRusV)WxQ3GD|@WMi>_T!J%ҾN4#w=#6kbfS0TB u)$3 4Ϣ s`E~w_V伒=DV~O?\`\Z^p2=2*8f[;@'! sRQ&ao]bgsrUOriF;_\ T_3u𫈞;DlZ88X>kf Z8Ym#~Ҵ*[ A[.D;l8hی'*p> OڌaKc’FzH@/h?ޕ ATFsUy}b#oP](27߲WY#.`L?f޵>]ITc9<,`+bb`JD5A)JRMH$* G>TAs D<񰯈~,3c/$vskBi. t"6Vz1gWVS!#Ix-'e`p0CΜ3E5U1p"ajb|BqX]xfRr~UʹrZk 4 oX.?9h>Ͽ9 FǙ%GzRܒ]cքD]9iT`Mq26[oL;]#dANt%؍:fl #o$FP!Jpխ%V9JWCV1+&" žꁄYsp~0ڪcgUWĸҞRuȼ[ogzЀ{+M3Iŕβӈu-/kvѰB}MA5O QfI\h'\-3͹׌{q6WŽЎ3$sq[Xρj '. 2->!^Fj0L}}R\m_EoSi4l.|q/&tV>\,eMJGܳ=#^4yٳ?v , 3x竩1YY*q>u #jLbm 4"zLR1hqU 9Eh.q;\>m:='c -Ӄ]-28&%9_)ͫ-Mptݹ%YxIj\L|%UIdlsӢܲtfY,lmXM̹2p0;+ց^W&dŕ.3hk}%v<|wׁ= ~AnYOߙD6h0櫣'ާ(+τ*ɬJfBAgm=pw0]oqf-TA[91/sONVFucm#rF=c%AD$WD ǥs$|VVaʳ=b[JA̕^q,|+?xFcz!2iuȁ(økd,Ziߺ:Af y"7: bD5&Z4ѯL S8+#h{J=*Œx s? Z\b?J45"aSq&л"gT H߱pa* Cǯ〶{L:oN#"KF0펎0k.R X. c%ne  ]sЄֽgk9CpӨ;DEaQ# WVe%N-u81gu3QQvR\8+XFB?C:+!3y%YҜ9` bE{G|OP*«Z3hj-yC4\# sW#/򳉩>Ng1lӁQLT SL g~nq:C'e*ƾU~i8!|B+nĿHycbk Fx蘿6ftAfroNIz(f;Zk>whKC M>wbl * N4fY}^Bf$^:dy̛2 5ؖ>X .>+, :Ƙ'qfkyތ#sQ<=ޠ nJȦ[d5ؓx,<#5qG _I<^`U扔[a9 VKf@0 bZWՠNJ8Er7Tt_\c:L*ׁ6&%h5x% ]^m'wDK2*ȫlo+3J r*J@a#!3}gy8x>%x+]>51Z8 ?R+Ǩ#Մ|TSed%~pss9GF*cyKf⊂/Ӄt2cP +o,s??/뫋|%Q _S$'ݫҝs~_!}1*Fkǹy _Ԁ~}4alY" '-1AݦhWEa6oGLu;yӍ;~;|z|ࠧ߼_|3rcdI‰A we%>uݛ9* jj4txUkTap820<g*Я>G[sdBuegiN6[u`TR7oJSGYմ@.OYh-~ЂX(Wr)?Q G>"E9 Aׁ֬_uF9(c X xaY0h<-|w +xf-74q6طc.OgT}G͛)d<_ekB}`>E\c&T]3Si9L7_ C,X((0v,Ak/myp.4'S'r,3g}#s~*+7!JT^9kȏ<oF=/j@ouSFG&m jK.PEiAP tZGZcKppʹ˕pW S5Gx;uG:`^5ҏ|PUZ}`?=(D#G< IygwB4w{w:RnԈYqN{W>.kR23D~Ճ졋N'<Sҵ5 3x~#| s(^@NL ӂ= i`E>9`@~Lī{5WCVK%5(@vRD, X{/ROBcߊ7hUW2,64OVC zoE?,3WoQ6Q/kd}8pFJy22X{.7H ^XUՔ k r_9Zz87_yWq-4GGӣrW]Wīȷv&:N;rBX^ge>NIsDS{=T"vBQՂ> t'Alʛ_o2W3odKZw\V򂬓L |b='&IMy"Xm2tPf(?{#8esA HxVk+1Q~j4*PH4Z ~vvlϒ{i\|6)شARBPee28aN)0K16F<̚j@D}~v;۶ 1ap`# ![p1lc}ݵߨkwGϥ1Ce+|֤sIbݴpPVb [X*l8OPn9үI֫d*O.'(d)|'W)Fox: 6S -#CIxd0]^|Ŋ@l_]̍1̍ ￙ދpξߌx=\{/VT{:c # s{{{Nܣ'W=&٧-rm އD:ថ0 ^V.>sb 6ON8͈Goɞ )5;%|sdTҌ9Rm7e㼭qr )Ȭ OZ?bNTL0A>=bz"z d{;'+qjNpu`Qɼ @7C}|cU/syAуY>& ?Lr:Œ(xTW2Rf~D[kZpHz@CW~ߞ1dX @گy fD>+ˌngvJ0K I|pMif1g+\v){l7Zp@pF)A+P/EWP+Uav/N?"OSx3pm35^O\U=H5xy݊Y!;4hTG[0rߥMhN&7d?\OFAQBF8AfI|12}~d-W^A>^2`[N# 'Dυ.&y^a?_*d^Zz*}EP%VYz"bytVGJ  q[IHܑ?2𳫎GЁຩTXv?w{W ^Uǚ,}2!GG}." QsvT?" dLoy>[RQI+e"ݧ r"̙j=i3|l#_Ŀ=#vM-׺^Ao*eO,?U10n{Ԃ!fjiR"Xsh89Z=jf;Y@S{R58X8nS)"MjhIm'n6#Z'#;u #Oۥ]s|Y[r9ͥqGÞ߁v^ 8NĬ& B]X|e*iG#)AAC[{:G GJj-i|/xggxg_22gvNc=ʒ,.:HAǸO7MeJMnmlKTsv] _k1 W '\"1+B/}ta_}X*?c~¤MSzl2U NY`'Wd;eGK k~PM(8Xu_+ aKISb$4@fHAl9 %xhx>4a}..k컬ڱϫ w+YuGWŜ*8)H'faU9ĚG61Ά(tkmcOL({~/M=UEΞY==EdL|!HXE3/dv"*xw4)|P`-'\qe((}s+wαwHT[Y|=!RG7(yk`7eq>*8>fYGA[K_Ja꿧ʻI=Mg,Iv-W~{&ׄQz&)BF̠KcݳL NrЅB=Fžzf*]h8 v#`'-WcKa,s ^VW$k3 6U מk"a8Hj{tk\⊇fɬk^p;y#mKk7/ӃQxSV>@IB|{>'6M |#8h8 NH}ffcq6\p!1}pw9dH6Q Q/43(FJ/( p(pƣgѫ\y ~Q4.4GRK=.q5X?M-mJJ)|npL}~ev9K kZå]5EMÛek}|ГgۅSf*t5*t!2Ԩ`ؚ4XJ #"fL-?XǕ僤4F/:!;[ܻBbJJTax4q !',1 >/C\Tx0 lᩛr>p ,Y }(j_Q$çFA3G;k<#4QQ1q2gCz2BsR>6<]n2'ל\u㈊1?)7)WKYoЎVMK`U;ͬpbMb.f7GwT>R2~rjkՆ2KlL]d{'HyUTyy.pxeL'Wu0QfcaB֬pF ִ  z{i{y3 F=5=c۞})G(Bv/mqNyyca*zp.#` =72Q+H58皦LC BbVMKfO! cp~y\ǙO:P𑞽g5]cl:C">qVPTy#@ B n&ꡗnkeDV|@s͹!T3Q5`žo?ހYw{j)#cΗF/*\rFA5sB#eF֜{f*P|*x)>D3}Hi$ݡ;22'aT0DqA q;lƍSrz<wOu锰J7">M]RPz_=r R2&HWՑu1?^k噮:(IǿLCRqp4;RzAYwQqI{n_7G*NMbD >/z\6O W:>GW=vw9z# A־4e5WR59$q]qsiG5`&{[tmo]GQE³nkr Cрu4/m?ºg5*.ɸo>FbSvu1n $!g)OYD? 1_D<qF^Q FO^7+ >w u 3}Q'a\|Z=(Z.TLJ7v}R}^ Gxx=0^ieL]xxߕ, j%^*w8'_3ݳHzNSϓ4hXe<*o⋯!Ε`_ 9{mLj܋uBW pd 'Yxf2}T~_|xH7"Gd_{$RG_̏A|I_'`spoJro"]fkg=$:32fN1+diqÜT꒬6 G1.^JBu/3M_}R=(6}Q1 U"U,$vm6 (_ZʶuuЁ[1` b|wQM4`o#fGEk<ќkD2Áz>5ԹO]S;~1H^y4w&Z0+~vkXᗐ->ҝ$wOU} sjw9JFt HطHyA.9ӫnRzشWZ/G;}$]K| GC  &al_eYOmѰwO@*P#r=۾K]opngEm rվEŸ뿛pَ?t$V<`ۼf\>+¨O4[>3U~0}(rWqO{^UǶ} 9:#Qd ?z>1CP`@4h? {~hK;f>[+hgsz1(m|gHHόr#RA  r,1%>WWc! ˠ{Z_/]e ƪ#c¦BjyLH>0U諨/8_4<6X(XY:vjP+*.C8j>Uk`|ON)1ꑄ½{oʿwz~dnp1x/M;." 7s\ >f7*@z`ܞS+pʱߌe!D}}ޡiB ;^}^:HV|dcw28\ HAySshԛ2?Gczۅ .1Q?=r ،-#ZJd>W3%dl,1qlzGI VD$Fj%^zrJ+с>tY@!c4|#J!['Jli4JnHKuҚ/rU鉠F&m >"׀ܹĈT-G6U*pu}) D<<0u߰u|7(3^|W}c&s7pX=!J= :Pr xV[nqQCvhi]GttOǹZ^ b(‰3V'RʹTMZՠY 1Yﲁ5 ^9Lj/㨔yi XTN#OB+^ieWE ;8%`EE;ty@x7SSgU|>I]N?<9c?d0WH8u/l>?~qG[zgcaEeݎnC+L¶W-<"^q;D22HtP+;j A|+"aFþnP`\-ұH kdLc1%"W"hkpr*bbq#PwD~&=Yx鼑."~S~3J6X[bϿi/UPt`me "a(SF*d]] <%iiL?䞒O[>RpFue Lgs Psc"[ }butT&@ar 'RHԿ4W'J悠0e}m^iDRUɅ{Tuzj{~G+dN 0"K3&9"WNC Χ3lWow k\M ;.j:jߨ7X}neQ3CV̻t,}eȼe҂JB ^LcSUy5xYŠjd$W(GT X51)@xN+y#^٠_U诠w}Q`Gc,+y(C wŘ"32ZpU j_`T ?jY4*e_5]fpH]}PBXHiÊmU V*PoZ9-<|zpaᓔ%:H$~b`N F(~`z)2:Ҩ&eE hԻy8{{h<#  +br-x: hpp.L ~9 /KL^D41W k9Wa{#5+ ¶¿vL gf5ȚAx H? iyVpXرG4YLZwɬiYoDVОbЕzHJ]swjQs?mItw\R5M`_ʾ꘼X :RX!ߔ}>׮/p\NjG*9'{+rVNczžZ0R ğ*WM*"r(xF>)B\u?*sXe[4%SE#ۚ^٤ 5|"b<:|(V=sGY$9kuV#L`,-꿺/u8Q%{G<9]zp欎n aLJt\x˦<7!tjGĸ@ @A*o{ߪ?d8MXMLVO0?}\>P&$|p<׊kUċIY5wcƸ38Qb=`~"=OU1Gi?+#P?d?(=`q7OꝟZI?n@@?UjWw"IF\TD2gaW?Kх@kLa;O,q z8oГpAsc:ca<#>(Q`֍$ۦKHD.geK,^ B$e?fqϚ/Ax X\]a8!^8*pqܻNL-?Zxo&=~~B}LNQe=M9\ *j|IP 5NTЀQ!]^zC@Bр ˆ .iNrlf;wV+ɿt{v$ #)!bfʿRm?]<_SjY+8TC捠V2x}T`A K Ӝ|aHGhxyᯢe#cc-9AkVG_J) 3'iI1j}g8VH=Z`9I#' SM5]vlGŠ2J@ȂRp@m&\P^\< nF>V*J@  4!Yc (=NL:CD !JaJ|swIKԓ+D3Z1-L݌ zEŷq{E{7mpAA!aQ ({`vn#s?^´ ~*L:}(٦)߽DxX|G>#aU hOʹVx`(Bq=ʏnkR=VzTC\b.QΦS'5R(3{#0h 0'w7llRIu1=rW0Ѭq ,`EÁbCk+joÔ_^+J!_Q re!J$;A;./2PzAFp8Y mS$:q{1n1x8#fsV{t!oC,3W7l{EXWuj<^ڣc=cTlY2"[L||~҃M ^x**}-jAʦ.qUBb^Gz9-FRk4ilO:Px 3VxcZIh\5ՠ~sz?tQ_> #r$]#Bt5H!+'XXO/g(>f&5goM^qX'b]省9jOG yA_1ק j$lw$ Y=jp)'!L`ձzAgϺG0U& mSm>aPpCpT!(H2V)JF!$8Zz<4 *c9V>| fSi ҹWD8?*i@Cz^41i}&_QAjys0T{F tĿϻN*B\.[ǎW/x?ϚꜥՀ 4VVmqϔ}iTy۹n_!/s.} 5H1bgQT$qp!m,\7S%8{ &prPԡ(ĿRDdټ*4 ^Щ3A e'9N*5Ǻ!7x^I7]R~)*2Ɯoz- ~}%4T!-3S踊S*[Z(e!{,qی"V(߰\ Y#C*&yT2O|G? +Wm9cu1Vn,qe}uo}f?}V7_~5P;Ki}޾*Cy(HYw}l %Xgas^OdY7V%F 8:F'D?x0GAC\ΐYc%V~k{kcE |}͂}8x:^hWo}m,wޙbؾ=I_y&^ ~7?C]TkY<'8_Ĭ༛JJ\'CNx:Dž%oI"\mcӘ0SKfm_B֣cϿpŴw<x)Eŏ]V;u=7Xx;VwKI6g1-I\$Q]jJ­O͇,TH ~ rj\xXO ;z3/Cr"=i,E>XA%!}О`A W|%WC}JW !yu7~ wa21pϢ`(?hAAiM"5;w, NZ@ ((=u s^8-z癗ks•'׆ #`(MZWJe 燡𔪿JcmoȞ~vzDke8eW;NЉXAKY,8gA(,ĸm\8xY󆗴AlpJCb#ߕRgxXi跥>p5Azl! }gPጋceLz{* 9сzkNj{7ss|=p ș?] #:%9@fԫek#@&\rG_+E&¿W +(Sr Y2ǜ WԂP~O {N GgZ;%}wdɘrE6V' ôlW[r&?{+.[\W\q\ϓOLE¨pE_~KXsL Ҫ@fEab_р-W(3)0=p<{r3 xPCH&  Z0&I hWS cBU 6PaA[_̾`lO3J}¿}Q?#`~{/@ybࡲ0rcc睊;Q-(GhYJ뙛׬~jph۹N½OqU_} jCj9U.WC\dtB 1s[[ ;>O:ܲ%SowëSITB0nR1#rwݞd@ urS?]jq@f L^ӍL]d caL݇b/W52!;\Y0Ԡ-vy^]V}Lܷ+OX$0X '\X?SI.ȥA.Dȥ{- x1P8weô գrU 3-@Lκs~rpߪ@T zGg~M$#`TFs)@OU ^el|d?qB{oT[O/JBh}놥SJMtҁ[^ Vm! ~7_՞^( w^\ {Hzy#Ђ~ <+Oe)x~ i8W䉒p x*?"pJpƻ̄=ӁXO?*S%#| x!9 _l2ԼUx r/1t>M?h[վߢ3xgJ3=SzP१WAf5ϣaDA kEܚ {G >#kOZ !~xQ AT̵9Q?m ȷbuյ5^( XQ)cP0V4ё{̙SZ\lYEF@Lq(w`78+1(sߢ{6~T_Oٳ{Rqrdd KՂqU8Qk_a_+7Ty!D]۲OZu>1-j1sEڦ;d,Pbb&g |D) ӁjoEOC"ċV7H}KV1s$~L짓.o>ȵ\2Gc +6Я%T=\ ~3x&j/j}gۤ]] Vl;lM'v}< wsOfx:xoSهĤ4`5ⲀO]4чq>芋~|h1_.}tkAW-+Ͼ?>LaS0f#":-|Ng^p'h:p*d>htchEKw U,*KwT| &x2c3f&Cf 7xCg{h.Iu6nٲ+=u#r:F98c$"yA>| [~z#]pǚ+|=wsqs@ UUeTB.;u!ڰ#0f%LQq+0#Q1eW25IH $|@?vTB&FÀJTGdФE+7`,텽gl,1ׂ_[>*;|tӌUA+Ŕ`S0jY/ ?qQ1k2_{tSYx1X`atc:_ko2Pĕr"eVz9CwE KNG ' ŲFo^7!Xx'1?4SΌB**:@OAĿ^^XmJA8FAB@`89W'{ V3X!HZ/r;Uv`wbv>=:mO]ܶw!;, D2` 5 ʻ:r$)<_#f|o0''DS9( *08E8zO}=%f1QU`\ 1WF}uR)a3\N{/q+i-Ӂ .(RE%k! t>+(P)D8!?lMoǭ.p 1+,:0# {V'9(,<0%HI:p9NEA̞`Ei%ޓGBȼ)}]l>9y&Pv@+%UUz%(PȌszH?D617zgX1 b_z;wx^< 89?PT`L3gG?2WpeU'y(u21멺" ˱|0_eۢҏ8K1q"yu߰C?G=Xw]%`\ap\k cJ)P' Laqc«COBƠ0XGZ_2fQ$AWv3Y) a.?&h\wIKqЁ%96=}AXB ꣿ\ ύ1,1"~[-#S}L쒻IE(-|Ab"bኅ]{<Ɲh$ I~OBu̓G9*iSNz0+KT g$0 rԁHFpZ_e:!qւBcүY4JUM9:PqAY/#sBGa;(!4 cb$'jĴ`NBJ "y3$;XPTWD4au'3[.3 _&,>bv\Zybݹvx*YsΘ"V+.a$"fŭUn3:inL᫢gcgM5('N|~ӁrKpZU c=A>0Y]K=8rͧ[hھ *_i,kAk爜]!~՟:O~Ь鷆q0;\*Uu &7Ur-O= Ԣ`^z1FĬ檜E:s13 )ظF@mDȦWJNo)o)F,dȒKB8߭J: .:@HuG@t #{)A*PwPr@z0Nļr 8׳@'ٿoL%c{CLq1NMw$.S#2k*&iɩ^>wҫ@ԁ3>'Xq^յ`?˯\`~_wGnL:uO]szsX]Dr/kZ ,%}I  .g7I1.#2f͜6Lb4̹R3S9$6g u3ʻ5ninoEy9 %\]IaPo@p/RpI'\&2׿Enǰm%+ʜ}7"":1k{IVZl'e(/OӮ>3d *R4]'sb֣Bzwc4(Jèr:9kV+ ׀#4',ft˱fW*W_e02XwHV̧&D8ȇ.aǕmGi%hU3i+= 'mlztNJ6}.ɽbfo{dŢe^ts\J:-[wknЯtlw>PwdQ0 S"sb𰚬w; (Rz&]ym"ߍSj̭@T&DecD;*v+U'&? ÜN5Q%X8_$ݝ5]b: #qCMyx]$Bªbs[#xxe@8 . hJ9AN=;w컬cՁUiW1jAKcd$NqYu8?Fg ʘ}=+9!=cHQV HXpH=@d:FOgxǪR4iE[_$|O3:,9IMt1[iUgKb%+V?#qA[1n;B-\KE.5*]ZN Eey CӁ뎃Ѐ]ۄ*R 'T([07 (Յ~!8+vxzŗ>k/q@jìW*O@ %`I>7ZC0% 2'," |`tqziD:l \js1#b/޸ë/Du^^OGũbdkrdq_5M V Ŷ b+ %(כ%W\/aĿ*[ s%-VL7Aؔrbc=" [R)B>1euΪ(AaVưos% 7ϓ\J0WY:)cf>"U>?1YJ*pUH[_a*p]4j׀qvVS 8pϪ$wPH/sc|4IX'^_Z=j{TĹY>wj" ;ߚYO>/f hڲN9ׁ86&uژ$V}qzWתk&%g͛Xe3Om"lIplrH8c ~ub 3*^y)9\CufRO: -xU qՑs}qCZ|Kܣ?"7BF!4I:?=rf& U/ER/>f՚1|1;^X}IUZw:Q0ke# φS[U]~ *hHG#sM遯 r~㪿= /vs_sG"b<d.Y?=23Tw2-&b88);QWDٱApbY?sdqMbUoh݌Ww=#8/&&u^rcε:F0iGM:h#d$'yF3̕E< %XjVw F0wCf[(E|c%%TI uzyAT|m5{"w{dW}}q1mցMKԀiRv첷ڻW Uр\ &L[/Nl 8?m!W` 1cP2ۺ6'Wfm2:]\) cIEuCGh0V]Z2 zȣn)-([̽at92ϵNMG ]!3r-xWxJD5֑  1I>kzJj[hDh 6zO3&'I;WNŚ*=ӀN0 \OiV#y#|ਝE Hi@ 69fߜaʔ "#H%8,*O~8ir'YIzqe)8]YZn~*ֶZsM@TB9R>'Ec3.&  $+RiBvx5y$I2eU"b r֊NQVȂEepť3U'2iXE/l>& jDHu2[%x:DOg&IL%س| *TG#"?u_诇ֻ ^b^ayG#.rR8q__sqpDNmrD^jeas*! X#AEܯ^ zsQy8Nz0m.g*!+Mg:XIVNa:ž|M]rHm"D̘o?gs0dn1qČT XJ(}t fȒ2$:p*EG,*/FGrhF*KsRnie;e |7 'IU I%j辫 S)xnH铃˜ׁMl=E)b^?+e+Dm*?va!wF-\zNp~Uc<\ga(דו/5a(W#Y~J@/l`ԁod[_8#͹Y @t 3 %29)8k pOsDq~ c92.[.%"Fm$;BOx1y"~Jd8G5 >YLz ~h A9NEJ^T+?,UJ}rR#0߲2I]PIťLٹu2nf>QK">e5LkL9}"]*O-đpJr'nj  /OMԗ #SX_NyW"GYj5 vү<|1u `u1.'JpSmta6BZpvGGy4׻Q~ Ղt:+/D6hd[D ]5)G_bj }OI "yFp+\+ Gn 2B2wNxV;H>Zc@V JAqb0V`#\+}ը ]UC V$D4c u_fZS jJ7qh|1D 7rpgz'5k3LaM0BW71Ǣҁ4 `U1Q ƵD8?#s'TD^(N}➒K@ Jj:to*AFE|v֥VƜ88_e2p*or !>J!C5XIc漄85*H͙bEΜx3̕CEк\ι:V<{!*Sc[cs^{'k_ |k*=PO E !WYӬɧ(lT;|Y&ps%G ؔ?QHس39~LX&z'kQ7iWdG r-eQ RVPH}:G #ICۼs5~y (8\#szs\skqhɼTV V-R2pQ0&HOC'-Z## rZ251qݐ 뿦7'"f]䞨3R1i4HcZ!8D0.>V!na jif:sulwfp ge}5O{\ j}ː,T~#%>&F]#L$ e70P/])qSQ1CM>#H52W D]JDU̖r}r:Gu1APOO9A@9<5%M71YZoM|}F\qJSR @F겋#r벁=SY%QuQ vBTɫcrG|t"{yb1~:ٴ<f{L;W6; 'ضizԀeꓜ2bCT/yA{_) tZ6^?DCܣa?!qQ0Ef{ jz8їiT@ b+uToD×@;>9 ,13 |1Rw{TIYF0N} *sSpKuvZ'xX(TG$7V7x!hфcJ®z8"=WC80[XOO}byjm~48a׀GFF愂RUpiw*UĮŌ4g$w/'~njAutkگ~i}roSM`S<\8HU\|Tz]] H$(C=׵l`k)"<3Ȕif@Wf˼MtmRc9EZ N8j tJOYZPQ3d|f1vgYFwMDdt`Wc#wP`Uu''d{#qߛjerg'by-R'h=UXL/VUin}9s:sT"Ҽ} ;kEՑ5|ɷ"z&gLk6091o`| H%șSH^FüBګ@Nj̗zZ"1=竦1Sa 3]㪈N2ITtK4-Kz웦e "K> ӀB nJT ~ JPrܪc[sL8 NLʨZ0@۠{./4NJ է6! _+NS_,d@#=1ghaho䥣 fwQܑe='#."^lЃ/ ϬaHA}Ixj UY. ?Kl}}nVC 8QRp:zGxF{08!;F:*f,/2IjM1~we[~7ʊݒJ@H/:y>wqG)ʯD$/i4}aq̑yZRvrI`@Lӏ( ߩx" }A=&.񅫉ssO$ׁúFi1W:3A'\)4&((] ˱wèT.9UU ֫sNC^7hNHצqB!>pg%UwQ+Gn{T}.5~NeLbF=Z n d*.\O&7b߭UHuB;ՁU|7_[U[^8ы; |z˜sMDóh+~T:#Ju~ &/XFP*벶0ԟDro)Z#`/}RYJCl{J1.6YZA.竤9QSfuvh!=;֟ >U2w%,!fH[5tXqίjAz|8oN!w9ϾR0.gD/̊tЀ!gĜ<Z;¹;);gUGX+u8 g>_ۜK$ў;{뮩 'ʩ6w*Vpp+suTTw9p\9+Sa2{ WZ_ qGZ's|l2bE$+*g&kjJe ח7Yh.50p%uj󳦋 {=b;0;U=(\'I#(1pVٔdFӨLwN :ۥ_?iRpё0%3M?e:5*ʰx$#c)B&&$2}3i"ƀ|7MUB(*pS 9JZR0-Rz@ADЁ ?<玒&D EG,UYl`Y08t[?m&үfܺ9˜*rUUF.+(3TըQȁ%R|V,Y%E r*:}=S>yMp>cS_pGwfѝkTa[;Qp=<)Է ,ĜGaC=U2/O)O9؜ Ӭ!3үd7oN3.JwSXQ 68V+Ww+^//vko0#D x/QW ^Y_{XcHzC5jv ,me й1fFc$5CdZ֤ <ľ3 Gdѯ߷we=z+6WDt`;]n9'y@ϜLog޷^sF0SϙfL|͖AgE3 _&g<̙׬A~+8:||R4)`?-U1tE8-@\OyJN' ;gjU#c6x81p/I7U7\}SܐBR TV)\o+B";8@IH_^R>pj3Es>GxI- N:7k"Ę'" W>dvjG3jgʬ(i;3;,@NG^_.ΕFI<[`>fcSX M6"uH#5!׫\* wuk?Oᘵrddb"J>QG\OYb9Ü0u7}ȉm!ڎu+YS1\y]e_-WK$XiW\45x%ߒu+9 dp勼׌Tz|0Ѓ~t ?|KV1DBB0t1Pzj0IՖjט6 /,E11:0n[WQ:+ +6b#8omBOBAqH|j/]\;l͙Aтͽt^6p1٬^3/ŸEGjXaoU x" dM6)A3]#2aTIb_j=8QFb__(/s:21kTÛiJUi*V)BQץlBU?S+UѰ߿C2L zi(B@x#[i 'H{ v\\ wF3 TzWDVznCn1#\c{caN,$tyM%(#ӃD:U5qjp<(b##)==!Ƅ'ht3dnWF$ߪM䶠[HUv X:-Kҹ@uxl F)r%xJ*UG3ʼn%snȒe9Af+Q}u!.m g2Scdn֟6?A2 $15w'`#+6W/4S-"& 99YWxKxBgޥlm! X#T;]#"ax1 }\]S|M}*p/SG|5ENU:ƯB6Y'HWDT3)C F ~)in`]|_qg噘g _Gx^GHM4  )\$ܤ*)yd ,+ ++Q%{.oj뾂#HӁԀXu}d$-Y, /5R*e,8x)I > |0XҁTk\ qڿYT|f(ev-WRwi0iOxtMUC1Pw {E|t`styx%]A<_!rAd)"݁9Q82ZO'nX =m𵃇M$\ |)CC 2OXHO *p}Z#(Ֆ~1#j$wk(kË 7/8iC+SҌRD6 :ej\Rw˭tHm(|g3V##uѷSD-8=D.pL}+9wG7iN|#!mc`;ӀG{wgѩ/ |lgR0 zzƳY_yͱ*zGAW||Vn%J!T]\=  bG\D'F<'{4k ϙ, 茄F + RԁXM X3:d:+K|>L@$ƽOJb{vkSW)-O7'`| b58jwZI>SȧEu5A®@(1W-"3y}LsU^MXO:;+5Ff<,ێQ:*C2!2yw۫!^g/ֶL+G#Il tP$\IW\ɲT.#iv!~r{˪c߿lU@RL$|2egUF6U52z"[pϖ@xÒNiPj ) 9|H}563,?**zC-?d. WqQ g|tBc ST ?W橎e:Я,ו]Y+(C^pQ^^TCc:OVF]@caQ[8#2-XUȔZ5ѕcӂKٶ׮S]~nzw|h3ʾ[w̄mÞZy1#T<}[Y(cV͖>R'"8ȸYIwdX(LwY9n‚wM+{"]NDLdtDgY'L \Źy> #u?( :>'>~qUa>q9]`L7(XtF技\[@+9+Ӏu]g\?iAM-{M࿔*Od]ۭ.k$z>*~bqm?|baTqNryDN9:"2'Fh83ڡucE+'h"-2~:F~i%Wsc\H|9li ZpbLY #W zdb]!2"7F)6_羲:rzxtWJ@fF BϺ) YaCw9Ojw~4Hi3wH8-FI7Y4+PfruMrp+Ӏ+rF̱ΉL1ćOJ) OҚ+4fՀyWn*<%u/,YN`wZ!(LGK VIN`o w?5r,4]{ЯmAgjS砯a,'$nAw7p^5gKsf &g\_HC=' y؇QPKf}NV_`NBY0 v -,*RA ߔu`E8 Tl|מ)ғn%L)F1}'kc0L}8_^E-T1Ku{{}|z$$qL+LF3Sbj@LXuNy4 *'Һ!>#[*RlZCXV@2`aV +-gdT'| E19Xu`-VR-ܝ.IU @g^Y̋ScHOE$_H @C啂Ès>[?BW㩱BTu "aNY^prC焃½ 4Eˀgryc:#I뎱~[#]sa'#TWA/mݣEa+ib+|ܞ 7XT'Š3(A0M9oU WQH1VWh/*zQqOCUÌ81m&ސ/u휫*gR/5H5g!t<3rta#ӑ T 8u&L\SVO(x9"|+t5_!ΰdr hWӦ:xd%4 :ry'397]y#7xX"b!hx'@S/uH+iΌrgeFd_ԥcr5t|%W3d宯jIUǯ,ѭT +^~XFF|J3P+US*[\RVH;>%&6$}(=0"f ȅu3ȊG\`osm _Ou"dǰ.jcw\q@ַgЃ/MY ?skք첋4' Qf_keW`r˷HxT.9Aļ>>8cn{U*[qVjZj OӞ4ǦђW?x+ \Q1c;Bp)y򘸘Rl|`ł]%?Xjb_<Ᾱ!}GD\lFZW"U-iUt2WJjfp]E]Ҵo76iolm)+z%$gZCxj1uPcVD,Pt P/tOnz SԂ_]< c?\5%`qʖq>2V%X1sDI+Υ˭ApzDL|kZ:*:qu9NPbbɻ&52/8<&~V8aTg%?3]x1#g [Ʊ&5?W?όpaS_ WDj(QӀ%>h뜐oZ #S-VI.cx;XG-X:{ q\?:84ޘKs^,,0cDZ.pЁ}]irB\ 2f Vǿb+Dĕ?uJ_Pf,NjF ziWu?2RjtB7OTj0'a}*&yR#`չ+ZWDSIbfBG,&M(JΙ9P"7fЫ3wcЗ_Ww7#+qv'MOdD{Dn{B&99 (mH"bZG(2 Ogh^p=iuhzS>0sP 2YU­!baY] 1PъI!jpdE6MPf 4<*Ϋ_i;G$rnHp/ۑ ĕioN8Ax7WP |3`sd񳡛׀gȢgKWe{ΑУ:wI~PG7TAqp&=sU+"*}*:F8q gfqs=>F)y,B|ZzNR%n r3S5wU37d.Kh=s99f1@ W׀P_ʱ.Rs J[h"ז+ VpkӁ:P|1Wja$R'S@(jI[DjT'3R`9#C̓7̾y؜Ȼ3|6Q#TtGN߬Κ 4*7%kXP8F{4?ϑ}ud< | q t Ոx#T:S9xfJpJ >i~~^8X߉q̱< 'U9m)JvJߓ>^pzV߲/|̄*((" \ WŜ|VŜ#O Nyah>?_'?U2 ״> *ADZ'X˭$5.m>:F+2MMy: ߭c']ƍ.~RabO gz},ssE+]zqD}O\W9 l^IdSSߘ#º@+.>Psju15糁.KF˾H1RU /Ru|Os%8srS EBZjr֚oC=rMu ZU|Uh n҂#D bL 4"+b&Oj4XW"F3'+%HW$dnԛ pnNhdc |l$7L(5ROĜkzv ḣD3]# 3Q凉;|'^9O\ߺH8myhN8*p*'+`7)hu^vVb gIXlyVSDtzz _; &\+Wg]Ml{靆3e5FU (8)@ĿEw1uV)xNWg̋S^ ߞrU WnV%%@9zT'櫲>t L}"wg\?y0__ϕR2%0h?7U1T쨋yh ':iLO?9p_ 1~8wEwUEVZ;YCc4 od+}k-1S U7&,5h #;ou\>/8U{dؕ^SEh%YU=܏+4~b`(èq(X3k)G*6)fByrQ5~GWѕ#ׁ~ ~V6p{ c2V*3v}4]T"o:I|ȴMs#X8fNL?y;^FoJwO#fΥ<Fk90WY ];g *GR@ur35 xm𩋆H:p7͒UW*7:C4(k|mzPa+֒\Ks+%VӾaΑSUez`3z9[g ig 9M&}> 4DBN}wG9k9R:Qa$ksk$ճ+xcx}fL@\ p-?2jfMaC&pT ~W|I¼y8/ *3fG;v9JϯːXH2Ш9 G㑺s# e%X{7\+9-le⟰,[c2 [ B` 0rPhBT')J0"vd[zF0֘4i온xb, g4FD|ᮮAҷzAtHtfMGg}єlN@FpZ0$^>s(21q21Ź,ěsZ>hܻcnIjp2%Qx1*jJ5\qϾE Y]37zV fV+j{뜒#?Y;YsZ$ t1s=OL W}S5n]Hm8\w(u!yNﱑtM)r)` F]Ӂs+Llӱ  H*Zcj;M;x2RuRB9MjJ4G)E$UwŊ}'P# 'lMF&LDt_h ^5Eƞ{}'rN^$&mb:6)k[;w7e+ALkS=3*>sG 9'A>ĸϿXɯה{kE~FuRĬxxd4'gUg%Ɯ ߽8n̸lH<1Zi+@֔beEL r*)۶)tq VV\قJSøׁ-Scv]JUH'-''iMYZۖyWҀscl׉}/{E `9DuLl}Y_dM+$9I SUaaE&^O Iul[Ձ"V\U\]S(?Q ޗЁcE9!6 $ GN)xzs=/#V66ܾHF2RpCw]}lW#_d>qMJi+n/Ze<"bTM* Z/8Axd_Ar h+ =bbYUt 6vwsc< wXM TAJNpq5cEɹdl:0*@-|SA Qoo30j;I"3"W¼ӂp}FnnrE LI ,; NzEDqQ!+N-W^v:F87+ʽQ)pܐtD$|pN@ۭ 8ڼ)]CNkuYqW%i"S7G ".^SJ^^!ͭYלLV+VP1(Sd0|­NZ F{V+<3Ԇtسk''C"51!B,<I-suVm8~:Џב-=3+Íc>])U#kC_"u2%֥: ϩM׷N:y@vMYS wU^fc݂|np|QizN\]jFA[ 'w\1w7y*GaUiE ]&!^}6P*wzCMu؄拼nV:PÐ`Vt,u:ĥRq0bm}LJp@ H0]rrZTdWq's1uIЂ{V§I5 ry%4Ub t]mc #_d:*EE@Hq۴nwvJ7Bg#9QOgz|f'̴nAUgd7iY-fǨqnC,#X=D4 k]y>~"8g~y?1{-o+X!׵w<MC:op}狩ZBgON2pļTF|Rq0u *{m8X.Zta A |ZyhCU-xQӐ0bb̕nc+~l c*I \X<4ݱ^:Me13Ek gbh+ӿy@A#DֈE nk$T$6\?xk_$W~׋$is[tިEPzsz#b`t.pPs 0qk$=-7SC}4fScMY|3[]G:zFPbR4a慑|zA{ rۥ׀r|;")bD&Li #/ Y Sb QP9_JVD`V jVruU}2MAw!i$Z~1ˤ98 tcEy{{~ ͘X";tA:z7ʐǸ;sIV)ʍgIBa.s2D>sAFQꏎJI TffN9=4C͚~{?4PS}2N3 b\4Ǟ98q I_>l =^r۳sir/7敇XMjVS27K|I񳑟T߃g3nV[u*E!(5TR05%FØu:w:[:M&`!Mj'qV?_'N Fd_^ IWlq%w-ȸ)C7kJP!6d AhB0H@>RčyÜad^Ñ;Tڵ\PP2~oU6S q/`)nUZlH$^qP ԁ~y~' Zc;xGٳc#zcNJ_ QFPk_(x)׭.^ט_rx"{%Xi_;̾9z"t]@Gˆcu ?jP4DD|7.av/؍qE<0qH^5 :{lӐ!B|;aƻq{zG/3|# wKB\YၞppH<,FYV.'$? ]:ʙGDn)@ a# _;,UZ $+u |<|^lb 2l53#tMo®#)BP:J:{_3X)kaKiN /WulnW5N,0 4IuZ\u` fF sH B«VTkXGʬ`7Zz+@uJ[=$f?<2x 0 #/Ȍ 'nB[iȧVOX6祉wҮg =q}Д^+b#❐g.gb:N V^Hd$\:r޽uz:AG{T|V%a*_+3'\*D4,cbͼa9=s nBIT.' tJnn^z(X9m`鹼j04͟/X1RDWxD?-':i sY׮\1~c]w~h$ZW47?tkأSط٦8*oiBrW2}4 onCלYfDp6~1wI x0WhܑtQ+GykPo5g|Ƨ IzryY _*>[gHu5d$xj0`FÒ$d;K$|aԂ/Ro:}IhA<.IFT;+ V&")P3sSD=(2uA*f0W2I֧~Eh-ڋLDƻ +wO{ed@ƿR(=0Mj&Ulv˫.x&ӮiBĮGo6ϬץĬM]lotv@:'fE=ɨ4Ls cǮ[c>MyӠ/MxZon1^`ڽoodE)|[;=`EVjLԊM獘VoTg Wt@ 3L.:P(HjksC<4Od/=`W_CF0jqsǓdiЁי N+I b9qJ$". =Q5u .En{ʺAkuB /s? iDm Ͳ1#k eUCٜTd;5 &M>uϰZlGdFb/:cT1FdܹKjsY8T WM "c&sT^m dOT"~T'`8:ِ̝_("E{`@7PV\(YJa3{CV%u PxC=ľo SVJFA0 $7ɫ(}0t#Ȫ҉u{s'ᾮrW1}B4W fϒ='穢 P ~stpOɇ5/99j-ρgot\ݘt9=rJpV.6GXCв>W "*cEB +KL|:@0p|_k 1@%"yRJT N ()7ڑ#ܙQo9eUG`/ЮwX>пf̱urcn$u_=i=X]ju r\TD5TϩO1f 85BgWom[d_yŻ͈zY]M\3iW^%2G.FEC ԁpBnkC>Y; wKM*90ȝ[$PU$Y@b3k sQbvu.Z`Ij6P4vq@! )X1{IطgJ,9" +,z-чuEc"Mi(Np,6dR4X4idL/SSBEczĜ_ԑa.jn?Ds|RwusV3WH7`uk٭>_!x硳4\gaF]\SwMxqiA:IDjrvRuY_8W㌏2>9QJU?R'X!f\tT&w|L:19^{ktk68}u4sV,J몯)V a,鿾 q h+qȞ"I ^U:O J<| SՄA!bX2e!B+O4! `D+5OX+3}X1#.INA80Z*:y7F戾GLrd*v{owFlbc]/GʓU߆MCnR_[=Z0 ^ ޾_&N>9{ĠG}eirr+x'V/1hEٿdPu̩7%ք,pZo[V& K|Y1W={VV4~j? Ӳ4 < 7ߞ¢Ra,/GjdK|銅OS {I<ιHTxyb[a?m:#i*&VAcgϢ&a:@oHOM3>'5ڗ/'I&lc߄*R-=j ,ɹyG_}^iܠ񷭔9qeG"W`E]Sc&0fUNjP{QU\q豈2Ӏoy2I|r95]"m\pRc^3GwLʄ2a] 8+) Fu1#un@dOSiJpa J$Zl zk<.z~(\c\,CµJ[jpk@!.,C8|ӡqgdy 2e9^:.Bp,{xcƺQz)F_ߢ|TT|9l A!KS$YQh+Q\ESR^,74NTܨz'%8Q#FŴD3<8xٿ|[c^O&IW<*i+8#"TzQͯNuܝd:5)POG烟muW.PQ1̚Spt]6ށ|`+WZqϮ4%_˿ W+ʿ\X']Gv-ی0TNjL(m!?sFVUL_s97 .8+*.B{I 3QN8 Vu\%7fQ ` fPI\zFü0Gb^5+`ߘQgPkޑ3{o"o1"QOָ'e"OeGwdE kϲhX7*Q>rg@3&ɥtW܅h\ ; ș`TӋ!s~cbFWMxrD+#F?;ŤsϤ~IU^JN dEB&: `E7SbZ `iJ'*׋N[ (+>4 XmgGAnMgK_>cHDEՄ"f),\MwR-\vjp"Qp\-'fpN%8Yp>GȘ11}ojٟǺ 9ќ{oy&gܰ; +. 5]4 ZI_>ޫ\wB3;SEDDO1#+g _AǹR:pGߜVO >* vuIX,qBo('"7ꙉʨRE  Y+uՄLBu2\csӁ}GA_~|i ﵺ i;L~DD^"ࢋGgD65\}~l1:ࠨeuJDBBo;X\̙WI& 7(9!p :M"nUtBC?iL!Gd_~uSGH&T*KR[V̠p\k V5vX)?*O̻+`'wT.n40|fہFE_7-s Ș4<ɎRML[f֋x'qdI܋F3Ɖ-.so%v2gI[qV:@PcJ=f=O-1|b^t`'٪׵*5%8{`sV̫x+_g1 3xv$覫+R8ۭPfv* 1kA<^^e0qE=U78k] lNy1(\l_Zؚ'.-je#s`|]L|tF\$M^wPh pAJxd oQAOd,m!;#o{C27!u  =Yf7݉ fe+U0iA?)&0z W?/rbaL:3^kV:<: ;7yo=tXRC3P7V3#76_sW'$.ԍ)eY~* `|{뮛^^M68blWc*6v*3V"XQ8<-ğ\qvd9\XkH_F_߃Mc򡫼Yf#;zA*hjiǻ҇Z)] kA9g+ 걫nnjNw PSad,(D*QWg]d=+~@TD_ xf7+BTa^q؊u]ކSXqWJFx*ϭH{)'ίN$GfT⮮LW,$'ʾ8Y>P=ccM}c1͊HYV=Ѫ@@(M =р$;7YHwQt7JYѯZpo7%Vꦢ3\u45ϕqbj[!$!{C(:c ~K^ F raсÜ}VL 6ez)K$8@%fY-Նj&PS n\tJhOWgsJIՏ#JԜ} $g`[-' 褮/{2|='z&@rŘRc}'|$S77J__]d6;U(7dNs.*hX}zS$`|/fZS$ڕ^+z^b[殠' 7Jd]C(B(AylT uy柫|@njz¿E 1gP|~]+JLjʜlƬ dBC;r4}K6euEČ-l frE**?QVzYy~z/oUsg>V1S &}ߓQ|INw;WS_~W5]"(ߵՔb[WثVcJIE浡wab]cdF=B>F(ߕ UH/zݒIeߜQ܆l߄tB噽+S4J>>^n;ȻE^ɋH6uB3 Q/ ރ\ȿXEz0uѬZW [6E+ a` {oL=\-LbXl _m ]dL|jg9Nȱ:ĕ\T=(8fp/k1ϗC,FxPBUHX3aqugLo;GyϰeDb|[-qh+J G]}_\u]-1Sv>vѢp:J& ү#ϯ(*ѳ.FxUyzX$;XU'DNtd~ ?Y5Wa]|m|反{rs'-!jx!] 'qASp#EI]ˤeb 46SNC ?+z@ &sbkU1E j x4)Aт AhoE႞,Mr/> (鏠^X7#bG]!o Fm_Uoi?zxfhzU%%[$^U'qYɶ]w<*WJaJ4[N {7[֟ͯ3:O~{W-}tA]'m$^뮯wv}ړH?짏f0ZY1)C`8OK-1,D}gmv| ba rj lNa"9Y0Xֹ>W9 ?LcQ&̾ނMkx%%n+ wwGKL  6u²>#+Uq##7VDp@q?#]$cp5Uʪ?y%jX.}B1>tcFŸo3>ky%_qww&X7l%PԷMh[сɟwگ+BTyc=zsmdJ **Xw`bݮ*"bm$ᠬt+~k}؟Ҿ3Ԫ!mN jaJ2Zܐ``JyCzI>LX]1G*Y(OzzF6s4ӃKŤ?: \AT,') #a<#]Sٳ9nﱾQ,8py7~CH63ѫ}4'Wܟ]6_?+djIb㕑ߌ|Q^ OX|j;Q7.T~~7rϹF:"] j?"oJNB5Sp .[oD'PܝN4mtU[ScMj?3b$VE#+ 88Wϳl~1+"10R 2"y79g.fLi2Ҵ}!b+[n9z%>/'^&.*`W[ M-?pMOvҩ9nS>?_wcݤWsyG9ՒԫI>/p%}'k_V'}jSɹi/BI2 i>.e.jС.c󟬜o;LoOBe"+8IG?]ft3P *x+#=I@#vShM IЀ[;CbzbF?xto |?ZW+ qIȜUr;A~Z`u|>MT-X>Pz6MEP ~nxwN(Yל)m|)ƪ-ºĭ}JVw [eD6UjaӔ|'e i8lq G-[r%1}&Q%Wy9 |~xe؀mt6 ե% ϻaxSHD9Oewrխ^/j@0gcbĶaWe%xHA Y,/g6%䚙\?>ؤ@SǿPHH_b~) 'dZ<-!/q@~b!]b*%ۗb҃ϓ|n5[jPJjf'NX'I1sٵmfy?,ꕸ k)T!&CP:"ezZ]kpS L-tW;fB?sY+%Kp &102c&u+2p@k4<*g(( :v\f2%-xSoD?WZn*TR'}C .O<)AߥtM*+#䀐iCxM y7F->7ذzW˲@#kX-ݴ5iA{ fʻѭ#WˉT}PoW&dg'ܦ4cߦ{5]m*LWZux?g߰+dcW6>k(j3>@F&@gmٱ8WKOC-Xn^\|ݳ,Hvg{lyM,'ou<~]DhlNֹiE T`_ᜁ V,|q\mgw*xy 7r:e'Xd*5!Y6D~LO%YǬ^Ra O:/f5o^ӽ%w+2O+:6Ƒ5!sq/p!&.*V\Y9|TODž*Ԍ cdT7OJC{4!8j97:k] # JG{`Y</޲."}ǕJǫtmx@ :GjY#q=v2 | xGapC~ロRpSݑwЩ3YkӁAT{(l)IqPL쁨QK,XЕ ;J>x||hmf@F? E*p%2E҃=Oo D?/!OϻR<?;;"9fɘ+1k=|Es&~{{B m;zӎt TZ$bmSZ>=sC< _^{խWoɹٻwqJrϾ,Ϡkk+_g&$9F~)/^ [z@nȫ|bU2z`n/}xG,hʻgRM{ʈD"k=w5*'@h﹪=!㵞]+iDUVrQzUo8hݡ`¿ .j@;I(1F~tೠ%:r|d #o :W4:2a1⊅YxyЃzһr8V{DˮQcW{;3wUE)c}V?ϝk<ֻil׬[>{=5b<ӟנm/Ͳ_zd#y}nsdzsF|&2SXOUP|x;<챰@F,T22a`>WGvc[xλH|JUvM=W޽62b6@}U7@tb e-,qf3DO'V |MmbT'/'pmK"xlJ |1y)R `^kBn,y廡dH8。o׋Ѧf9yN#شkfuJ$Z`bƎ r<=%&rOeblJб.=z7LS򹲮(UkQa ` A,abߺP""<+nK(]gqV 4kOW5<@J#Ŀ[Ojib# ^5|my2XLAG߱VЉU,ёDd|/JϝB<:Fk bxޛwS W !Vvςx 6]k㚴 >)6xEY#x47 qp`bAj> Rlёi},}7XiiQ9qc )St1b5]kRH$>D9j-+xĸ~y}-,e&&3sw苿C*<ƱڇՍ{c>A׃c ݤ7 GyI#1{x_ܖG#Ѕ~]+1lUT,i8 rr ==fQg vt+yȬYd_D>$u!ߦ1殮{Q9oxѻ =>́k=jAT`GIhXjN AmsUσ P^r0V7p,\Wj G%GOJwiu+*2h?.M VVpPK BrH$ws}Uݧ(:G>9u0>-ckCK 8~ԩ@yݠq~ޞ]YS~94ǎ֢06ʅo7Vb 3n~ =֫.FOgDF?O򣢜#X=FR}=wj7Kt|F} ']2/:״lzi^ط+ -18?E~`@Ή^)<*p8#?pA?gϟuQ.֛P=E$zQ5"^AjG|^r?dH4ddZb==[8󞤠S $D%n)3]#=yvkIq N$W}/Q# =~ Fak<ܷ-^ DM]Az?gm5<[rJc5Ve^{#%;PB@(MTl늌hW)#rܔ_WU!f K."Y\uV; }DCh{{f4ǃ]E:)-X?XMO9),jO(Fxr?ZJ' \İ{:P\P< d f =bi  %{YvKGX?w2GYA ۫ VF0ywgxgvSo##w-l\9gc9g/{yܿ)⌮3w$T#*cpұqt Y.d. ZG.Vz{ҭ`9PԟdTӂowwH˥@|3yJc9ٌɞFϮwgS-PgWk+sgS1w ٸb=U߷ä d Ν>~"t}}$=y" vZ;3aub^X¢U U>dC  .`>/&;}'_Ju~^M6\{3qzC =kXw|}2-9<5#@'1bJ x %"d>%w+{Y}Of^2m}QnI^3睝+y߃ՀD ,@sC-/pQ`d.f91a 1*_e,XߔL+1(4 V?&MWp⊄)>:()B'W~D)1>g#Y.[eFy.#%#~X&ޏsn1YzN7(F}(8>^-JB*%KU&9- 3ߔ~>W^sw# u֍6cq/埛҈V$ՇΉ \W @|T wh, >N <g(&2c1qy`d~N y|?Xoz`*EAa1e 2_X?Z;":+2芇u^t-NMaN8;ƫ\ {{|a/p#c^X9 qGQ^x̟s]zNO=քy6E zE,э!c{e&Y zijN>\K$d[9=})g?79)^0 *ֽ ٷ`QD;}'I V[dC XH]!"JTV!/苐ECEjC "='ꞨOb3˒= XԠPp_;S3xl^K {Z O~ҡ*: QTFOO. wnPNM՝gfO$ܩ_SNg齨Y;&߆{nǿqmЯrinWԇkT8^B)`JxF<>?RDrd4j^#'pu/I5nUohFFb^?'kN[wn=Sst+P EBQv(#e >9Y-?3z :pF8Ζl'obk<5>J鏦/F`;Jm7]-WYJt@CqTgYtPwi wKobЈ{͒xogm˺'Bf&~_Wu)D6fFyLQZB+O}Su ^I9GScxW{v{.3?GnÔ};%'T9dIw?.ޠn:W 6TgKQYgwyEk.[Wk q$:ʾjaSwZ(1'z[!.ڻU G:<:u~A̼dn)s-WnmNf6ca̰Ju{e^Jr^P;Xցص =q6Q>4;.eTv)Ah>q,V eu#9O6" tuSZhO=;75WZ\Ҁ&4WWЀd(Ҁkq?.>kDu͎wNXrgΘdvd_B<#bNG7^91|b avPY#I?3/wLtRb"t? ^Ss6,anD%mS 1aك|gNxF@Nj@ߐ|A:::/b c!|R`o=b+FZ{N$a`?  ~hW:CLg%*)=SѨ@ngۏwb\߷Fp˗ϛ[۾=IAʟW_ߝ`TξI4k}Ms|cR5rZ7zpB= B^_اT/Ĉ㧟D{f9YwS;#/=4o;d!뻲Kz %VAh1u_;[>Ͽ/H^=r%Y}峲I6i]$]ZrVq F˘}g#(nQ-(ZZM(]5Lj/i&1m 6ܶ}o/iςz*l`d!Ӣgg#a.\N -pOT-SB7%x2 85h<<3 d"n5WW1=gقpEWdL#R=lep2dc5CP$ T|mbY3Iה9>@Y6KD`w{ mA6IE;wQ7}|Dg {*ͽaɒ$lքo}_۔l7*E 'yR?3%WLVuC@x[m`ц{>`Fgf+KI| L>/]K7=Dh9 ]i3ەXϖvqa8s8*d-&[kF)<7[:)UzN/Z-zF^#{*dA2pO2&h `dCCW}b\wr}Jb }X%ݥAgaYN?}ot]`2c;{ 鰕s'ir\lu5[)cfF>=<\HW|`?Ep)(KÒ15U$Fwۗ ~f|4`$3z 􃖃*>/5zg>`=9躊\%[ ,Ҷ ~Fޱ1FO<?=S89Ӑ5a3+)~8sh;zq<]u&''`O|R .%z[s# ~, ~@]&gF;3I2@=gAY*M:'0,׺E&cs0.ܑW G(hALi8*bV%[bM҂SS 4=wI8DB^3[U Ezja%-X@0È3d{xߺLP \ 9>W"d aU-9OБצ#Bo9͘λW(,e!=y=jlJA'U0ᰈJuwG˘=0V#!ޡ٭c#c" RvVvd1 Uܼ6O ^Ϻ(A:vx`iTk!)@h@΄YP-$M%Z|ؕB-6ROd"n vc؈Će҄~WXW478\6tF^{E%ߊ\N$@Mۜir(=bt' \~O'E~~Գ]k.̳73ysFaD(s$[;L%J7!нoX0Mh4)9Xf3l%A ʳV ق@Zp-(+()MLòP?șy|9O#%σs6up%j'VĽ<踝8^`__yua\k*ˏ}%jO6̭tlnǓh7smO{a){pTP _[U<|pT}\őoWAGA(#ӱ:ko^B'|/q.&uoa:l"<VX&wsL[{^OYѲѵ< ͊jWds^[W_3%j0FU |P'V:V4) *gˇ8ȍ*kS'aEW Wƹ'UyݚגU2 y x)B Y'9՜fN${F^?uϙ챯YGG<դ2~]qvJ9/g__l[-z_%+ Ut^ xŲWa=ʮ[QZׅʋJ4t2kAWu wwʕ`~[;GoˏR1?PGU\EmtmR=zEa@L?zNNƿþ6p'GMH0BA:łYqx\D/,  [E&$Ϗ^3(\6%Jgc_ƆgE,ְ,^72J0 :dMJQs?=V#>Ay=8w+/`9_ڥuø'%`"{<tA]9>2*mGzdc $-. @-Cn53 /\kX]&֙6\zN|ͪпc_@=,R0EA&]?^ 8sQkV˛ 3?4رw[+GC&{'0DF0`X4 l<f2[k:p`K`#v{{)|8ЄgZ2мpqPpxC6Et]t ve`NAYxחK]~3esD;2?boEv傾>sh" .aJ,Z8q.v@у_{sbr x硫X.[P c?d-*?`7O܍]++J> a<#c"k+t2%Wz--T & *%΂AQƭaΘ,w)k]!ZP,f#$5 ϑ;p(m&UL| ϵAT(ai *ҤĎ|q%)g=8|L4m ]o0nGxT~zYY?I`by톯/q.^aT+sھK/T^P428Qct_aEo=x|6pVQfʱH5<Ҭ rpoxlC,R7/aIW5y)WA(ƿ=Pu+%˜R/{'U_ Vj:vҁm`T+(u5wG~?_cʾD5X}e+5U+%x`CiDw (߿op _eAx֌,G\kye nO`uG.vtܯ&.MotM(oDF5GS\-fK=f*fsr;Sa3 gY9V{âWskf]!rELD< = /v͓4猃U\ZixmCx**FϮKK~^8ȄV@?QЁn+=X={c90-c"ü55u[XH58*~ArNɔ#AĿ}ZI|p>/CiX2> HVB~2CFS&G]|g n=ΥG*,_>\l9طSTB="1<M>H3 A'B׹>=f#e& [̟ b[];/H9ml_,^ RӐ^C?@PC*8?cEaW|>ЁkXiҀԒ\PrANg8g)1U#JP(x13_p&=9n 2箵K(G鿍9kٝgdNonuhO 亴ܻ#ߢ Ωsz-&=6f>*G#KF'"b*Є}p+Q;͑IvոZ։V5isY^nL{FmT3}gPU(pl<R~HHGy ^Qv=Pec̤V\s#+Y,8[XȈ d6Rp}-R}1z Џ[):J^EHD`SϩµR҃U뗐1 kx¶*DlezSbT!z{6+ꙮmSآo`?_?~sk?r-Q-uԗ2. >=lԐxЄ^uHLx c|yLܷt}v4mvK I7eO#"~w釣ׁ?LNڞ+gbjǔ-O,\1Y[,D*#EOS<08goEhpYOd 3tJqUܥᇤ%K M* wlu# DU/KdPE;# }bfK@,5,,YȐ;c!ԭlDZ>Lpttg#X=2T`+EFiɞ j*O֜SZ_-$^꼕7d E\ WJeAwjZ }/|f)7WG`>JWõĵe% wjtp0QOyDD5"~՟x+J/+<XzsmX+2F "fHj/ NO<ºl{~:HN7C}B!O٣"×<1;7u4[ ߉2`Nωe_Hݢ:?dĸ[sd*nk[5 ΂nW1,@vӃeTyXexx<|ԥ ˕#;kW^>]Y뗢)cZfDMJНnF*^N]Is'xj #;ȈyKʸ4کqSgwJCckDUE""lGlj:FPޅFHvaZѕx,DoyG1x]噈8krd#6o\Œ3_ X9X˹ڽJ?~A~|IKȆv\zQR,U #ߩBfcg`ft@V "lNsFӣDϖEG1=ʿJ~3s1b#:1=@DFb#%>\Rz 4-? 4we\V&W1oWm}r"R֒Z ْZKi]QtzKzD t3bGw(D4+M.b^L]/ٱء}51Z=ۿ iIݰ& W>& Xyʿ~O51ee pN7iɌW`YDU t dZK"xق,6 .c 1O=aQ .4jA9s_bи,I+7pr"YeN)'r ޿JsLXgC .)zF8y;P3{yߛG=؛Kv.cnaO5l-3s]Sy,|l(:= lWN})Ow[哠W"/L"$k- [ٯ ܋Ӏ= rݟ.1˂/B_5Paޓ9EB s?WCMoUM [b\xV 8J+j4QpLWe Yϡ*wSP98g\Ȕ`HE/*R'$.V 'l / B-^B&yt[qh*@SkRCV?M\}d\=X :xg5Ȱw 'U%}{ WwhȊiGn'r a}?G{@JHdDXG+We`o}@`vg㳳!$WЫNx y0)sU~g $^>YЀ-9$̾C㟫\NVkVl "v &_1fJqxVCm#cE@?.}"c݁BmlA]LRăsY*=o5`d=xx\\wBC| Wqs<l`={$Lʶ0ײFQK'1*|mosHQd_ _zpb1k˕~=>rVz$yNʜz甆+Jr6Qo)yL-%ٔ0OϦgpH+ʖ1Bg|j%82)@C=cp΄׈ix퇯yQyD{u!ZYĺ VvIBb "5B¨EmUbHTUZ..4J:N{ ܖQokt^PRr_] ;}Wd\o$fZ'NT}AGք}z8%8pYs;$R5jA7 GW5{u_A$le?fA֠c\K%sX w"'k |i9LBsNgpԲh_d{l${qVpۥD#%/˪EMY$cYySJ6; G|'uY%,'(Ʌ=GFEc(ws+Qcx=wq?sv%2Nʝ^z9Qzƽ2Q Aٮ}cx !sGM ^#tfەk @?}Y#H< .w3rMpU'!jKمi=(ִխF_Ț"}scׇq<u@_1͔Y.;ӧGLI4 $%0ɼHIgeJ}/ۏim҅Lľi;KěsX=oI߯"rdzRk, ]B"\2>!Br|uA>)=;Jo^AAK`E_!=)GGf{'nG;V*vP8)= =C;* _۾G%~ ҷB,Qv{WԲv.Vʿ٣60OvfčԙHvϓiyT9A[)& (vN h0؂gQrȴ1z,gz:YģW3dNȂ{l#sU2y%*7JB׭bڝƻc甄Y~|TyR6e[*?)S4,~T(a5/+/[ ,Ľ#U+j|QЀ39*c$4$[罯{ "2L@ϘY8 4`G5fi A:(7~'(;|~RQynW%ˑz_St$dյl_dA@\z_?h VU>3˃f < 60@ψa콜ib\!Feq˔ErP9/X%(ߒp)(7%Flھ3 2GS\!8WX7kԛMgYR8dVb-}[y`Sim6%NO'(XƇHauu>)}d:w5uѠ%qbxEݵ}FǍсg%GB/ZP[" m+CߢJ> y!l`xEAc..~gz3w|9p80a>h0hZG5wX]tY;ֵoOY|hsxhC6ƭ_k GcnLN@lKӡ |*3?r[#l&; U {\j!J"2o/3 6{/(B,ѡˊ* f˔򯺺dUSTRU[kWjlX,L.[ݓj#]#˼3I`WyMp:]97iYًgFS=]Vj‘5ЕxE,ɀGϠj;L& ^FF*#5YF''I[ Q1},b΀fa*(ʪ"%`'x< jq:[j-f9K~K g rzaAr2y|aoi(sNOd:Kb3ųDwGS]\NH(Rܔ"KtEƻꑜNC!=:i9RUt&V4y h_zG͈<1vBCSxG8L_5jـ~ڻ@ߞ+G gϏ((G ϡ#gCC.ԃ\[> ׃>6@vi8jU-[0wSpϠk9[1]U'DA/m}I2/5>"[xqP,c}żjGe^WKpSN'CBIXصBWTbۢZTNv+g#OT`Y/Gd:1R}-OL3G+=+p."woTy}xkJ}r-]]]iʭPk%E ҉Lq䃯&*zb% vEx!RAx }V0lBV xz*oܢ Y|5=8ZVpC_EAbFd -8JVg dz )ЁvEX8Lb"I([YpE(8[R:T'|+3/jbW7zo8(hyS]V\eͨZ.(6o^Oż~=N~ ;ViQ($]Eq柚 =PQYlN"'sO7^/!ݧbpaa-W|V R|խdq* sĤwzrKגBzr } {[؜G0m͂|a^vd[W|x9UHq^')SHpbwe"⑁DdL$-s7JGhžQ )3L sXHԃ,( ( p4QpԬP. ZºG)8t®̽3z>XIs\(5^E|HzU~I{PtbOu H)1ZO?pn6XJ|ٶ'o`!ǦIZPlcA^JGJCd̠yG"< g|+|eOww6"6\뚐v >dJd<#7׿ScJyO&+ *kUd~y\rl"!y)Q}?lo|?CRc u>,`*^Lo\r6 TUK;* )fs`Y^39eBׄ#%%;Oa:rt$N#^Jp!H <9FKf!3\byWoN9:H7mOW Ye:|#jmnF3V۶Svx6!ݵlbxzc_ՀPτXo3>ϧiM0(wa+D,WijpfeE%1BC#, R{Q)'_50]u@>~ާZA< ?ɉ@1#VdPFnXz@AN# iz~e]lA.5А)?k0QT#V}^{oTU{!ߛ~R'=]wpGY[g:~-Pk]^Rs_38AD~Ko7_A  (vpWƠ)S& GXkFUtdL!f0dƵǪ zpBe"$Q v/cIJ>[9sM^wߩ.b(vu 嘄9 6lkVS%7< W9BŹk{QY'>gGen{e .ZVdUpۅ8%m|#֬}:hz5.*UF' ίD)ҁ{(θpE(P0?̗?'Q-]Nꀥ'd xwbmy/'́E'3 ^đXI 7fGC@'$wʳ Q?b2;):M(1+q?Ǝ|cIp @awA76A?VȄFXD8j`RF̪oU)(U 2f/VG տ;QR:2d(X_}@s1DnD(8C̕`K!#^">_jd{>BtZx$|oh/#qUN9muζ&J\˘U`qKswϹ}SO=T2\ –}TKybW($ή o̜ee 6>1 ATq]10˃Ay',P+hȝg5,1tB:I-vrGToߞp+1o#P[J-a;o&F p sh`'P˔85X$MvZl3^B:%yy[W-|RҎ}T!a8 qZJ &M!єyx2|FI.uDHjQ>:i8XnuQ羾iV}R(og( FT{fqe޿-%,7ߵWtLwMbߍ5;j|+;c!zq3|Gjj\3!Wy8HD-^,ES爋m{ ݜKfxI-##S-3$QQ7|goy1`!">篍BWFKs(&W0[:cQ>`to쮐i7pb!3L^y\-P;@PmRk={j;$7Q54J, VGPq:ItU/6A1/ TߘQ}IlѾZ{}=W{{_Ź^:ZWL۝WE] ^ǿOBf-(M*P5 ё%Ryd1bd>RJ"V2Q6uʇDC_FȩHGjߜys;سe|JLs1y/pV50NBWMcJkɅ%x0X %~;m%`Kmm@Fpo#m̓cѯT]޻1wm/};!q DW,Vc Aa\5j{FV~8FAmV Lb_u,Ѐ%bt$ZP Do>N pAcŢnw#%W,PWD?5B{nz"_/Q,d]vWD_ӃG :WO,̿[J =e8uO+BmȖ/0.S,)YŪ*=H#b/^&tc^ vLE0G)H}ο; \z3z UYb'ѭjJBm 7![+5.SӁ'Jb&A|>ҷyV:dc6x"xLQbG," =p-F|Vv{}ֈ^9H"cc >ֵ#GJc,=hwCe]ԴzXj|xWl䜕M~Aƀ_@SL{x*lI}z5D.5)nBHyY)%~>3^Oؑ EGyꑳMĻHhll8O>5K{J7@ր lXJyy/~N vKj"= D vO wz0y0&]烌7cD؞eEETzz-{_PF 1AP3ֽοIʔG7%׎DQM{i:n.t:Q_~O}8we4̵}$ QZĿ> hYXpu+ ֯+%b.RQt4aאR$Ea;鸗`O-Lx=ObBļq3ja= 2I[.VnbcTh)9r.,`g)jGqRA5r|h҃k'ʝ$Ԣ$ܷDUKuܻ4pOm_&mH8(4F86+A NiAAU1"^׺Bp;2S8eQ[TtxtC#YVܧ1p9q|Bѹroʌˆl/P<˚3f $-PG ,zu`9ex@ؾSE8vұpc>l2KUlۖ"bo|D'E@wUrEAƌ l;{x(X6Ѫ# #rzقAhVcl$vYl*~c\ǙOeZEVfmx.Ή8]ʑ]{W-wQɅ'D! %wF%Z j]k|8U"CvT!S-k'gi~r|_9^R* ]%wnvUC~1Rӆ0ЩTU`OszZy/7Iy[Gm_9z~L9X 4!XqՁޗ6vp`Uu_Ԁbp1+Uߌ,5erMqz9DĽU=^]J@|*kK//tפ6mxxUTH?϶mЪPP<ͻ ;(Lڂsm* ҃>Ωn-}fZ*J|Tr#elC?cu歘}l^~:ҧ{OLNSC"Usw#T)kXU{<:~W˙yBx9߂*BƋIS تZA,Xbܽ>B \-bfpIGEL1ւfZW$>:TֹE|OڿOwFn݌}j C1S+QpwU{sWA 2oH-W +vd\.$λ# ZuOX8$˛qEZ^ [wptGcMkUخVٿ0o4 36 FꪱkyJ}+s"M잼O^c׃}{3'ygTLI8^'S45ฮcZ  A"+pqVFY630F3'Z?7=F+L8$l?0ZWgTGN2Ϸ?::k %Wzte~ DJzju8!Vjbw-jD̃_qe|RL5KEsJ1sJ.vN<(-tb+B/$ED-bX>ZϚ,_FL.%Q$^Ba(YYx7 !<6_?|ׯDZz `p S(b #>q3T7ќ8ma4Jɽ~Ie[x ,Nf"5KS z= 68-:F ĩYa<>NUrnGgv_MOˮvsp~ceq:/#0oH(a+UYEޏfmB9\ rg-_R?RxLT$XQ%\`*T@Y>`B^At25VA[^݇1 rZH4>\JzPXQ-%v.OIO]zm2m((K8ɿz9X˲ݥ}&? <םna?]pGV³ξ{{W`C~2+XzWӮtIiI]O,bd0f{שwF߃D@5<  pdzoQT0j,{FWQH/0zu#q]I0ipRìh3̇ŻyO.9#UxJwS7)3e<6[Ynbb~+/\WlqmЖ'9K3DMU̼㞄5 3HIA4D+L)ϩ@%Rbqb[#e?6䣪%gjyu6?8-}(W%}_vS@^u+oT wY(djϯ]T;$$Zp?'yUt &=ʵ*$sf,K%:,tbj">2Ӓ;Chx.m^BǏ%f%zV޿IVo<1}M- (5ohs6 rAvt^jxi}Dc^`3JD?D, nzo|րn|\3lj-;."ژ5!@;12[V5|p)$3x1^C#LǪۤ ;sZ__όx|1 sKZY ~5=T,Redd V& ,L쌷ֽu] xm dH# 2wH *o*زk|VI jC6{eJ6 P5 R0 w0RY0cŨeÌ*FE^Uw.:;,8_psd5c"`INgNs_8I Tv&T9ʂHN{l;ğn1cb(qc:pUpLff6ņWgaDqUDA'cZ>}Y'~;EVO\ ̻7X/J?tR~A̻Ь ci}1_=9,Z+"L?"}w+8,祚ꋪۏ}xbB|c?xɓ)l%}+|UU`E9^cYm#a;̏X':Z~B" ȄUUdzl$o@w?0vF T/|=9yi5ThPUNy80sH) OdQpK\^O-O*-E ii2uf*[Ku ˗ߡ?/Xj:pƼ36!1.03-]'0yD$**9$ӹ\5=2Eo{0ƷFC҃+=W!ї2zaôەl"!YK90bP<{A_EOos>&&'S1S@i E@.R} nyGn®njc;Vk۰~|}V( p$*QJЗBIq]}Ahحi⧪?OFT^o58bOwb\U)@ N eLM)󘍓vTT|̧~5e\J PpO)s}e&U| *#/+E"~vL;Uwl~cbXfk=4_gCOV=9h #h GH6|?Bxt$3h[[9 G 3ч(Hl^wRF=dp}bhj]%od69o^/ "puD7 &O'bWy7SBQ_uⵃ?\͞Sk^h8=GES.{3[!zJvsFOY)t׏Yx''&?8SVzaS">46V,fGY$b׾(4G FK#%D㌂.2KXŞEB'n,F2{*PNc*39V%b<e0mު;ީ2wɴ;*ܳ)\u}ZOUu>NqZXsFEkYnfyǟsF8 s7{Y[j~Q@i%H}fN8Ą=}_pXтQў"G4ibmfWǯoJoyMO$lRQ+2 a 9s^1]=H1gΜ^лBgZNW늏y+REq0IB&l{_+oxX*d 0p˶>wwVC~A'D>>=/FAd(xɇ}źÁ|4`P&iȝP=6{I\VbFm}BϞ@$ k'xs WP_ WVs cFG;˜fmvތHC7;^0^x*4jp^}LBԒ|!($vppC+H|X(%r[;|Qi%<~lc!ywmyĞF L ~ ^ׂ ZE?ޤO7 ([g+|XCҫ^{.sPQFL#gq4_<\aN/߭bd\㽫1G'p:0~DN?B ̟Ǿ@2d* Oc"􎶬jKoz#8)WDխbYIȚPI %J͖՞ Zⷡ'uLapwB&a3wy8bT'c On|S`%fm*Cq"G&噊tuX_X(jG|tmd^lY%ɮVp/ַebhGGХogd ~r|R!ӥBI֋v&_&U:N? 3p6BQ,C7=)#/55Id,еH`/#D{Z  :lmiE`tm<ׂWvu3/n|kL Sqp7U1|G)AL}j3=. LFc]4|F@98@tξ_3!!Wf:QD )ϷeIB&* y*X@=Ιg # 32Oljs`>N *=Ad{Z(j(zV[AȎ ߭QO -*~5e a {4ؽ`0G"38X0 WŽKb”fn3-Aޒ¥+?}B=g_-Chnd@]:V} V!+Q 6po@l(m6 F sH{!l7R7470b!>K`gҁųt䟏LUw [PAM$ @;ܒZ-VȈwOnݍxK:f7**?Jg0 TZ`&0asG.3ODAaߪ/D>&] \J;ē獄fށ̺g0x1/jSA ^XO{6l#=.A(BQQw4 }WgƱP5(_9y[Iz Ut(y/cSOl_d3mI~n.#ǽ_K#E ?!ygk}а* >Yĸ"y44 a"E*.] [}gx{pU ~f/Z1O#VQZ4p< 98l94 .eۥb$OΓ$f!:02i ")A^!ٶ't< 'o\{BhupM0|nVp[+%q+ĺ7 酥+S"+߫J17oQuY>~O}ߕ8ǜwWH˝*>]B)ȶXr?Ɓsw(TN?OIO~ŵad|*稩]~ dex}F.)U,=ЌcmjuS o6li=ivo~K[ު* DAV;ọm>#U/T`3 <g~@<6´ci{G&l&ܛ.]M"2.,ʿ|#d˙oD:(d`:s˜'޳ITa`L ).N P09xeMaNN*O}w7}gl_ C> x߂i\U} o)9Ղ̶àoi0E>kcOQ]5oj.Y ߨdrF"6~3t]+82R;QwA/8sp66U+fN>wS6my畃KZ2'҆!faJP?&\98,mO|8c{|FWAmk&`UUlh{7cC9bgS9 5Ƕl" r11Z0#7]p`=sS =i*uޟ)SGrK8z5^AaW-~^WX4wŪ}5As``ﺕwX@͂[7Lw5qY0=VtZ(}x#s04E4PpÎ LF{>N R=Ҵ9ܤf>H1h \X3ͷ\$mG=?L:sט~"'%^ pU!(jp^5O)bLYdzA" f!N?!ZƋa#j)8/u-T4G9噄 a#C LcXVAp$ vq5%K3;0F$2rqbyfns=(7XQ=U')^Spy>f!0!GI|O <ă!#uTu4qzN$.-aɄnnWe>60QjD{~RVl1wg9`Q!e5pnTPk软]Mn㺉?Z<U$8 9)>>ţƿ1$\M$5+9YcptpfCւL\;dX`]\*KRiL]WKs]hg0}_{Z{pmu!&o^!|H^bVb!X@P C*8Mar~q ý<|`jP4eI݀#T68p~v!o̭(YEi6^na0U_MӂuO0r5GtJq[׆]1NGЄJB`2F:?느k"<6 ~6S# cp>dSCk9svL r_#o{YcCORS,^jfZf O@Z.݇л.j@(űsE΢?H&d-OiͼLӪ<(Nڅ=Tk?[7Vr^ -Ƒb}1&?F*VN@ hJ*N2Eޓ! t{Jc%}IP$MK9:` PH j׌Fg3m֬<>O0m:ӕ諪BSWIKaSzqv4^8 y5(|X[b+΁ji[VKKg`܆R\kQ˶rhEn9u^|Mz-ȚYq @^C;!U}ĉ>8Fl 7ePK*ƧF8Wә,9I;YXݑS?! b%nёoAܗޝ@;-J|%]mNvޠu_60ž+-N?o{au9 "rcsP6gf~`f@ssǝީUAUKjI2E. z/0F=ɾ}$V/Ϳ ?7õ| ,jWοBTjֳfxT! yM )TQcveJ, ؏&reJP"_5oqO%Y7κup_`Nf`ӲODᯪg)rInOzTMqSˆ ǖ#s_!U} 9*HOP*yuT{I0 Ҋay05 FE'2֦_3 MEa&yXh[~v$+{s;aǜ 9==G,_O?Dl Rn8;L(8Ob\o.1G¨Utep3hRN 3j0g]#kvq}p*ui;n*&j#!mzc"al۾}wc{m}5USp*_|N{>MGD$,Q^?n >uwAiՁigtj~"-8SΕ}?ځ1ߘ@-gVoS ?,"-= MgPB J0^$?u!8U"Wf3+Y ށ@P8(B?۹ѣ8@+Ș94VUb#4D"{-]*kÞ P< ?+9x}}wֻ60XNjpR9(;Dp7E:p@?*<Ȟ5ZRνbu'࿇?wU JרE9^: Mw(ŌCzq'NuCx?9ɉ?VnC-h?ld9s52wieOs}V'kk>;(8Ǟ3R_~L?Hd;лnp gRwΚ51w؎yf]!W|f5E}4)FGO7S0>5}V_ϗ7U ojwiXђY,aQnOKL UCP"6تb-ݥiKҁ=-ܾ) -?]xzpy*u/rY\Z. az[§SG޳;ޚ;~#BDIVuqSJs˗utQW0Ze=_ w(Y{sֽ=9Sn%; 38eDG z_Amv mςm|1( ݂gQp_K?ׁ_ y̎+&ߟTx̱Vc*]^LY$݂/]WG_‘px/ f% ܷA|t4iviyV,,#x8w>t&e2R(YwvwE:[g< ւߴz;-kmFM3l3VkLfϿdd/ p_ ?7pߜ9rҴY\ [y/AdϤ͕`@]qIs6G]=MO?98"aOb?Xϗvsmc8U;lNٕ&2 .J@UAbW|3{@L1@Ga٠c|Kq EtEW1@im[ *AYsYt1r>PzpYA Ώn,To-G*LJ?ɿjO2GQY s$vU+>Cᜋ㴝-r=D WT#DM9+'Y޹z#{L_H"4\,WeG&_ӕ jcZscz?3:N +txlj ?LW`8R[M?QpZP,b*r;8gO?>qRp]4GBpo+w bristol-0.60.11/bitmaps/textures/screw.xpm.gz0000755000175000017500000000202411233572001016063 00000000000000fHscrew.xpmIFϙ_A7t[hݐf- 0C {դMɇfT?ں${L^|O>d}|Bznڛ~}3|/|OX, @n3~Y{YY\>.4k5FM͠qR]Gs}\?47zռ[24wNr~_kDiObCk,g&Rզ?YB5\>dQ꽡c;m%RI罵>z׹]WɢNj4O3PbcƘpA8zAdpeGD=%S5\F!k:-\gyBMxՒ&0NS$e} /+҈kTm;ajm<-Ia~|2V:j4iy8µD%z4hXLHY;s#sq#-+.ub-sXRhs wNT+ qBo ڳdh/(wY2h1sH ܮ^B]s[9DHj:sCe*ʘ(Ulf8XD<ro 4 + W#D''ge6GAUGmΫ٨E\)DYk98{DODG5bw&4Q,ILᄅJf {1ɺDFpWRg ӄh]]hGT l87z<-BFk, 4ėtR4b1h 'uJrb;Ҥ~qI'g.&2=gWN$=>/>(C~#rgV@ps`.?lO{fo2|?{ƹiň&I&U~@.5>o^!o bristol-0.60.11/bitmaps/textures/white.xpm.gz0000755000175000017500000000017411233572001016064 00000000000000fHwhite.xpmRU*.I,LVHH,RR(,I(ȍUUR25P"CC%.%dTT40d0kTרQ]Fu5kTtZs^W bristol-0.60.11/bitmaps/textures/wood2.xpm.gz0000755000175000017500000000202611233572001015774 00000000000000fHwood2.xpmmV$5 =3_QsQ-3!]-7ǕV$8 X $ĿcgG+Uy΋U_}_]_?o_|su}rso?r~{͛Zt_^;p>ٕ~ǻctoO[m>/dJsX~ ^6RZ.;? Ŭ_ kP(l*h]>@ }ʗ‡K.*BC,ar4g/\ G&qج/%2-[e@9"Ti;ӞrbY{%E'Ŭ &3̻yhcxTFLܥY*|aKeeo\vӛO4.R.?xz;.?<}>o/=rq9ћ؈KmT ~zs9'L1:ϰ)MpȣKưHcnYvcn#OX6 ]@vJI^;XDfZJ~eACTưК8-Ed|+zlp'(&$#vB+`G 8ݯ8 P,ƌܚDQmڒ;]˙ J:y =oqK$*wwL2Ѳvo >A=!7 H禭H 30 ٮ|Dm2+QSIX$I_xSuaI@ҟ bVRR,ALBmZetX,\{ C(W/ \f*Ƌ "ø{>Ȓ &[Am)*ʐ,+YA80`;tR*S* ~  A>2U A6l4Q< DYX o۲'i !h'\U  [bLɕ\mh;&dG&VGLRupD wR,;;al)uŭ# T &`//=҃gҠB@abbEF7ի҇mfaFH<^|]ڊX P ozld\_uv_luVW qjj#n7NV,c b~8m(ڊKv]"y*!0T?NJ\QX\:~AQ7~>.hl*l73EPהFNt5 3 Ա;щvG&9 $\5n7{jF_"DmNYHUR#ieQF슑3WqĨnEb:mO^Wz'\-) H'ik6QcCl(D&R%)2-uBNtaW|m-[Z)!C(Eb"ҥҸ=bq$D#;Jsâ]WM6''Pȡv0j4 -}No7aǰ'eLUuES9Φ3oRXUu MkR1Q 0[zevB2> "~=>WNh{gn*<%rrZvpgw=Ɓ-sA >Uz46@6UǍ{Q8,[roS]; -g`pāf Qabevsa{Q/  ܩ,JXLm {1?j8C[9 =V=N<4Q?<D Ԧ׉KDB)Fe e9\;5y sxNe z|q M]Tj:b(pծ-vTO!S{LeEF8I7ΰh֡;'?wCi󸪼q^R4T``ES?fhV0$`X:[~7—neySur_c̕A+F^~%ڛ g򄢑q  דuUE]29v؄(A^œij'1+xZTPǑkܷ-u~y$a I-Uf_II̝gvA&SWp \e J.[,hvkoj IZ]y8ݖ[ K4*o84KE˲В9~'&zr H%> @<>s/t\_Kɯ?`0/-55AԡMQ"[TW-m8]LrʓYTӹL5=?Qs7&bristol-0.60.11/bitmaps/textures/leather.xpm.gz0000755000175000017500000000413511233572001016371 00000000000000fHleather.xpmEX]7|jĮ`ob5ڄ-!c Y݄[U뜹wtF#Guuɟߏ~q}_~Ͽ1n<_ڎᚸ;ֵdنaww,eGxs\xyy_n=XO4۵Rx;w~n#FUv5g`1ۛo<7OOu,XMZÌ:9FlRV[c]! 0bp;WݾyZ#c4 8N ۨtvIkw:"};`)pVntpCܧRr8gxVیB&_"HG`<QG0Ӷ{߅ea^o1}6ژ^{7P$3fn<l4[ ƑHZ/"*Nq{:G Q1|xb3S <=bY[}go9= B=}bZGkmD[xrqWoၳ*#%fE"iュ'xW0[+##L5d$ Fb҄g. 6`q@kLQ5q-*DUFd0΁vce"j߇"Pgn,[Q0H d֖G+ll>d@4nCU~e ֛ oHƇXai,{lb*[l˯]cvDf/hlEG %nyNKdnt,1]dxfAM_2U3h\ + Yd1PX@)>=9qC,  f_`Ԣ5:e~LgT-gIkԒ\5Xd" ZQ2x G̪'D&?;mi(~#Hf+ڑkQHDWȌAUP2l#ڶ"_Xj*O"$ kQ`L9.謓j3BՄiQ&;\ـJȆ %{wj8|vodedXbWHm KA]s+\9ܖy.|#y"Rצ(Cht?Xv61'?)y0^jRjv<|*1h);r4"-cz"!N SnAOA<mh:*Fxڱu&KKJ-~;<,sqB`-lٻ $#@V@"?GdkFQ|2||m5X|oad(G"P(2C saXtݦMF<' DmR#i|٩b$f;(f}c& `aͣJY/̇ZHM ! V 0Y/M5(r#Eqڒ˘#ur"\1fRL|Ie$(w.ޫ5e'/"%‰qTϚ)ٚ$ =GVkGӛ'-Mj%+Om9$}I:dLdkެqNuHeE,Θ/k*%C+#b]؀::%#.טt"[xiЉe fQ&6 RVmY d͚&,G0CrTE["ki65D%E(*f&uKd,I+]> \I%*P1j62"5yhu @)/ÄUE[Dv@/߷保&_>6G2ԏI7DG[ ]_Qm6Q׈#Yr`YmkBN:U., dj"E*E$pm2'cdlE.I V%NNїClvY}q  v?.|+)6A-Or ɉy:'A*'W gJVn& HT>,ЉTuOkD6!b|twںַ|A__Z'ϮQKF bristol-0.60.11/bitmaps/textures/p8b.xpm.gz0000755000175000017500000000020011233572001015423 00000000000000nMIp8b.xpmRU*.I,LVHH,RR(H(ȍUUR25P"#C%.%dT[V6q2v3sIFu5kTרQ]FuQAW54h bristol-0.60.11/bitmaps/textures/metal1.xpm.gz0000755000175000017500000021563411233572001016140 00000000000000fHmetal1.xpmdk{Y- ~ϯ@`p ]v9ΝY}-Kt/k\V슧 ] Xk^sZ5j׿&O׳'_ґt>_KC%!|˟#ґy:;>f:#wx.HMJG:[HS#xLG:t%t9nP:_󼛎t~wH7<>t;w?#t_yӑwHtG)A_<#?ґΟy=IG:t/<ǂJ񼙎tty}:c?zHs/9np: ?txJG:8K3t#OH?džK?ґs,og<#slto<It9nh:y~tt 7(<`ys,ܿ~o7[y:`y~o)<><˷>7q彿QD5JM_s]gWepϯOhM(Vƻ]_Uʯ*o?Il_p:_gr7_Sel<ۿ8=|2}/vcPpt>]lG'Vqw7<ڿjsmLyS܇1j?l8Zך,Jѳ~5P;U^#zlXM+d7zy>~%<}Sj.Vxc&38ݟWsڸsNN_?i`]]˶`{UFyYaE̱xW |~.\\a|~=7m+6`xٜc|??:'v?_';_e_4=3gWk+j\5٠o X+;bZeO k6R߽_KZ u'N8o5ԝNGM!YOd;]ߧoJ먎;j )~s^eW`v^uYLl Uvnx-|lSz}eIt ~iv`'V\êk$8 \a__,uG3XӒoޝ9 ?vBZ#'xK=;X3cxZW4`8ŊJK&wV_j]i5V#\`3ܗlR?_I@{ ޽1wJk(a0~4`sjj`Ke엪VL{5W؀t7G.ӣ$dz[Wރu:oe<}-6j_9ݽ_فK}{ z#ee !w}}qO{\3MhlO83,`Q;jS<%[75`EhuK˫SH֓ʖ"P*3mFX\Q;>wM bсhGx޿{QWHz#+Osl_7ILV*{{_K<a w}a'urX~"m3eX}CܡK땱˰+5=+=2QҚ|Żyb;WϹBm7xڻ- %@+'~o.KZ1'CX,6"VrZ?*X=$L&x6k6/N;ZFqu=Eg ^{)=Ć"{a4WyGxo/7ɪL7uͼ=y-܋^kIfOV}߮k7<~3HabGC!{HW-D,e\yUw ֱw{0.#}{9Zi`G9ݓ'} ~껛^X'|WB=ܑ -#BRE1E.6|-~akŽ,WtS_"l+ՏJ~,`KKV ٴVڒ+I~U`ag~O+^%y?eEdチ?IXmVPu!>StA+ xr Ǐ'|t 2ߵ!J _dw[.د=|zrl|^.7dC9XӜʿ \c8Y} h݂EM3rP9>z3_sf=C|(sz\f{M{})P{5paI؀EvV``G`@#7dhzԍ_lux2؀F{BNqWo^=TI }UGЎa ҽ>8[/~pߪ2lvi&4jg7LJ=ylEk$zZ: _K7:x/[|?97q5Vaxk &[ ; ,kv/]t>c2<\;W|;E_9kuH+GYf~mW>yLWDo`` ÒryȔʥG}<f x:d΅y{rw*lԹKY1+,r3]+, S<6TXgec}mk[C5K13Fv(gvѓoc]vz{#ؓ ~M~uƪh"LςuVZFF w;ŕ=ްQ[㽇_!&y7G]k 2 ޶u7lD겊+Օq w۾';;o\|џ\f{"cxY##fK<{;p O|Iwvzk;8yeZX{_/6sDm\~4zB?8ٯ?_ȑU= cw=/".q;p\E>Mkm7y%sE5|.{C9Ƨ;p {v2wo3 iX5%WGOxzM?)7:*c$%D升ׅ~חXgeS<G%UUHVpS=ޛl=Dt#twXg2Ka=܇QQAZRs#K .aP n)OPǹ<R&0]OAocj /} ;7S>~ +2cE+}ݥ># #:UutV?E*y|޻;~k(rX|e`(P8,#ղA1stFu{׀hTg k ;?:vl?7H_f-DglXM[jӌeh#O(>RA=eB@k&m[vȇg'{Sƿwݸ:񫢧3T/qNuL ~򧪛T3rVMT-aX}tOvk5+EyGZ9X!4 ;*is Rmc&VyB_أ ~_0[Q$#Zʡ. x<`vXAK),g VK1WhE%F3і %D.Ӯ[.W^z\Y - <᫪o^`^{}+ՙ07 >>_K<Vy-5u':[릚+X[Xdڕo:Eo?vw 4{; j]vu UP;@oO>}+[\)lkV^+xMC5S8iU#͙" {ԾZMZ){[+ت c|du|'n\-o<9^~Bs$;uKܥ <1,ڕ~;-/_N]FWhdSEkbB9Y!"SϐI{X;0%eF" N7X-*-U* 0_WR\j쵆ts1KWd:l"@$}.v81נWɍщj5bm .!k>ڱY{J-fGVh!p?u {;BKv0'VīX!G@Ox7b#k+C`W4cqgj xE_~Ujx5˲گ:~^CѦv\ed~նURcZS3v1V9T(A\q\OhV`SdOϾЇ9 *:2 amiZQ~G5;}ijFsU!慍U`d* *ȹbP9j[=n/VsU0/)殈syiiY5uߣ=j᷃}1~8e,8Ob#=:\M)|Lw*Bbg{0~kqdsd4gZ۱VūZ xl1QKȶn㗀e2}f[WA~|]cخBN2V /zY92/j* SRL3b:Jpɠ8ζw*^_y g7xmU@9V@vL +-;%q˪Uda|AP X",(ERf[Zt-(35kqn>K,@2V/Z_~ҏj9ggOi2?bR#sy/H~k ~02%/SFJ;8_pvb ؝QdK`܏LI3!3zڑREIK=3eOΓɡJ?{E`c0K蓱+ǀcD:@_*y+QHEU<@O1'$pFvbyӷVz&Xky:9R(W:~' UdкKػ>@Z1va#?4G漎g|6;D-Fo r6pǏgԱ+\ sЭ*\v, $v^}cF1RT+!a\Gv{FY^"Sl  "fǓGD̈(5#rlXWԲXDAv>&Kb cp=CؠGVM*dUPj [WLDbAt\?)iwxZdtKvܡ"dmhifNy8U3:BSM[Uhw!Ke];YިG u&$vB d;RLe w˻^_nKemd)'ʖ{T 8Wf$X#̸e= >p6{Ak)Z6b=5zؑfj?ÊzY5uCbd{{Mbk`jTM&KXQI\MTa_c,w?~o!OBw MB Z;Ń30˯r&[ANN."zȁ721S5WD\ל#*0T53grp9bOv1UywޜgNT 0s|+Qk}@#4f(H)Wʈ/-E U9 c rF4 k&#ySf51EML@]rlՔu NQ?GceS, ,Q {&nxkE/dj3fs( zO븃gkp[O84  OsHd+\?eN3&S|u+F<=hcx[_Sg;ȫ@SBYgiљc3 bm} ="X +EERT:o=Q5l ?vp bg6/ð~񑔷_]vPDDb]oLm9X.0-x$n+{NCEie`j%OS+X;OpJ5>GLxjZ_$c_؏'ѽbp +c|!Fh!~u׸rvkG97wJkٱNvk(cW-'#Y2yE`\3^b{8>bs#c!Mٿ"FVa5 S(գonB{i1?*zRl_olf'YeE~[1\=2;tFzPVIǃTN7B2XR3vS촠H?,DW+ץ GuG; `ySQ{b-%2C*z, k~jՅƝ`FY`gYs9S9Vqu lwb8_) JZV_=e̗)fڇl:DtNO,r+Up//QÇhu;pbϚʏOU`Um^(9]2Bb6q%'Yf:W6@zlTsזeESQ"7kE)"o_O~GK?| L +t3J/sg}G'͒'|FoVtn.W[4GmceΚJ h#R!Jvj s]+kYXu2jx[ sϖ<]G%[tteM+ =y7I6݄`-v1o k=chb`2.E77ȹK/$CÚ^ϙBT\:ڑ?w8ĬOlu ?7[}OPj{*Bx w0uK> *g={Qm6)\Gw>]G,n4Mvq~) ls Eݝ|CeĽSR~.ܪZn֩)::d׺|׺[UV/^X9QAӓXJU*^:ZEz"h%cس"~g&H>|jDHcO֝WX]sNA%Vz6z2im]7@o|}+e =U]w+7,;Ӿy=%Kt+WJU=,Ԝ2",sTf8ɑDF bGwt,DJ\%FE@Y_b%l֫9"\h7lO?XQ)}.FOFF|3ȽBXR6Xi 5;U5OylZKMXŠ.ڨw:w8zr];Cl:;K<f-uڍ\c9Vtj({w@S@iO^ԶjϊkNZYzT. glދt-ouH * Բ1oY[aA|\I%<ǍUԞphFA$_aڝM^ W w7P/$Ob&iX{&lޮ프w(2G]jbT<w?2r(FE7 *+zF[Ζ&L4EXѳ %ҕ*NL2v{3K㮺rTgW*8b'#9B~H>|_xCF .NBNDN`+o:#s**)::kĸhwW qݭMs^k7=[9M\p O@_kR}'Ƣ5{/V/rr1ve\*mڊ_5qDjo%!W GﲢP:9Fϣ~ YNIIZ FT)V_%&;7_flnb|P`W,N9 +X~;9%ƹ:UK'x}sA̔cV)&ؤY6'jZHqY -֧*Y2Od0MhH5ʼ7FEZFcI\M}SBTlI`^^^-xYjxa\{{] .RR>DM3+]i*w)=.‹Re FVRC4Mo:W$~DpmPj/yѴIɏ2xӅFyAKeJ?cYWX!; z9_Mb*?l$y lzy$=-2*.WkA[gd`z1DRǪ@6CQ7u{ h]=]VLއ'ܷKr0b^z/*ez>[1%QoO\*U#&nuep棢"|دuV#gZ p_/ V1cbR"3*#5}rCJVg)8٠)'U2&LSkANi]B}T3xM9.8>d2m]\}̚8Ga]쒰}SMjnx7AKx>kkx|WB!#^7aߞgeJPՆ&+,\ rT ϴ}7Bwd{BΞsgՊbI\{_k`UDSF-gK|B1ޭu2~$Ŀ]V>e;~.iDsg.ڹQ E;j{64Pnհ`UٸW텞'OvtE{9%s}sU7Gݵ$I,*;uNc}W#=e]i;)Y(3pؼ+4` rX\a.ejdUR1ֈ|h]GQUսr@^R+Pݙ=5 a*:io45`ӠbP(f=uALrs9è9d>Jg^UW9Q.1ڍP(T'PCp8_V,TEs)6ZGY+݃u=x>c;Șo=B`3o`[?2GdڇUzoڷ>8 OX̵`ܹ˕\a͘hE(Ѩ'k%6WӗYqT 4%51~c 8I#e׉Sn~WUeֆ_o+E_'gԅ&' Uҵ?d><1QNÇ6U=0;"r60٤X'];̧~X3yjAOimv@LnyXr?^ZgYWz{Bڵ5Y>='6 JNJ?]A6WD<^Y7FU Og_qkĞI.uŧS}yp6Ԯfqlj[ۏn3|{-ksxIw쮥l=2pPeҰ94ᎨQc")ĺ[EMV}ʨ=> mڂ+-)zYX9![ TMQnZȷ}KE;Jzi%Twt8Wy&8ϬG$qChQO@y)>ٞkPTM?Z~wn$⿀iG^^rxq:Yf ΍%:QLXkE^'+P#]΃a^*k깻1qnGbZkՃϚeXɔvs9[H-x[yǹ< !V +Xh $z}2sXw^[A1*7/[qޗ l/)JWNL]5EdY蝺TϴO6~ZONe2ȭm7y ?|cԠ&^.s<g)o{omoZnn5t]XA!~Ժ!nyVO]{:xEZ[d9gj<6zg (TmyqDȊ`zVxɷ}V3+E9eKaFhKAVd1陳Q'̈{Pe[|MV9w>2C^N;݌m?(*x{wm+NVQqaE7>L^E Y\]Ȼ6E 6vJvUsx3YXԀh|~Q,Bۿ,dVbwESS[yRGX%51#Ρ vܚ*lD#8;ԕ:r,cٽj挤RޫEuj psa/8qqFsOP!;,ͰΩg@j=^k䱦F^DD)mdV s>}368簢\L詠u8M)Bg~Tv~U3G}g _eRwO#3|_5@F?XQ̍v+v֔O#9sd>/¼̽^ cE5a#!uM?#D1j]ZѪ[BLY-c2]+k)]n =ՠeї,`Gcc٦r~MtU: +r!ɩfj'P;Ο CCUbN21y;ԧֲS ~w' Nk:MI<c]l)Py=gؘDS;g>GDQo-X1?T(zjDx)y[T*|l[`er}#~uWrU.Գ9O8e!jfx/kH_ N:c ֳ("Bl9NX| LDy;9۔]Q>7:?XFSUb3-Y̚^Bp>4R\*gd&AtKO3O ]+ğ[.V}$_u6 5nH9k-KɉYTtO˸UVPw;ߏZ;HaR˂sH_@}sl3JMOV:]d=v NC$ jQS:YX e*;|#SK+T`*,;hDcowHr\D,Z+e\eąi𴊑":+KyʬcKX1\TKA2xV&Փt 18!8c\ԴY$c!CS]!̙2"Vp·QםIT<Ȣ9uBK _FXa_QjFdFaL(.m\q):*inu> xHD>!^M=swO*y5a dflUƩ%+&ID®2rEYcc#XsAΡg^:_5No` KM\HK{xFDiMdM2z.Nx{ 0UPKsXìUћg>Co/66η3JfW91bMB_fk߭MM36Q5pyr=cGQS͘-+bF2Z)oDFܹhq OIUgN.gY5{%& QV^$g̷#JcRV1#Hjup_mS[[AmrFNMdi3j5v:],p 3Jd[\?c8H uq92WM“-gIC3};]X{WbYTD{+}gߘ+z >CUk^#xO Pw<Ĵ9Yoq%%RgX湓 2úcyB?&Dk0'kWŜ+NJb Z@ 3Sҷ9s) pKEi^5a :CtZOa\\Iծށ3LJȒor +*ԔtߍgV)yuਠU <^ 3OQ#/%DY=""6Gs Tŝw|^g;mIz(H뚱*vcoPiu t |UA /zO*Us_6-x+ w;hܑ v$6ZW UUN%g%њ8{;tYaٟnW ՟ⷔ\UefhzNL1ٮg]zh% y%&TO}xek)gef_:R ۺG-'\wr:;OͳЉGrϧge g4v\dw'~՗sƎe]١jz7,+ 5vgN OR%SvrRatհ& yg;X,NG̼YfطyVJGvmDo+/tO9;G 쾱c Pqxb 8h``A"<;XL[_flGuʊҕA*;TX,0jk-8NܻqLp$ߌ6TMKarIUA{> k~ΎO&w dWܬ@B;ĕG 9EPS4< sz5#n}곂2f؛MPuq2]AMZ!ДzŌgSc aGaBF9$G|_y/2g[AkxJxvTE%W窣pэJE.])ftěl53T[!9}e7Qϴ˘9= yg#ٳ$=wv\KQ0SBՒqq ~6){5P6a:6oPVWBR{F@G?H_<)&4ow={_/O3VLgg{`1"jZ'|yU5zƾXӲxoUѼNdą.*()zoQ]hllBq :o Q<<ϑ5y(!ZEE̠LH.bZTQF ?c3N5?ʨ,!/.U+2tR~ ŢfXcΠ&SϸOO9QzpB9+ yMϕ,zWϓ%X"^OhtW2RX >.vScI5{-<gݒaVw(uT?O?+דYI 姝sբhja6pS;NDY5oNO* L/ ig]a6v8OouQfrSEVy0#b4U d:Ja"ʘY߉{o,y?q}[UG-ØJVp^k_RjOM U wpQKUC(G3?axǜũyTC>71O$>Q⑄ (#1cܔ =I_̴B'2Rͥj3"8pZ t{%xF"})Vֽ]U+ɃOoy oo[1?V.~n[xV0VTب^w)g'ɡkoU0Km5j9VPZ`Swdsz;EQZli+7n - 5,™K`tGpSS6XkdLl!zy r WxU؊*嫰pЅ4ɟH)!_>}~aUXxk˥Ѓ^Kjnhãg稰d-rK=l̟QX.ȗ0^kpQݓʒg_Lo܍9WEV̈9{Wg,Y_R@qS$[ó>"˪"iks""bRG+-u,W&B̺Ȏ8l->8X;0mk[ȿ#@jlxjk}LIo8{&9}™p1 \-zv+ yoғњăf{+v ڮgdzK Je\Q5zpk53zXms, ]7Ӡϔ)6'%HlFvEܥ U.S4G mL#a]y(-*<ڜ%O{w|N6V t>yY V$^t*SU;.EzRn+XgԊ K&pkğ/lPiϐ1PlNdѼSh/ܻ7+\vzϬ pF}%7Eܝ=3*"F֚_Y(O[aKXpQM9ֻ)T2C,^OI $'i+|ֱa] m)UiVv7Ȣ1 y'gQlObu5X+r F^E!@ Wyp?{ߣg='Yo#9ᙷ3R)>pgBJ)䟧!`|5Y vjR͘'6^B|U92VӦn&ڪ8st ~¬'Dי~dVU32B *pwi">_yoȂ>@K rOLLb&p"Mꑷc23eqR-:.A\>FYM;iDzlR̓ժvR86F19_\ &oン|@UV& #OrZ[wmj2?3' :.'ރ;;<5v;ug]٠)T B/y,0= x]7γ#8xrEض"IXyavj'tXj+Σ{Mašʍ7B#[1<{o ީ`;]UQΎ(\Haĺ9B;q쭞D^k߱j3شoԿsLTP1bg^guBןdznjvOqh+3% y߲E~Xa*"_[p OCDr\="6R}Ym gAD 8?{[{{ K-x؀st'}309fG5%Ao-M+I˪@OagzU꟧W+voM2v#UV򓜚~*JGmm-Y0ۺE'kq;8ӯİbx}E# <&.TOwY=!wibnxy,b%\O=c3vj@ERh xb\im)6yT@"[x]koY3dɾfۥ+&h{ϭ"hyU~Re>Gw'ЬQ'7R#%~?Y?~"N~ꊓM> >>q? eD֕4kaAXuI,=!N?Λ"l"p>a.[o ,Tt,EhadTIW\h/Ҭ1 gY`PIbַ&UCi\zT-qIWN c}Ro6DG׷>|>fzQ^>=mm67QejF7%)M _ewSuG52ܔJcշREc8b$ EDKw'Rm:1({B eue3NF=^,5:x 1?gudLa-TA:9?=aЇ!X,]x85ɶXaWs ;Y'toTmŽ^y_'ZWvXyYp[}/Q5U%<ma-"KSŮ-27FYQ)  fCERL+<_I]p߶]w,8FL*V>{|Z[d{DKwe.ߚyr6|ElT+b&<ņ8Z}kU+t\jݗg]+Wkgu`ZE|#0zDkf߫cq/5im>[Y9`)6A. vMQO-c˙KTn½݊Yֲ qgbI幝MT oq'7>e-A0j-4UCFxdR%U@uRϿ)fNwBEd[Ufu 37^[JfRї jffb[9:_80$2ʪ65 uT2Z24 2S@} W ދcjߓjR4 zX3=G]eOE9(ՒPKx'`|>w;])ȖjO Eo0Hbg%>6C~f EWBJBa]8cVoTQ- &{+;ι[IQz+܇ą~Gt Ud#lٟbV&xVʳ nSF7q{'jVn"&/IXOqYվK];~x1=u?g{J|X*s UU'`##*WadR-x>uޣr:׬^/5fNln#!uzLS[R;*N0"H?PzuZB:¬3Pk& ^ >; VV;ҷ -^x5?iɐTt>Mxݵ7*ر5>?;%[2_1m ̛ :~qZY|OvvV1g98e] guZv쏵'U͉PUm68 |t+(W˦,~z_!E{zNK%4}eH(kdm=1RvAG}޹$?z!;%l=ч]Y w1 Hʑzm Kv Yh3*Ա9bnNBꬔJQ+s}3{ o "[=/9exF@B݄ܳ\kkee1j­0s=#>Nr~4WÊ0ox%r?RJ ϣ_3z#,WR'AMVN˨|m'koSdx  \tͶ[<*RtYHw`"2}$gqo\i-KTT"aաǒ*@*JttawZm5FD)֥g૿g=g:1;j>E_Uw9cĞxiu/15 L8S[M}翞Q^ Rcg'Nm"| _2bӐB{:nTE 'l(ME9)S!v ^׭’ꮜ~IR *biVwBY-T.gvu > "ǣ:U=6$$rjꕷAeWNvBUr<YB}@U1y%c Śb OE#筿; ` "&"tTKw0>(7dd*~kಟyN}~1O%'mX8}}^Pw\{',C+c:=eP Ϯ`~zt3WԿ j rֽt{w yΙ{<ܝԂ/4jXo%xִȦ*n\ jQu&6FUBCp.DG-pk1gl30>Ÿ]Zbuޟkj_f`51KUdFd/_j-1 %PJOb+l :KX7mtSEO mO.'XŽ^nLmqLXcy#|h n+ffg3٫{ s6V 69 0׿/9Kg@֭˲vyDI\L(#"pw%T,p1LvFkšoV?27Β{SC^ e J 4fa"j,'EC>y>dL2F:YgrZq{TՋA,ܛH5vUJ|wxcx~B|:!D9mG'nX-Y#6ZaΑ ˡv"{9+&\&v}y8o vkzafyojF|vP drSo&e8Lk;ԃi5;o&(5"O`R\'*^&sgv,6N VsӃ"EK^WOE'/Et=5K1ìE"5&ZE?^budPuZ_L2d5:pR[Dni)z ]CSG: G8Na,&Ks=p-1Ї ' T0c3k;%[[1֓(߭Xybf S%0٧7RY'ߒ32amQP! 'UeȖZ2_S{'m`:FVf-5p[z\iڰu^KxJMpVx3,a}ɬɤH6'Q(,Љp4 sޯe8V e1qYU!a_\4w>'7kXlNqGZ*{e*S ds=K+-t.4zo]o(;{kS5^^բ2N*F T<Ҥ_h+TNޅNs/:N2fXȺWlW+U蛎bV0"G*Ҕ;)ipZu-:@ȘFJVLFE&h> g_c}5+٪)zPuX{ȑU?a'ŚtUZͮf'x pF|+4-s`M˴_^+^ՠ*Em;ŭMxJ;̍蝋o0X=#{Fzh~ӕAM\K{aEwWlXuws̾u#) *TeS8kTH@}~R]0<5uƥ~_kZ2 !X\w gMHWϭ4~IWg}F&1>{:9ka+$x% YIQJΊP9\p+BΗX5%~UL*è۪`S48^s$P$+d*TGjhF a. 8ò/-:gY0,c>W/>֨4:Ϩ_r-~3!SDU ";dLKU[X WA1~gYΒ9j Jvvsx|7?k1KkfVy+,Ō6D=G5SSTJN26ʘM)׀:ѬP7s9A_t0Re|ؽVO {z깴= Oye(ߜm/[՞G_{>F?Tq;Exsgpꓐ-"X?z KUv<9eϜV R;> wb(x7_[(WBM[;X @S|+N\kSczP ]WBI=[}Ti( xCݞeZ%U4yߔ'Tp-ݫV>N:2|s^1Ud90ˤBö,&SV|Dwb=Nf9}r>;9ƊJَ7OJ({p|[ZN2NZ!㧏͹@vк㏺ִOh%g jcljϭ IFVR0nAaK=#н^g9 c##V2Z5'z5Ӥ=[3ݬ7x')Rv<{vf:z]'x&PyYϸOPSew=g1Csq'Zgn`jvOOʚި6ZaV< t)3h+XA*֬,ON`?}im`1 xjS<(NO+)TiK6`zs:N<JSjw#m,H0/y'Ї%$@]*!Z`geU{x ^GyFQ|x5^30$*g+u;_9Y0+5+ϳv OX{OKMT`m•m&gߴ{͊J5~,jLL C!֎YDIcݵ. g<}b@?]' &Z-ߙYQkM\.r]fnv)q͇Vv ԕL8Ԭk^23ySpmw!XҺFdqKJMyhmXݰbYumU"*v մU6zy;:سуmNxΓ|EzxϕpjGdESWz{l\$Y'eg/ݤs:$sN?|sL:C$tL}f@XSaОv^G=O1-Pu|6* 2jd6YuyUQk3jB89]a$m޽:k4`𺛠Z;U+V“i{&jqlb"OH_j\+y'JwxW>cU s4`w/1'`Lɦz^'*<==Y+,cZ[~稪ƐvUF 8T4N-r*Z2 zS؅ j9|WdwMٴc!V2'zg&1^15i[z՟3r;5zxnM LJH,Gݶ2Uܕ> x\Umyfsp-5.Q\baͶZ/nJXjUhԍ҅TS^,i;nSxr*MS_ [y&mtS$qb܃YgNL1LUKa/kNȾޭ%Lo*_ HR}N"ӑ|KygTg~S#v Շ>jTXi><>^YP+ܥTBjO9MP'PT}JHƚ#/xޮ[!U/܈AjZ/XS?6둌D`-R-2GX=>óO>OkHP S\yz}"s~N~iϲflMQT~.>EX׏Z=e)}=?cjT全JV.}0['KiZBzԀ7r7j6O4J]9*N(z&I"Hʯ~BDQu ?5dBW=#bE>즛{v/{iD&n/L^9鎕Yi9 Dc* 1?3L|"UZb\ٍA&{A8a-$Ŋ]aC|C{PC#ݨZAze ;W1@ZχujFw/=')/f3ȊPzjP 0;yE>ģ0BVK<X)o".M3]?=RلWb^TN _SyQ{8Ǩ*R-2v9)WP9&*m#مǮqUjܷ XI6‚r*Q%۴QBIu!Yiڜzl;2; [-smi$^2?^gp^ͪ4[g b)r2v5c?f6zsU-rI+ 4upFٽQZdX#S'EZ[wF]d-s=T-:6D}Y쓳@hiYUpN "lfp( +V\R<̲j5WA2BnN gL]Ndʞ|vS$Jnm^i5eSzT|34f~ }|αKuoK~[T]ě_`8?Y;^k?!R!n+letx'^v^&l`3zҟ +A1kI ofQM,SZK{V.*k]9;+Ts`c_H%^ F2V*.ý}WGI`z8DyJc8+f3LJˌW-%2YƲ%+Z)Y MwúΗmk+Б]+wQ1l-}%3'yՓށgi_:mN웟01n=&dqN*r Oz6S'O#V.3BeTɚ}@.>gV6Ąp'ȜjPעk/TzH2`v\3B5jS-;oN?wsɻJ:K.c^Fng.=y2I@o ΈoFx\ Ul^8BZh;|PeQ1S;GdWL}َ|;#_\-OWLP7jʙa}/OQe.LRW1K~FߣtsgZD`SG}"zPk|lqxZ]s:k5}rw9"چ;7a fpZ6}ҴfY3ȡ08z;QFr+l_~naXqd$LJr1ΥSh-!)\o_)ƲEUQ)ٸ^Г?*gX׈M"/arcʹ>rb.F Ϩ]P( 286}hJ{[*fW%ؗ5]P3ǙsFFqѮjE񜘦Onu?һ##>գґrXZGx U&ŜiA-a-%ρv}s{FZHv<ɛ(ބ`KYV &1kjȵ* )t$c(F!cdR<_k=QGgJ+3fa|T/Fnwz҅RcZ[}!X5i9J3׊.72Pfee̔qGM.28Te?#U8s|"Ou~jaΡ,)b_)NTT>\WMq\nʼnl'xOhBeYsTo }n*‚pS^"v?E+}zOW$^~T~Q n VNV̈WP+N ^Sꠑ!F..W\՟UJx>F1[+w\hܬg#Ab'35d#Ի>r]YO\nڳntrsFxax"V/3̦X㜁Q;S,!\/gqFkp\-z]bPSHыXR}VVX"H({X<接xO*10KZa4(I62+s] ,q2Y`<KXr TW'x:ؙVŝX'X־]jR7!_oi*Y0/*g`Ey k7@MdwV/4+;)" V9PyUS^>s_Q)ʨT̑Y<b};Q xA'?Wl C}/^@IWB\_JF4rF>yBܣB=6w ^Qǃ<z:Vv_>ښWVHZȄdů; ~qB swa;9._ªu#ğ35ZX)#q;^gUgL~ÅPd;V۠A",#cCO'Oy#ywa^P,zȨh IXǎYmz=OQWaWL4$CQCS5jiU/Q^4r#e+=s읁0!8ȓ0ܼbV1FaJj$KYUPbmqk3qZCL{d`Z?}߁oG5H, 7e.\Ky2aUVT]8^1Xq['܊|זn]l!bWSI+}V=(K{ 1lUQLM!*A+vfAXmqlnܯWEp//9 %e uE[`eLhFݻ0c9ɲ?3. xҚ|Pl kS}ͼʡ`_tB2k~NNMN%*u<+\Ca]On ji ƏY>gt(M.<M:"tJ/ӫY{e_MIQ5CGγ&ZTyX㗱{gab]ZxOZ jvj+z/V"ar*vayZBye]N$+#M];W HAYQ+ĘsD^ĴQ܆~@VzրiY 0P_y:PHUc9,v$QýVW XgO&\mgxUiu1눩{΍7>=8͵U5]zG'`/5a "ގiPHbܴ뮀EV N Hl58A(acň1\{PֆAޥ~䕺ƪSm6#yߩ|!Ȗ Su$Z:e7 w`9Ҋ(5wq@>lwk1NY5?Kax_+8;T=nU] Dy+R^RW`#&4Y+sw:=aSUf{LjBZGE%yp}<41[/h Z r̵ ρ{4Y'+(/l:aD9]#/:$/ĿǛOzrڋQ>(~"e}uֈ>k 0wPs)"{)8Y\k@+a;7xsqj,̞ \D~RZǯ5ac&ʺT]iQ(;^ܫ:b՝:PE}Y]j~+@r|V3W\@W/ADl4"*3U_98$'yy ;(%8F[t]D]sX Ռ{3^)g΁x.35I9-v_YDJ2^;Ɗ`n\ƞȪCV#L)".Nn*ӛ*s#NҒ5GJ?27m̓|By<jER} KJVdZ[):FÙe1112K`Cg`q/cI.SI8EO[1 ՇTx%>N^{9gDJe?A]yc ~ O|'݁^x"'z>cXx=5EVq[Q,gդryy̥SX'[!4,b)mg-3NN}<%6ԯ_qw>kDMϪ'63`s xsavˉt va{D>t}!=w;u<.uP ʗ 3? fvC=Wtxbi0G 67_TugF#з P(f!^sRl8Sv0j*yzwZ= #\_-mIqmFL"CCu,y=1`m60j;J8 OA$a*1w}1JញUPk&6 \}#"zġ,~UeNONGA#DC7^]XjzʭeVP.#N*+y~u+I[;>J}/y/z)B<&[|oǰ >A+=0;wMF8ۊ/oxgY_d̠ 'Eimc`S^'K~5FmV}ϺxG<8BݡnEL&׾]C2lԩwwɴ|?+3.s@H@YkD3Y2bSA93A$DGzn?hA~?C_|T˅f~_dOWx?DsV/>nz])v 1ufyRb' Lg8y!D BHfQk>PIO, ](,}Фws+ =YKKQrg'`{dbTŠ!L2aY):}qj+b#R]MꪠcPEb]=ws=ΚhE'#-F;߅*-U;(+f1#|g.{|AmufCyٛ]=h{ivjz'?ȇ $Ƙ_ j70ZoQ-KR_Lcjg|P9"Aj݌5i&k0sp`İklZgXM%~/ֳ+leޫ7Y8y-an,4ך+X}pT%M_r|.xme|g ;Y ՒwUAC!b4c _ow3GG-"gI\]y.)8+p~3 [E TZKOmfԅ>\KAͯlk"➔ 9gM_93YJ'7C=$zx٫F 6=ZRJe*.SZ8"N ;4;#cx)pu]NL8.Pt\g)#sZsD|symTȟ3VFQ&,9dq=GWTڞ3q{p}q-q&uHnrBuW9|ϰ9.8 nv)8G̾> 9vu/5{ܻH[Llq7x~pi CJk,Cҋ 5䭜Q z»T!j']pkaԄW+!FZz:UQI;uh渎{ 'XuiQ\Ѵ@ęc)Dvs%֥xmvēf?k!l~C|x2OG"~б{؄'b<plXi\g[7䦲gzITMJXu[yyXmP\# p Rg"_z'sS^ XڂHKyܞ7tQnOS/;@rd=ۙq ޝ n7a{iی\4fG%<~Ԉdb rAMeX&Z +G&'=l1~m6Q# O ،ҧOm0+V7^ 15^@,/_)Zkj<2suR{ˑ8BɫavZڤŭNq2fXc*3@犜ْj$Zk={>J_Q)@rNʻY[:g|qđ_s[ܩ2Sx^U( k+lO=oy-WDȕUS:X1՞v4P?[YouWLܧԔm9=uzjFsO=c*Dy>8Z\Hfq%#d95 {1Vz)ĽcuRگ;_Pbs^n>Uɘc= IF%8אaݠbBSIMOb1#f$ 8/X_g1=qtح|D?c.Sh{:R~< jy2=Sȅ؉JMF=0ni/MЯms&hƺM!OjFgf #1w|2VL[+l EoәSllF[/f"b Tl3୾Pj㔖{0+zzX<+[G^[ L/c$)]5j$Ք{.'Q:^^:Vx*:}b.b2Me35ϿBuoVȥR/c mdUYsNJ|YG>zB(|GTwm=Bc)S MX*E';OasUIJk2 q.Z5H0t?~ܢ^HET1{$e?g}Һ"ߘΰzTSKUR:%u $_4DNqcsn$z}OxM.Un\ڪ^u7a9`@TAMsmp*oNTs#*irr2H]cuQ {?q :\?xc]SEK1r\uDc5<ัSWJ=64}T6z6eRq?*8[l!6:shsȦd+=dTqfPLMUDOϜ;D& đ*NW j^P)qW7żMG<Dƫ5=W³9%楻 4 5OMٶcPǓ^HZRnI{݅k,/J;Pj͞]E!Ws`׬N)" !CZQ=l(&ͩF33 B |GJ̷[˜=oڊ%EWbU uAMȱo/ts?žSy:ceL$OO8K Ci=[!O4 Hi[wOn"cǤYWR+g_I%\[ᮭ;A4 bE_77kaMoK.6v<Ўt:,8ZiK<=*HT=w=UJQd:vEK4wކg6;fGW=ޞ1zB8=֭>}.ޭlUhhsEk–ݣOY ,~E"Jd[Bg;xN& -PwoBkk^7;ͮO!rSۨRSڱD MlS9L*rnTdjFc\MBو !(Pob썪Þ=̈jdΓg:ֲ2A2{A"xVPt| Bz=iB^G_4#n r}>u>ќlrRzb 6"g̜Cj3qPMsJs Wh:7hs>"C a)FlJǾ;́HtңX۩#':c?:G>vuG7ms3~bzqwR$G$A>œsW]^'/F#')d"f5%F)sRYlY>bɆg98%Dc30>)kδvAmWϊsB/P\""c0v9aqVhe CRp4_tWDYTӴ]oX\-M t1 BɊg<.*& PYpL?F45CR9NJ @UݯU+Q鯨 q1XLQ[Owwa>mKHL3MXhNx>hs<Æ=M{h!!q?ß1ߠWk#>/n=WbXe1$s!6ƎF1ݜ쫊soȝ uΤ f*4o:2$gA;0GȖs.TxwgAGq28h._p/>_~  mv0-˗|maf|;OWC>'>7@?9çOȫ~'! ccj{K8OyQ<qr5kRvv{MzagI ^ =Z3_賳 e˪jS{ s"VD)(د{kaM̪B= S` <.B50zיpTS,h]=۷sN)kdԩ/8#.RM+Ynp.0K$X}^!;ņy5 I\ Z8|eb^+ /&Лͅrq.%x-vꞟJ+djLsգJ@1Cqؚ­𼓊MfvU'wkEM4pC$U^Sx;֪݊7$NKxJnҘsQេ'X'DD_|+xWd(4a-ĂX|`B9dO;x_̽l҂=!tT *S4~/!&eC[zKaOBNvQQB1稫 \%WGw⍳OLac9meQ'=rJx#>D橽Ǒ,uP{*EPlK47; Ole݋ՏeFǘXI6?y-vGT Zx-'Fx6imm{vYK1fc=mչO)$n7QBتM=VrjqipW#MU=k*#3#[A>La~8q*Hx@o+ k>˿Q-~ZL4{uzӾJ2@ -V&@?8݃dW١4}M QsV(wUqLw[|").H.+S Ot.*@nQʣj!?Tu&!IVr)KBoiԵYe䝨Xk"d&<1Zy̵kX<*6-bf7󅬒;< ul}V-qVSuo7*'?VF0Yϳx7[|פ:>wCz/QMŵ$~[=p=W1Q|ȴ8{~fx"RK5d&v{l];@]iq_cbVBzzdB舵ȥrBŻ0{+2 Iy/pKι  DݸW\U*/b$>և( M/?I_~o>K^ٍ5a-.~ޖg 4:BEX zc қ1Uyf%U5޶l}.f'x/bs>Ȫ}Q婃sS(7sn O .r|}mI3xSh&J-d+Y=ew2fDBV6zcq=šR~+5M*o|yl[` 0hR3Vz"'R%&$ Lq>zX-+UU[+xHˣ*z}>1<_3B('=ǞkVKuɥGSpziR~?Aw] CyUϕf)T!!S~ĩ,)[t9]qL^}̀ ^#3@5p~AooB?gdgԢKO]_BX.83}V3R^:yG3+"/5_pk'*GGTe'񷨎xsKY1L=3GžkuDW,j+)CpWt M(tXw3{=ń\PP,^+F5G覧EVQyzǨ8uʦٲ䭧~q/;nFabZ䄷:Ud$)嘤 ZV~:w(OY+x!euPĕNZ} X?*I7ONk2g{:3e2go ccfu3wTuyWheN_#[\U\ϠK,-]j_]}(љƝF$ٓetK\)rʊUWK(B?* =-v<.ó q> Ĥi&Żsp^])!6ڜvgܳ'=Cz>#;Λ\Ogb/$m_>bmv}\moxesUE~!jDZَezș5D" wȜ?ֽguXĎϙ\J߫kPEx.{$p lwlZw9|Pp/ 'e #0H8韗#/`]C(GKZ>N2V rI?cIƃ.C{9INs~:2BFBC͝RtgEa:G'S*g(fXzH|v%Z7(/DS tNեǕ%zU] Iof]iP#U:}ŚB>ae%|gqT<頦q_qu2v:)R@#*NjÚQQL:oQ;џRc`_E>ߟpyQ}RnZt փ3b>O뀓QLžd1GsG ։s8ō7ϸ *:g[PTL;,nblX(W餣ܯd~,m<_sL9 Gk.hYxƓE~ k/|.kT}2gk㯿#,nE]"߳M?z3w1wkԽf˾;(em#b-(nȋ/R =C?$U߰~wiNs8#M[(<^d$ P&9_\^SP(:̓p?E=Y۷6I~_QܖDMBf4) EJb۳6~{<߾̬s!8fnJ:UYY ˴y+эgTbm@zAMdKщo6 kl)jny^ZX"J UuiGJN#\,uBPRe#l -LуRp\Сٱ쇰WpNb2[ovU +@PgD!BuUJXd a~Ր'~z |+shE#^n]w#([dsgȮ Z(֑`EV]0,Iث\gEPbG<|ܞ:getN P[Tv!9ueeCDvxA 6#ԒGEa4P'ppߣ9FWLέWbW8킣9yk薸ܳ:Ҟnڭ*vo}>Vx&إ0#YuҤ焩x )evb9kwģx4*6tVۇò9eNS')&/R{HWbr?tBz{_.I> caxFC 3jhpq1tc>`ijGN:"$vOZ :\37T+8;hN*Ghf8婽Qօ:I텲9zW&Xh\&sk}^|&B ;sP gLblYaw"QG?ɼf0q6N ,ys W#MjtӝD@(,q>Y58E; bW>潑 ~Z97%tʽN?Z.3Oz1<UȬ_$ツJ 4uZF{d-!9 "kKY j?1;6ʞB-RHX"^8I20"1`&O+mQؾJhف=qc-鳱k*yJ}c8CoYr!ՓZ%!67v8uH{SzUyS^o*NgV;5<@Y Nf*+Ƽ>@e쟆)sRjF28H̃pF=W}]Яrz߳SMC/^ܳ#qi(dꖘM R.sZn\_ykdGSmrnw}=8O㽛Fޡm80"i~1G1d7-UT 9ֺQsП+|47DgZu#O >\ eb5PݭC@O*:BjC4p \ZJW$۲`uz[F?/t9q=o78aI֣cu^3Yɕβ) 8)"P%Ti~nIi18wCUx- Px:Ⱦn:R~mI, [XHHЊX63DP~|M)u0alx.ޱ~ᚹzl.8zՍ0cD/;r }-χX9Ty+Yԅ!>b__< g)'jK#"zk}NPDBcNmݨ}؏TjmcE3UeBAoih]u볶~t%e6y7jό*cͽp@Ji*lS!S|O^> &37s>cᆁ&9ת$nc}pS4k+q0`7Ta]`Cѣ=řV%r'bQL>ET!.OٿbV=n1i.qS1<\ԙ?bZNSSÄM0OW??߱-e]+%!#a}w荳S"3ּ`V;7P 'I/+űttȻA OK86P5,|_Ӝ=(oBYF' 3;rYDl Yga[)[鞔:iPAtLA[=I@g4[2݂?=ę",i,#x&0XAww@4WCn S8y.S" ڢ<?Uga'bD3e՜kVY<5t`j ɚtT4p 2zөvLTk5˴>gI>ig5Ũ E5jx 40Nwpl. -fiF}ي G8})mύJI6"pVT4a*egY٨seR ދ>̾zم)8.)FGsKāscN-6fXଛG Oπw>΄^! Gv 8]OFup+rP?cmq }8O 7:‰,S|Gdo9R6 3n3ErР r9(k -+zV Csa+d}lFj[fv(uxN~hq^=_5GuJ XT wųZe AL;;˝ M=EX>gsuEL10s܅s7@VQ&ӚcO9L.pש3R7R~9OĂ!b#,Pyf}(gAiX}7Թ6v hҸ|S(igXxL,8؅jc ]Sk  \3XMhU owlT59m'8I 4L$nm0V[UI9*Yŗ۾vZI qzmUDPRCe_9I]~_[բ-!}"% l=/_i >ǹ?۟0W|0~I/8˞-1`W54OW|[79+}=2}W314+!v7dObSuGy#Mncs&M墑Em.x:-/A[#`q ڇs9] gld1NNOS] pt ) Fg&K~t́?˛^zاe֌e|e)>(Ȱ:[5/ ]ĹQj Zb8,,"ҩ"b"fTF2֞1yIVWV:LAQL@ΩQ#*c":H}[5݂:.Ll]fmnQъjtw荲G\~'j07WwqgAĬ5]UC$Igj9XTZ)u V.wd9¼=mt Wd,`"7d2_`e/#y<Ų; Ya+6J|΅CS3%X]*VO@qeA^C7=<"5Ļ 0;Y3u~Nh_B j3Ba:DBbP]^B:[x|nIhA&|ecU݁AȬ@g߉&4<\QB=9L<`],p 1V\w"TV{^(z˺?D>N1O gξTD@tngsp7*ulF Akt4O`} uTFIArb[ޖow8<!gh%TnДbow*& '#5!.2IΊP75z>$l*SAY<KA}/|XWKetR %jĂe2@8U?[[phk1O <iY(?kjm *:+r&2VϟWͬwc(SϤuEu2#NlkWcNQ4dwy (_ZU@61-srAjykueG?+Yd=uWU4Snft%bC'XX<njk8{Y{g ufZ= ]s 4Ω[IW)W7fl}e34-c?Gq)utT3sedS 8Sd  j_<\X1r{4θP2a:M?Ŏ(+Qg]| Ql)#ݫc`"8\=w5VvBєqЧf ;+(6u;UOk9[BB+ vE< XݕK(fNcGaR|Nz=&Z?{ZXsp5NtnNsD1/g-"AxFx ΂f{8:DmSﱞjm^ZґR]1uçlO}mugT #O62g/868[\ņ $+z,$W'`TQ By9E"º3h/31Ʒk~FTq UUYi*;C8;3jQQ ؃ud\C@ΝC/nXWX_ЦB6Ju81KV]}PEw9BH!VWķ3 :}(&3u9ßvfd^J{h@.SoIU uNh;#'9gҽ4e@G8ItHxnֻc[Ntĸ)rs@iC}; T5+jҜ)b15, [m fS1uG>Qvg>zx~g*kq &?[oqm 6::QF ԄGVLY Yf-S_WȄ?ڿ%;A lHvks{D\U\ٵ2ǖ=p|&BzF y!ίUY|Ѓ`w^EPg<`^[j"`_w2{T>k-@+ |&d£Wq×ГDnO_Me֗_oʾ4#tƙR 5 ?;8 墌M|lDS7+0ɋFﺍy!z,=~W!jϚ*]bs]+D[sx`ԁ#!yfԤG8f>G,n${Ҽ%rv< %m3u>bʘ3BxM n;p{M){"1rGLiG:ӗJn5<qNt-|`JqT7bƌjLQhnks媬#xܛe\BF2 =J݈q urbou77:㡙HF?@YMHFp8rw>ыXLDz GY(Sa Ż{\>R{^wv<"c3D9FY̲\k:U#G"[i /| Tak@f1ߟUtxz0n=p'l9s2DXάLgT%:%)oOIBzgzYQm/tzfJ;zU6FaD $Lf+:~W>c1GVے^AC%p72coP,fMbZ¹b,vzCtLʈWEu|ixdE􀚄:/`h"+ d hFgJFjܦfK=D-ZƑUp)>yra[EOp[蛄'M5bu SN[{#,ApQzm(~K4P* x`YU*E:3k+чe+bw̃"C4wk]RnLjZ].1{b}t{j܁4@,6Ed]$*8zO_ /eyzT+d;>fB\ΫB>MUtԙ8\'ope&W/ĕjs͔}V'T`S("+ 5<% *0%sˊ2lRL*ה`mL762Bj+̭\gUqMot+j9eTCmYqC(y~158"Ά+0E-F4r}d Bi`yY1UcN&| ;ft~N9[[[uҧ2y|f"stp&9I1:9"NviF23ҥjRgJȡW۫"\߷33o}џPX^_:υr2>k1ը|x 1)Y:MFPL#.5UU=S#':BE3ZN朗ZkmZ*Zh A:gG9=@Ƴɪ ?\6k J8b-+@i5*t .E!=WO2kt,(XLmg7_3*|";73f$?hJвr.G({ε;@Frթ"2OZ8_yS=fv(ÏYo3nhk]Ogj*/q6uPApL(e{}]_Sw&O6:HT!Ӊͧ.sr7y+buWn| ![[AwL'i2M3wWoVbxT-ܵC i[;auej!TO`AḶL u#2 2اֳTgߥqlcN=,f֧|F(zFuuS ʩLNemzkSs(֨D`_lqBH{\籾d^"f*ʷ:чP sO/Ś:~3me]Veԅ&pu}1sBYP;Wjx0-FF IJiE(Qqu k_k&NK87c9?.*'ݗVx;'>aer1?W}RPu8K|_iVQ-Y{N? U3~>nQ]kuS&x R _K쎏۬c7T&3 -Y }BلF ; :*j˪2^K* rrVMUK\\ݤ e1TWL`Wb-w()gBN>}6G3:3sͰ2sq g@oV^?A"ćNeܟpΑC8SmOm5kOCռ>s'/ȅ"F7 LnqY r_]SϻH-Dvfig׸- =*$=K#.Bxp \k4]]_UVggWȖYЎcG?@⏹W}ԽBդ. uv^gȦi"6amޝﮆ;~d;T`Jawb~5_j+I1yOe^dwj<ͩ^3%~/XO`x'9&穒Q +s& VFϦ] oPr`gmJ _XpG(8=%GboF&T90!*3IC]C+s:0mҕu1;yxf.x{2*q>!ŞOyF>_F8GFTEn{.)NFˆgō6ߛ#dt]b쯦e7ZG`aUYLO ޞ'u=-P+F:.߫1s{"_^c6Љ1conJRUqLcLRp$$#zP%2M0I3UBx]t91վglZ+wed|-A8j3#V3>윰Q"O1#{^`-L ⾤O(1l vL83}A,7cY>39 >K50'~Q{KGY(R(h ש+ӶLxwe^ST"wV>w3}Z`r,zt{Oxb-Q'OߖZpBVtgՈ_]bO0:DDlOg z[_ /N{Jۨ&@LO {Yڣ"ùNWтNbd)Uin?I'YL5t>1 /WzV>b{t'J͌JA)ZuRJ"^ dĩms?~^Zg_PQ5c32?U<_?\{'-9}ꮘ1++=ZxCؓ_u $֥.U$8O;̲9 s:[wu}5*<);&=M<,뱑[E?i- qjĒ9ay_+`yboGy9* sQ>sQ*kX{/iWIw^QӃ4[[tIxQ5ܶ@e! Nw~m2֍eȸrT8@pπBsr6sriȺ_wh-dcK`lۻ[4+ pUK>&Khۮ#2]+/NOo5L\" j?\ZJ4TS#]@x(̟v|Wq3-2xL _wX[EQNW(UƈdZv;s4n,E4@}ku'F$ Nœb>%࿱g5V+y[x,q8h9]\gΊtHɸoWwx}xqSKcoصP` ,{se|ʽ79=?>uC;nԌ/ <.z u ̗JqįCl0/첐OSTv!S#8̡Vs3~>]Xkf@[%~@?/u#cX\2AEO:uR ѯWG8F3vk<'L7(x-tV'BgLqwQxY>b/844'ڪg6;paT+ /s@'FRZ}Cƛ ":{bOA#m؉!;^!^BRn&6Qi6 %jjfxcR9եdG_(c/Ub_~zw'dupv,+8FmjGpdW~\[hsb 6CD"V]1t̀Z'ܢz,6g&FLިS,,O!|ۜ^݁G~C&^EH6j"Y0z'Uo9HQ/l#5<Q`VMTlNJ}^{rN7R@nhF_STt Y8MWq7Y0{lCFl!xTR"S=b^\y} +f1 kH{3?]ՠgW>" %2"kgƑ&Ύ-O6ӵa7G(pmQy LeKF8ܨSO4u#gq5W=oRj潐yB 3;п"ꨃFԦ$W.ϓ0=~%v bF=nDO:Q5u.mS4cv*%aDcUG]zNe(`ĹP}VUL| _c78T-?^Qa3qUk%t=|'5OO~Fr£|8KD1'KELPQ6L ғ[N0[0XZ3?Uʾ` w 7|}ŜW(1^8:PFE=b+89sJuӦ@ :Р;%5iNCV=1ˁv`h ݎuՓm1ZKA!Mc>_QeQ= pԛE9U]d һ Ko/#e f]C5pR{䱣ĄJUd{|4f?ʈN^ES1 *bB\J<-wVh#"A:.Wc*@ _Zz\t~{|=+PݸFY  z/:1lټidg 6<>Hו,ۡNdgd"cU|Qx}dwL/|rDgT-wx[$|8JXMM@.@9!b -=_;ZӪQSw ,cfr¿c4ET"S eyFȗl'sgē!L5Usu\"|/$>{-_W%alĉb{WjQORg Sʀy`чjYD p'j >'gtySԢ)+*Qd P3z,#:B) DTdmx mw"zkj.@9dsExcu^ ]FJ@0"/9r;c % 8X5S?z@,80X0][Mbv +`L.qW+|+ee;-D~r ȣB-AQĕ2 264?SYp ]yF/sY^7x5 Ju";#ட,R*]1yDLe ?RzRN ߳PZh=sQ.|؝noqn=vowblso߂Mz==g尶~Ŀfw|37zşvo矀O{w{~u[D3l:sWv3W&/\?vgDIQsR:LmDo407;^̬s׻dNR#Y|prIg+};h)eCn||xFvϮ[tJA֢KAWf:tR^70=~Ղi6ҾnN*Z3)tO'HG6$tJAi[=;h]bt)'eP?mNb i~xAz i{jP#CStp g"F@ 2UY:yi5& T$*Oc ~&9AKrbjߡn#̓,Ł& ]& =R;`鼁;h[ɵg2t&M74 MLwt WHKVP ,M`R-@"@$I1ȔCɑPt7jUs g8L6\BR^O= ZWPy# Y\d"rnmC?x zGj-!V%﹍N4FӜTTfɥE$\Ŧ?OZPefKS0eIy|LqdHϛ'Y[F<3! xE^-- `:dՔ`[b{̔u*hc`,>p0τ̌Y@9!EI<%0($N#D`5g~HT7$S8YZ,Ƴ6%9+"xkf&Նz9<.`E'!̾ ػ`a*pህ*&gK<%AVI'juY~c؄#2Qbx H"WNmc>0DVZd NfOek&@#0tQ plrYfSC;1Ei| !^V^Y/YEJ S|Y];PR88ًJB<3 Ҹ >ZdQ)>| w˒zg@La"iĥ;2s,l:)dF1,GԽtctK͎epЧZM$΅'t"̷u u@Ns4+)YLJ( u-2ҀGJK:R.xY@sƮ!eB1D@T+-TnWD,Z[S.v%Nf k8`!l8k­/ X4urp 95>l%qgjLJ_UW:"Iu} hy`je6Қ* [9Va]Pt$tADן(NpSWm_k対='fCJٳ`ҴۍB *-#Ux[آ *?rī% Zђ3f0ildҼ({EDH%nB-#n6g mۈ٫+`)46+ YV/ @g:-ktVw8١d8 C\!x0V{xKr)N}_~Xoj+[^v㪄kA۠ݷ$,Y&hQբByMp`vyQBTSoH$$ .GkQf-6H"x{o^DCjQ@yize1RBu."K@najJՈAAB쪗/F_ByQV+ݢŗHƁA  ,S~>+/p_,xPKw}o~|O黿ӟ|'G/o>zٷO./\~/\:.?5^|Wˆ˟.;.^˷{ÏZnfmLju7qYqcf3nL? ߦ r /ېE A)hCjMY;vq9bn7{?}Kaس?- !u!Zq _iܭ){$;6FZ4#h 7>.s*ZƔT-JR AB2^<ĵ c)ڢ4-gt0RU[r_'0鿮{x+]}c.'\SdGH녮O\:;VZwۘ鋸7톯V1loձ+ 6o-^:"v&VYD,m+K.Q]11Pid. 5,`YtEDOWbQ|-dpi~b{HLL[@ S̜w:g]nE="Va󊏖I?XfPdvIKP 4%J]/}Lj7Uif [TCu=" G,xX׵ְ] P,gOx BФaP_T\qW`"~p@8DfBeoA0RTZW Uf',"f&S׍ddrpW(\ƛ6K]e h1X2 t p.rqp z 1Z%v0P 2E͟/iCJYoe<1N2J ¬XZ +6ѯ x ;tʁ];`SEnT Z :;o C-92Nfm%l7@ܩPKM8oH]r U&cl!^FDb!]"ns̴[N,҃g-vN!ګ=&a&MK(+P\iw,63)9SPBA; Qlൌ=Qɇ * aѬqCڛyfE~8wÈtBgDK6~nqhtBe B OΠbYSY g9g΀V94őuIVCS>[KPbOG~dIx3_LTRRq0 i4@A/dL Z4hɖ Zu:e7mZv$o4i(޷w4!Qq7.u@9o`T5FÑ=D2!N-1tFc")tI#$L"VAb|hk&qBXh[^PӲ}"#E$y-\Fڝq2w;bW7} Uʛc4q-OȥCϮzJC VP(j0oAy|? )y%ޠ2.eݗZf716u4ZAhg35E F3_ѥ7 +p{.yM:6F1)tChTw~y ԉE^OO9Tc=L 񘙬WY m/]4pQ|ūs5 ɰtxr(&p r/~!=T ȼ)hVPQQ(8(ǕjlqٔiS.48QBO8I7iӈ٢*q .Li}SU1k%sPӭĖ~99W&uM#5ޜ--r-9 R6xDbT[i8J>>Ŗx{Y ~9 ,5 AƒSVxǜwϧxc"N֊ӵźh 1>n/)O+z׏_/e(];7fqD&ECPHp 0#DSQuzŌp^y;ʛԪxS:`e uXPm$`ΫȦ4uǬ!@sc펅̴ fw}+!Hr§٧enހ(4}'0ʛϤbVTeU솓YesVRعzJ0g~F`\ѕW5#mTdQou1nJ 9Nb0;c\F}2 j3 ?/ H֎2Mۜ9(AFKYr[h3m-O>r`lO?G&s4]Jt( >(كY;$sZ E*x(ӯ{4195(VR>g'୎&Ez@E@2J:2'[OluPhR*~A95AGRlY+)(.pz|ׯɳM ANpi=iŇA=Y8Յc)bristol-0.60.11/bitmaps/textures/metal4.xpm.gz0000755000175000017500000006140111233572001016132 00000000000000fHmetal4.xpmݽ]o]-vc?O21Me\0$c08@$A2d޵>jwl([UjU/o?__Ͽ}{ǿ^?|O/_>?Tmv~~c~-1?ܕ2?1?<?_i~ן<1?)e^?<1?ܔ?懏c~Pmޕ?~5_^?{5_<ߔ?oT(y/1?|9?_W??<O4Ȇ_n^e-##n8|»qzw~K:_s~ ?i'hGO9qK/_45ʙokT %e:'N_5_P4'O`z L#4g ,ê5q3dkgz,%,+/>Γxo* al_fd#ÄzoV87*OA|(% Ay'N7aOWI1kH%_QܛV]2T][v, FN*OMƧ Kqh}H&;8_r, z߮ Л3&trk89ps|n~PʦZky~֖Y)zN X橱όzz\XH3j(4f;_+d)r4e , j@iY*w\J4ޚg-EL3&E${ D$Aluɑ-ۤ#<=:Xdg'˱|?J&cEP 9zlNє,Ԇa(wt_A9L:?ƿ_Ӵ DZIa0A"0?4V3u2YdLpES&WGKӏwGU β@ʯP.+?B,JLx@&>7F)1EJŰ0Au1$=gtԓ:UGCC~[|ZC%m,>q+XȫI@==E7O^m^ ZKgmJjB긊~Xtt~ȃC ̆5pq66sO'0QHr ؠo}neȫ,rst2ʹJVN3`OTi1-d4Hj/Rw$$F+RjLb`+JljWBa2c]Mb[o1="rه3qT*׵PUqY~#Rs'0mƈu9 #2w4 V쮚OayF!RτR vZn<9~$QU4>~DIƲ}JPLlO +M9Vs4L)4[$>y TS2ӊ V ,b%f(jCw, nxJ9oR(# 93] 0R( .'ӫ8C3`ĂX4/k&k88&'}Û1WDF  ;BeqU#"R 8·;Zb  51|-`J.rT?WgO)GkJ=xD-+ ̓ļx7#pnFg;?->EKŮcGVP9vY3XyHe2ֆu I<!?w)= m!!~c @,˹L7eؐGxZՐ=ל\bɴ~ jQG>LRe,4D#B'$&,$-3>T<%{>f ױQxxIKfdI)13ʺ`>}8*@%UQq,t*~١~|!ѼڹfI3D+d5| 8ìh^|AE (c-V6X#\%4@ӗsE(<L>ibu#`'TUIkFVL#PV?08)d-V@& ?)$w7} ;oD 7('Rƪ*(cz"/{SݐkxyVTmj"+(ʹ7Dv[I PB4j"%$n'dz•c[HrCIqk0,\ 0;uĥA=dg/e72֡Hg\k>9`1qV \ǿ`S.K Y2۪Գ`  ~]HӉMUa?aFi仕{a/IjCdk RYbrR 'qIH C{C@ ]~)xRDA<ҿ/ڧ,)6LCE]%Rn[6Ma2uZ_g< zu @S&~!LW Ir#66!h5a!ZS(~^Z3 '5oo$dk"(+\u2IEe&,ʉ dx 7]#,BJ.PiD'K YLX’MOd#O7gV{c̫d-E "\]F\φL$' *=cCYBdsTtQf&a"xചT~t`) nmR4,"atZUuSqS:8  |RaddI%.%u>:ƆY1Կmjgtxy驙!gIqPNV7ƽUS*,lACҀN7սJ.vzLNrQ`pIQʣߢXaXP>q6t>P"|Q)FbL 'AjЧbџΧ)#Ͱ+Q9iṉgcpԺ0 O<;A)=u "wf\ dUl>Y#cd2 hIb7ǽaLS1y =ϼ49EB!^V#>:#}|{T+]n3±a%z V-w`s*\uza'ҥ*bDP{4ЅQ@ [~y>pwXN~⁛Ř')GjKb=~tH9&X†8hG `yJ},ӛpL椯#?&K?2FVd8ù|}G"q1Rdjfg'pi2~S|ĐɱOa$?&\=KL=T )Z{&gU $JܔUu#t,w@vK@:x&y+d8SCUuXʸ% ;L"7RAbҹ0 Ԃl>K/bqʉ&ꐳ5cbd{*9- dxLt)Y)vB{mP٨p"izEg3PkfM={g\j!#)KVGuY%sO-ᗌvΌs yvd_"\-H Q054 ) . Xk lҴ7;KơD6ȹ1Ƒ AtjPrp92OzH)]dB-X~ LQCFK S*2yrSab!gE4葀zpl  `3/#` Ac&˥L|\mnyE GOez2J^yX/dJ> LyAӒy\vp&*z* Դgny{PTD R) GUŜNX߃>N._L'<<&J%8տ(WV[Ef T"v֞J4hcoy@^lߖ?m9rkIُoFM 2ik.yFKE&@պL%A %27τl%iP#94Z"Pv9~7nݧbj8ŭaDg/OyTkߔ ]%VΌ捏M~Ґٰs=y z|$$8YKQ^6˥L\xT-1AFAʈ1)XW(f]I[h-bbS 2w~1С=D&!ƹ\E(g,^ y[~ekmt; "&#SRD]ӄ9'T edݻ(f[EL)s>zD~ L&oq"R&1)ϗT&)%7Fҏ,@bF:&%cVb219߼/W.A2DG4Mh9|+JDl/t0P#^u `{tDlJʛZ黤dԅԲ"OP ͶW20Pz1'5LSD>.X/Z˼Sn4M{|a'2KSB#0L)[`z)3ULmB! Xjp{_eg0i3#=r&!G!6VK)5!%SKO0-t m# vP)SHڊORSH_Sy AKI(ސ<հ&'(W2`]tRTmA$N>cX)("?1OU&~`JLӅD1iPc M(2WbV-Ѫ̽5}llbiFj$ ?؋Q@@G8a"RR_SrƔ^0-NXw>K + 952ܱs0J_}3E'a/` F(rv`Fg4sBJ04YځFH8؅ha̬TLOmJ65Cg<4d@"TٱOQ*o 0J5pR8wwfe96bVVtdLgPJ2 HFӕl:-Z Ҧ)c7r) 6%1U?0L0r"N޾_ ScdZ ӈc Q3]lչ%dD'sA/63VK#5`c%q*Cf"d&MAP3:"14@kSS%A!qJ} A Q(ꐙ]tkl #bސ(|lBPfQR ɓ%Ojq;!JDJ6t'[A}1OGqsvJhP8-&E zK=F?+/<x˵ j0-)E,wv9O9Dm%g27vHA~L`iB%qHb49F0Ukj;[(~X!W%ӡa\_(dr {F2,Z逾Ӻp`v | 6Ka`4J"TBުRػ跕;81a ^xq@8D#"CK@o]:MU;11i:ReXOF0ٳ{e.fyUP_IfVR*@V| $#2[LXǩOenm?}Anr'oĖ#8إy[.[>va+z '2ٓ8v2KRD`YI~[n80Gb* i-& !"챙dr!o6ZpVӾI[ ,|b"~O!Tv9ĽDx`_2̐ j, tߺ" 4 u߉D{Uk:^r}i~ Zt2 TLOp/@Y,wZiٰ̩ ؤ6ۯfrjĮO(:X.-]m2Q> ֵw#8spxf(_0eM5NM|qR䧤97IFgXؚ.CgC{!U<? @{ uFT;,H( Wkyv$` S@&s9WvBwhr#I8}:;Ec o_59V`}D4 X yϯQ;S JB {Ә^g`;77 SܬA[>D$Շ+JM#Ò`s+ Tߤ~H&P rNa ſ 3~OQt c˪pcQތ#TzM{n}|V1*97ոH@[&-SV͡F܉ D=/`== m]xO *fӀ[ {T 8lB}JO4;FT0l*>trq1xfAy8Y~HDR?r1ғ,-%![QI}4_mă^oݥ&ֵ uiudtJBI,x9 xpD"rOa͈oIlrIlPpkQưxEG3o-&ĺ֝:\-8Tѿ3:ѻJK`Jʧ &91ڷpZXTƭ`K O꾶(l=Ӂ_VلvSpˌqE>P?'#Z*u|p%(̋.zjmJ2픤I&aUlP&D<9ٓC 8z#CԢ0l2ΧxXѬ^K%$#|$φY5E픗LE dRVk1l"H Ng4O3j$F 6G'c9ȅ㠕#]χ'ʖa6{ei7? FSjfbJwx-<6s^w_6K맾j)unWi&a X1$d}##dJ^H)݈.2(QƤ8Aw4񿲀&:},=}$9ci3{1`eZdXi"§bD2$XgJx8!S~֏|$==d׽ACksf|Pii`I[aƥѲ> aL{H6y$7q<+])_;Z:cY q 6qh0:yB?PHJI192=Aw*{"G$ bv%= ƩT:l::XC }6ɮ0Xcd$p)M4q8g.AԳ~xIL }Qط>ʦ̀9^ c>;euP0lZjC*3 j/1^mv]1X ( $>zd`W~-j?wX{Sz =1ʁog4T$Z^B-\VyJx6ҟ, 'd3, #x"=}M t&9P䒼XmaS  'uҗ!,sŤQlRQED OAt3zhRNZ,>^7eИf̗gM0 }тY"m%4H)@Z!"L,M:QOu}$IM6r!dl1tʞ,r#V(-bQ 9@%2UMq2I9 T"u4kST40Ǽs!\4:Wyi^ {>l0)O<:t<,H~B"^t&N CRN{D99uuDSOfQhwrM]vΘG>>wr8C9T#HonoT-BSuݪtn7 sj eώQW7e2)+$3AĽX%O~ @G4:P6(%RLO-9tϷߟ_¬FBTjg֦JL:T40hh_~ȫ|‰0Q!S4H#9t0Wqrʝ,UAc(Nc6-/I @|F%\jE@"P[M5)qQnPjWL;4,pbA8D4,0r{kYQo|?BhVSkTXI65ZڰEKIz@*PCkL2l49DFpJ"奈`]TO[Yv?+~MRD/T.\Fap܍W 'm'>DF 2in([ʄrPItLr u\] F|L6C3+ݑdQOJ> AaROMnjOiVHq)ir[Rcq|7UCӗ z"uU'$[滪ʋJ&D‚Ld?X FKCjPf|!+~ÖT,oF6M}\,gJbb V_qk8`rD6-]"c!06^Byn 677vƪ<>M%Aq3ٔ,WB;¦:(p[w,MFI)M "DoЎ0B5 1ofw(Wx7<94hjhdj =3*O+E}4V2 H׸ "N^F]DIxU]0*7W3fR\RF&9`^4zHIz>!?o*ds=PA,tGD'5lZ}3&P1aά꛽R&jF&*n8OpϷc[׸)LP&6q7Q)+>-_1+Ө|eMN!~) 8CKX<&Hwf>@8qX{{_YzpԄO5de㓻 O6umΧ]x`zNWI|'c*c=#HtW^AuunBjaoWUD&*iʵe"͹n̖&kQD9~تo' lq9@G߁(uTRx'h(Un+DuuEHDZ~L53溉F$:u$"IcYםp8Ʉ8tK,"q(zR{] , s36 RBV翋/Icܿw.&IV3?uurL9\ObksKT j v90R  ݅nCvȉ[q1DiC,-8}FE<1'_kœV7e-+ƾD&[{A<2tY{pՀ Ƃw|ANR 7CTAPX}%1{<-^KEI"uӤ7 y$Zzia9$BaUMyAK9_(pJl@$&>nT/^ DPHg䃔;Ƶ0}1e7FDwMek͊/BCR9c u,#s1#OiH& Rh_ UMiQSދgz1l(vD5bsj׵KzOO)Z `?Haybfz)[[*P7t +7WhwG2mRN鋢Es2~S Ċ D"{Fټy<qFUmc9xF&G`DEG{0iSTJ]E07#CWc{_$oG\/.P P< A苖7.Q=.kʂ+h}240M_qA!oڔQiekZoj37/,Qs*맒6A"<A@VFű*d}aqji@=m zVURL^ޛS՝q+4%4&+հ7WBH+!hEu)jzQꆻw9_T9ā1J(u҉3{Kav` LzG'd™\`x R{=D=j| 6O>&u$" ƀ8➆ vTv%(Kh"2Ã&o&%~hg (`կ!l}Sc\E:kXǨ~Z\/0OXs`?eґHWC7TdxoU: WS@'G*%W-Bm;)^+9!}6\=X>0q/OKz^2)0g~*2vQ 36 n0}RJ`bP5E^>mQ ~m ;,3L]&c68f2ӰTerT*o5b[8_1EDkqws+1ֶ<4A.qgÝXs%j؞gyf:$7l{@ 5n-Pqs^•pv?qRjb rsg3*wWM+Xd&Ejm K<1Sp.ۏUD"!U6@Wv4Vx|ung k0%M/ ay#^<>'a9\:|ӷN6]w_u!#WI?4mvhCIDټ"ۄ͍=4Ȭ¢+RL佮%tsHÜ6oad^4h5֫RTlmz ԬX)A RESq~|tLVPyjS|KUs+0%)/m;6{"O/M5LExuf5ui Z/9׶. hCi'n) f#)\t:TQB Niɕ*$&ۙ\/4\=ٌ!+r 8 PP!p5@դT BMoAzB\mi0VBG"l̖r\5<=6IG'lAq< ߚ. r A #S=8dyXX;Zpi/A;\dha ٥խUMfE$˕^]0y<<:bÃ6J9=IB-1-YS}J4Dih =ڶy6gF=#msp?mJMy{e F΢ Zp .K[ B@kܧ"z{s#mrvv~WD; E:-JMYXFCЩ˦y;OB: yWMIAZ^Z^)!c5l7M;U&@gM)]HhΒT"q& eI*E>vj% C%"P]l6W=7 ƅ,˱V:ܾm= (sV6/86!Bkg^ʔntǼhN$ yo~rlFN+M$m'+Dı^Q#w-)+ ency2 HNd*G}d7ir_#ppjqp^O[Tݏ8pH; $B՘w–^K_7{)` `|?D\!eiPT)TR~L1= 2:{}ذMˤa;[~ q̭4@aw{e&zDAxKp5!ŋ}D¼R"O?9o⓰i?VaNC#4b.,Pi4XB,w창-1fRd&6rJ#z'Q$"nR3ԳHXNZmsC||ITY_L%Hx~Xn9%>E^hw?.uF5bIĀKef@[zٌWy!bdBhGȴ*)A  ^Dq}MAM0%`5NirjpFrֶu,.n*<[Pjh]PIJs``m-T\7BUT0Wp%=`|ʜFc54vnU |AG!"upu>zN@f:q!2V-a=eDD!bN?I8 8Ut"kfS}) 4*ǽe/ٮuG 4c!7x^@V FDćxWkڬ{˟ To+f?D-k=F5>z=Y.Yv:aHEvIiշ9d=>9DhNis5z!fH ^Bƹt׻O* T17wPuRs˵/%wӜ䔚u̷A|r^`Eĉ_']6.H^j~^tj7\jIDC,tRT7租66AXJ 㦘O!LG#U\Q:uI:,>+AT ܫ[1!#û_L?M6bX\°r7JزӮYYS\kҢ2yW.+ GNiKM8uS Q)!ed`".\̄2 6P# Yux>iPVuN6HY.PۖlDeRt}œ*pS DQ:Sr^pJՉLW$R>d: \rxs)Y bhH?VzMJ\%). U⧱вšA#8U7E+0]G%n ֦Q6ENwa޷MQ 5yzzmL/!o[.^Ob]Ԫa?3}zglQl D?#gm8TDUtסx}aSľw?Me;iJ!4'`s*55@ N;iɽMgBf9DKp]]}uDžM&en`FWx,/ugщ:]lG+.v8-xICMq10L§C2^BUOywK9JmwF-V~Z=͍$6гŜC|.e1h?b܇t}lBz zhFM=P>"ь-*\^&":uqǔ*g1 [o/(WPA2i|L7?Q aP[#-aqKMK#t(o9+8 k3_Ձ3pZFi+[x+"+pm!S9"7̺i)/QUqz4N;l<L 𪎷v-i[V)\ P|x}> AxE8dzϱ^|qNw1ʖQÐ]qѾ["DzT,5QI˅1lB^cHAw9*L?[T.J4K2'X5 Nc='&. R&Xьh І$5g>O+\e} X恾+ƈޓt ^P>_%t#ĺ7h͋gSTs'(o.LiاHq.hd6Fr $WhbMmŢFh7Ǻ us< |l#lWȗۼ5[\J ;#7ϵI~l6x ΚaxҮ=1mEͳzh3 1M!I _Dcڃ6:Nsx4p--F< hzǖ>P6nw@FA[J¤! P}`ܛRCK@*e`ep.ٶo)T?{r`@.觫XZVꃚ~UyMNaCY**w(".H&l[ggj8Kyb]v!OZm V 7N>*DM(7S U xm;7%uحtl/i8QiimlqSQV(]'6A+8Ep#@zME4$F_E-O){%8ʃ88#S,k&]nqBŜZa i@*[ |1zg͇?taF/ ١ei,5 lC+:5b7w(nf;DPrn7&<"T3Z甛lk- =iHc{T}rk nȝԮws2AqKGA^0Ѭذ J_/_^$|r?͔.ċ9Gyx\b 8K#NR 3q!QX娚|+*/ൂ|t;XWdهrT !D&XsxǘgMBJ{_3SCܾ}>v(HQIP\*IܬkgLDt h:[M6f.WsУjQ/X^s z#m!;#"4uhZNɸTsS[N{Eѽ\цS}/Jp58ѪnDz\zrr`E" Jqg;ߪ-d潸B&ulPiڦPCsTa?x,68?kmn#"ʃzld9甄 7AD{*$G1<;&" ޼43իW/_|̂^IMWLaD til"\)x^?Jh_G }x/g^C,&;5J ^wlMӍ & Tp;خƻ5{hƐ€'DJ{iǫ2w9(&>i 4F6gӆnmN~ކ.n1y~xD5-E"YȦB,6aڱ0aפٹХpǸlS,=md(?"N'pp|[a#^j޳dm#1)?qaoOWW:1OEj j%T6 zwYȄCײj4߼S+-şN7BB5p,uu'mt4}ٜ"'̃5e|=:b>.&7i3"w\%&%^ [~z$rsSz~{`>nqȝʧh-X7.:7u<M^kbJ_^m&CW%+խ]?WW/_RinlF7Rc-#b\;5n*EBaH޽zoM*/Uw5^WͳMZ&6 ^q+Jg7z$Ƒ}6/L"hĤ:|<<hz1l]ms a}xO;JP37v5N5Sfm^S@kк0壘(4ɢ}Ѹ{Dߞ!o\15_ȶAvל~r]䪶W^ûz69}llquiG'?Q|h*R3LX^f9+EΌ~K/b89eΌGX]T҇KE>TWz>a*7i\N]!߃Db41$x/)^m(^gaSt&;&ݭ2f|M:\!u aw/!"B X>b  R7)l-´@Lus%<5:b TnⵘB%^rҟwoݴ<=MIQNGx6^FFoy5IeL0]j['_Em4_2]W&k?!9MbS')2w&g#{+f4TRMCWa|4U׿&NF{n{"X>mDQ~}T P^uڡ矿)lAT/)q P 3X$m}}4:MJ .^mDobxW0K%L>l=YhM~qXN#9PKqOX3.9vSɈf]$*TڲhLE4H *LL LX_cJnˉUسWAud틜/󣾭f]1j" @A;)=*C1;۱zoVM˚Dֱ右sgn=4~/󀁼LхE_b7dh.^́ͅ4'|mMO{,81Zje WpU-(^jJ[I|I zz6"/7m60Pyݰd ߡmVqb2-%{OIE_iݔ:1>Vjj)]ʐQ,AJzi仌 엧{ >?ߗM\؇!y=# Km' 5^m4Wi)]BlKhl5ˇԃGZe e|WFW-U qyސE 0'(%ΦjKLkBm֐ ֕ ~Q;6yuw.-Wv;M~Ek.rjs]{찇՝]oa"W zzG>و^@O6$/ qo/y`zFL&QyX8&ɧm@lcP[4|1#mugHyO|[nS "K4_7mdG8'vrO7RǣJF~oӔ^ykqds-Jszyhkdw1+Q772#Vil: :=$.%.ܫO_>{B|!hMް"s4=vuWU|x5ǻy݇w}ןaW>l8fpq>ۇ }7>|هx^63b\?]d&>qgYogk}_:ٟ' ~s%jl{XKڄ\g>gIy>} Gস!7I:Nr< ˼u¾IX؉ SnBj -N ڶ{_O~] t> y%ÁQA3^uQ:W3cDOD!!s:?_`F+ Dh^gvR+a߾9εt ub;2i8$ `*G( Ύ k;GpUJŁ˥s]SJt3>%|da=w),Nc7*6eJ`h;%.?ء`8* FAfN!W:ȒacBQ bLu7mGF(V<$4TY?/ee^#!]đ BmrP(2ai xN9_þf@R&p)L */$^2} melt.fJG?"VPAepB0N9 2a+O; G$<>`9mP6')M솓6Cp<^uZvT 9͒j7b(8äa;"i 5 .i$q`۽Ss}&!A:\k\!/Ѷp{a֪qsTL$sgMK9rj'kŝ;.g箱'۱5mX54w3T^jg= qW 7`HuŬRqȌnbS\vi8{B?Y;Wdtn9݋l Λn 6= oB-;ze`?=I%#ֶH=0^*AbEm%~앗q;jDe8Lym*x٤AM|2d)-q1VDEPX?G!)Zf25NE5@]b;j0=@3dS of(tRi\M@KXwa $n;ȋ([Tn<& t;jJax>SteVy_unpX#rHWiR0fRUzQ/.L*wFog sSs`x:ĂC B\.̳ l31ULtHZej[kS-ynM|fH˜dxw+e . 01g5x"@ ]ݶ?}+3U_u^ʷI))6_kv?YowϿ5uzo}9mp[:[oo;e_sƇ-~oao|xLVx4adp0L6=/|8?a c*㇣f<ć1) >} N//O7#>8]~8?chM>C7G=?Ao?ܻ!kڇi?LJ)?0Ňc~^ UMza:OZOS_$q/>ο?ɯy_>U_?uů{|n|Û5?=r7ϙIw/^K~W>4-U}Y֩gj}n]+ks{'k\u\.LYL&J3-͟>KҙHt3#;@2@S3yv4CYk;HKܩ`w4ߢGu+Mt&YjXvfL4;{fAi͸w͏ K)7Bj7Yi }  qIfY_-n"gY)W:%-]fx#6Z䌍~6ENKU z_Y_Yj*,1QOeTke~%(! $e9\ ∴ti2SGyx]xҜIiX$'MCX: ,/̡n-Z}gѮo1 YMO1?Y ތ<;zCZ2{SN,)T#0<Ji?[o˝r' uZg~U.'`R\B0|*tB:fYh+ccb>8ӧpd0*—X8t6V Cև dvJD~ xC3RxP:6T>&f1Z3ǷQp3-n(2g^Q+bR#Ȅ둛V^t2cpaK3ё .ޥ%L`2go#XALҵGtg"73 ,? 8e5 &2nKoghK9 Fe_]s:mQXk@̴Ef_n0|~e#+IM|jyBۨY5̫MIs{{4@ d -)<]ZVZug,7Y턤Fm{ &+ӳzhxxoPv&|s ԃ?G WMzPsIcyFT;3vcxLқ}FPU( Ԑh3pC}[Y-#=]FdUX%1OcBU ؂Cj9u%ڳGkþ86]w>C ~J =<>y/7jyVRKxnFcfn78광:bGmt*f" ^WMr<)ɒt^XaBbSr%M͓xOgN5pP1;XZYKH/}<|ap6̔Q41gBOݽUN#XF(c;Yu;ܤnCPoSՃce>8=K!1m[}Uqr@P|>yϳ2=ѭF5XmַhBG+RZC랔Qd/xj*gZc#v\j v[4 ~B;@K {&N)59@ջ fBmS<*Y Yb9‰̰ETV=L+!3兏 7|S,%j(0ͨg\JOOV<8y2jgst$Q X(,*I,ngu>HƲOӼF(B1En[z/@n`s< NNyUlQ#{ŜSYK~&`CJ8Μ4#d(NR)@F:[j&ߌ)0D:q$)TppV{*޻VDNV!K1D "p&v $syRO69,L9X^]0qN5"Yci-g(o A]!(›zsAx*Y!aiiA{{@̓DhB+>VLRۨws|D3RAՖW +A 1ow;^ij-h|)(CKl4FW] uOC}T՛9f$r/.8bj9hd+j&KK./ !J!*އVvVVZ;en?Yn;h2g'K]63wIn9j`h!%NH┟0|j9^35k*fX頳6CU0n7g(Er8@e%(o9MQ9MHOM51Ԣ۔Lnŭżш~0a$=4nP3z&V AjAPCu ˅j>ئ0|́d͠<9a@Hov}K]ZLQ $N"].5[V4Řݪ[?bCRڇ=gG*o2Hu@ZHQ%̫3 7BH&pjh U=OYܲ`o iFz)61P +#*9FE|7Cr2h(2E=p24Ôimr4gpʣzghԞrZ%u-+)3T0gAv*w^rRJgOOVeĕ٢cQ/en# !. pC"gGjZԷ3=7ר##t#K=̞RqIӰʦVrNÇjD *BʝB1TWu"fP ~o-K_?Z8/vNpm`>ͲZLޙ׫jbrALLe,9%9bªS~$Qs(M'g]Wr"?i5 i`lD i nADܢ޸+Im^ݛN|"1 U*Hǫj YC̔2əbho^p[6%a *?d&ۺO1FnDuxWO}CE U0ju~О\ S'"’aS>6+(F~<̕ &=х@'јN9%~X{DY ?V0m3;wޔMުNQQJғ܅ώt9-!6Azپ۲r`V[]2vnWog ' ;BVWwrBi,X `} ukfA5:fy@;Ҝ%G$K r$OV+E]'>$"-4Tn8mr^@`z` 8zd'o Ϫb &<-$<`cNS D6XFۅh1fcD@)Kd YcaB3u ahҿhLVB[vNx_scE.g*GN9{5e cdi* d:G'*} v\ y8^ v.5a틛7Lcg+3 ޔsHmRH6w[fU?4PE}Ů%kyS۩9:Hlp;Lnl/z$5/G"_MJez)wm1N.ҿm}.*'!hX0pjfx^8oiM_dZY_|3֫(SL`w7.IQq-eU[}쐝#86jђW(TBӬK'̍LĒUބJJ@ X87 쉶@gׄgp&T83^\zOjt GOJՄ$kEAR:e&qlj6rhnsF 9+$;ctr&S󈱓/f9ߖt&gHB梄c/W{hEkpTAī\ERFːW/Y[r E`nng0s69i8>|0۰zA䦻3_:ySjtЫzy®=>yfbbc/[u[7тbDC6۪[U˨MVIf)>lhKz`Y;ڢi'^2.و@A NN WfSe'C'-HzxؐF|v dp|4]Mǻ^r"5/)§Z lE;8joZj2mwJLlLf&!@'ؖVکmBpq Pg<˃_ +Ad+V뚡Xn? rݼrpAQ6Zhڏj)= 3MȆc[&h7tKC"%\ؽb,bS m1̡Nz=-dͮLݹ7WGb؊>+sTmuuHh D#:w(qjA-gNUE½ o\"3);~Z왉g u=o1e$ML2 b!zzݙ;`T=)]ɓX:^#Ar3e} O-&?L3W:+ӶSZZ)Ėmy˼SHЏEӜ=A=Of$P aAzzK>RV#.: AbAZ1 n6e/b/ (+O(oǮq=ylv˦HUOlN}*FZfuZzgSVۧmn`'GCQw'Z2nZ#̓S[N1ן."̛ i޾|B){L0VD0B{mƒ 䜵sʼn}r,I_s=cIxPA(frqL@M%aѡv1]Z-zwJ70Ǽiwfp&[=w6%'փ3A I{49xx=(vM0*#7UF29uW"5VV6M>2Z-BeCb֞Z̃ 5DL` ! SnwQ_Z 5a%y,4i:F=%%C^yz=3= ay>.,6E0-[p7eZ*%t hDN9wj4n vT:/c4"倝 .pV ~oA|2̳z5 1(U;DytCzFz8ݚ;Ey["M)v?0t}HoFؑ00WμlJAkK偝h`rrbs?.d(=q=<a m_&MV>u C3{l f'鋽I,Qv66<\vW~MKq*Tu |.V+]WK\?2J6bA4u+79sJB*A:bIHP\ȸIO='7姐W2Zn3I9zA+g%B Pݓ)f+_Q_>cvO_&=ŠTA`H˰?eAJwI O,hs,V}z"DTo9忂\.Vm.9nӻvO`:9d7#Yo"!0)'=U6ݝMA)ApwUz15bZ?zzb@մY % aOPۧ/[ K IG5ON˵էtQU°{:  =a D m"Qa'n_,Y;!t`:ޭCg6n 'U<2zF+yx8g >eh FOp/3y8Q C㍂4Yʺ1hizR=woY$sEYtG[yK ض!a=zy*Y'S.2+d 9,] SWVZmUANOh@/rh`YF,ߴ!݄Fu/Q]BzSd>EdҎ%>+|@"FeK"8y#:(eT2FuM:ҫ8rџZ\638\>F@u- bO+_tRh1owPBzRgӦ~S!Q~=|=pbsR| >EfRqOtX/)3ѩ̇$]VÃÐ]Y">I` o9ABV0Gne^Wvv납㘝trdz:.wj zi4$R_oa)C BH!5;ôLKc/&A,/sEnƺjU!NT:RN)zxZ?qgte'w&qNkj(w|4XA$N b)|.׃^I ',UdhoHєzboF ʫ9p""Dؚ]f(N@0ATȎ|>e&o{d2)=}/PDI.ŖҮD`?d) 7Rp:ssͥ:؜.hͩK%DKRjhSZo UUC4r(UIu:ckHNڛ)!5XE;Jc6 =aDqe ?vE̳y2S`F`രW<]PoIXc9jMm?ܮ'c8c#V`ޒt [I@7UCW%WĵMplC|jӉ[?3DP ٺJɾ<6IeE!ٛ;IRD$yAQ\)F&Ӟ7ܘ^ҧx, .fTS oV-^>D'q;E*&\)T\Xy<^l)m0Լ ]"}~aA ygz5o8 Qݱ!#1buЗtlւ%EV6O. ' .v]_oك0Sa <08Ra^ׇ S0YDW-#6fDWRi%pQH~FxR.q@yOd_,;;JҖPsKhFO‹wx&]H_YwNj4"vlrP jWJ%r+ai7Z&vn] M{ N54ǺA-= y_M'f'\+|峦Ȥtf^+z6OzqJw~AA+!CE{u7 6z`;Xʭ!\1<NX NBNHh^&v"Ϋ@XtGt!?)06(R Q,g,r0 (AwB-bk#e%!'a1R8rF㋒\Ǹ" ]ڝDÓ0bzm#̋h'O|JgxfăG=#w(%Ŀ D6wDwoz˩Y^yF2 4:"-Zr:&[tGrNA ^!':8HSG2R1ApdF9G‘3]Ztj)wۜdP& ib{̴3w1d yQtЇ^ RpwN"YD))ƒ4F37`|;VDE.ɥ|wMu(/eiCzeRf^Gri&#[K9wO0U>y*(hB>;OO N9{C+N6[Uj ;=+4z~Ry~B{ r[8Q/'/ZLNV,ڝ3]wb'&|+J,ju%%B}a˨w:],Rbz fN>@4ڼ!yj̩858M ƘM`S4`ܓ-mr_BUAOdg=>gOfزc=iBd.ጨ{SRQOXY+h[ P_b$9o9S8Q[QWҵ0-8yռiZ1p,xp1%D@/xzE_c zEÍp/VK[mepl+%m7\IglCU}wZhڄe9U]BzԉI,VcSmXDGvQ7Yq~ .EESdG8AAP7QkW0XYZqRs w..-JD8^pN}*F>مx󯟤Ѽ-f RI0pޕ/=J5U%ALm"T0rpSvrwBDg4u& uo;IdCiB.VQJc"5\W7̡~w3t%˾k`ךリk=+i/fbo>qEe;OVg02eA6?A#i:9@WĶ[g{e4m`-iScA\sf2T^E,^Wo=+\ߚ)ʵBPK]EP$J$9*nޓ-5~PJ_N]^d>69h$&l\+gd#w@۪fuiUbigHy,SB"L07:<3ӎ4i^״ 2RJ>y|"΁^Mƪ1Q iwf89`Cʇ;yoe=VT:!n(Y53GT] B, - !Y'm 6  EGփ+ wϛ]K[{}})vvІ`*o)ORIFΞIUv*Co gx/ 29iNSㅯ}f/6RL80̣RO"z{%$]YcF~ک 5Q})2zڿռ f@Q}\¼MS*JB> 67لi/)FW.yĝ4#UJk\נ|EfAoÙ ^QD@f{r/_ O|ġ'h{3Zō#xJdnAif[.wt^ԯ[nR4Xz$ 'ÉT3g7]7y^ C <.JMu/m8+c_4WI+mྤevЛg<~qw>ytrb~0+Ey+'+p'"FNOKBV⺭69 _k=c4vZC҃Z+ɕ^(2L1R t*sKL8=tRJ;{Me!˅g9!&tj_J_ZBb T—fR>DbʫuЅt2!f&X#n!.*szky*ZR 5-;$CLOx=m_q߾~ cD" ?@{I)Itj'UI3 ܅"*>vF;or')`ibrZAzDcj\$[&V3q /uJL#H@(~ ^ 'vĒ4JN4wE7i)g<ʦVQ Ogh ;؏eRzy!_ƒTYɉ9 b5v"olJwBMipuAV2|^KhAU犏TGuۥnJs3!SQ.6pc*]l JpE:ŽjZ)QWo +qF\_ 1$UGPHL_D$̗^}cG',y7q,w0w'Qpy#a= J1 (OUOjz ~9 4q*͛N|Mt K  ;E}e"6W4`{#Me s&RZ, KXRrE ~IyP䝈/k]W`埯nϋëAR@||!@͐' 6fH{T9]\cF6?+i| C!7*u-H'p !U[I14J;`bLzc3S++7cZ9yr|] -Eco@|B)za0xݱRNؔ?I-'cމ=e!`D2D؞We ou^6Y뮜Bɠ5]?lB$!5Dqi+eh:N3Mn*b[NUou!. y|29`ek|D~ =53 ,|.}?hAqOm Ad#/"řiUq^W4箴6q+ܿ$˶sbm[!N+eqȈv4nPĄ`}g鍰zk/}Ȱ4XI^dG+&/I NSdBEϩELO-OQpTY۞u}+XIVn};~؋rF #ia@k[XT +ՊKO8Az'.8ATCve\Z rS2u-)~-NCCAZEӟ&zx݉Qn ›2Py T>9Ė+һr`Z^bG"?l(v7%?Z گ yNxfmՍ(4%#_'^dho1'_f_:i~{0ݢL=䁥csc#F&'9a&{ 8c_JtU~z+x󌪶fBlIEOn/΀Dmh ˏo?HΏd-KaO//r+o;M5$C䓏<@c EӉ `nZa҄(+j DR7G2:z'}r"&MA, Z]jr&)7Uc&G몮LA\d)J0. >yBY_yz3 yKKf_Ze)0 ѝ9gY{ܴyDjvj8,f<6k=۝$g2Ip' 7M0* [A=4(uBzGϦd'Lxzt%䯪y\-p]ՎsS 78Yŧ~3{6|E?d_k]gO\;+ +<^W5x3zVLfMu^0#(GN]ЅXk;86K=R䨙7>%8ލCcA2D_9sf*Fva]#b =kE=zw|9![?-*^'K<,)6#ʽF^/$F&9ij& Vx#賒|7;aT!fjNpFBDz@~ڧ40g׸9[VM~U͢<5}]Z~Do1cr*E (y[IA4 D;23} ؏o'G~f)|=| ⬖xp+\>_Yµ/x穖_Hjyjy{l[ _]qh )D:h2" &!T41Ahx4~@mZ)SFyZ-iQW&j衰}~ŗ38y`27={x#NQ>IZ,-:k]]cg*f+Qngz.J'D7qz .fj7jQ|#?]ߚ7I*&7AB}G윰* U `D{pi H[]ACIm"oa{f?Op~Gr"pۙ|˲WP"p;ܐڲRmT/S48U͍̙]Gk'Z]FISãEqVtJH^Zz5Ӑ zt&{Yr*\7>K+$ h!-E?J/"noI e=CsaXX^¹&w)ٻ6eE@BM:" EJ! /JG'3CͦҙnOqOmżDu)JTΩQ\l;~%(YK//d3C}ԜdCDӎB0|@s:UՉJsxcK`pO +]E!wgS5jud@Qq2H/&Jۢ\ĹN3ӕs0R&\I{=R:h}8 }{/^7ć;}.긤> H8%U Պ$ %:DC=_$]/StJKMoqЄE_pb˺IuAzO^O*!QG^%#7@v3#AGhxMxEx{Ii+蕣I4& o3AlB!=]=cguC7rpYxC]@yRxpQ4V;\IϻguY Mғ>y_Qg'6v$q !'bOډޅd:gXPDŊ\K(7 Jf\B6UnOT-sGZw1cnd Vo{<7Yi"J~ĕ0;w2YvvGb9+TM-|~&~V?Tמb4?~8b.4Zyj8@}-[gЛsDYf+ѱ"JݒDEjB]h3ޚ7*;(42nPc8O&6 F ~Tr_X;f_>Rҡ=cE Y{Jvwav?~󦲄zQs/Sԝ(%_!XoS]J f Q:5tȀA1b[gSbG\T ~K*5Mb nLy,h[*.#Wnc].90 Cv4[h']o}a}6Nէ~nҗ`({e<:#6dm,N^EhS}_Х $JvDZ$>dgܧ)oz!4t7[v<63 ŀހk arLM UxQyNXj]RJa$kW7=O1ĵ_r=ro~? fo`"}!;m)Iv9ϓGz^R+T,M"7CuK4^R&]虝PZ!uϲP'8)89\"Cx"IMa/Cfݽ d^{Q&P^V:V<eh+3R7ٝ &4$|r.YtȂe ^u az@8DP2+ʖH\?A|;x| S>r۝Gsa.E 煄5jmÌzaƼn?}}(bdD:4&4O`.'RӨRӦ4-JP= \˙z}<_%ļ^x]=62 XN{|'D,QzB?Jya8P?<uS;LB;[QPĢXo3۔>Gω Z^ лQ+p+)+P#qF|)-6\pBuk +R$>=9"P D {Kg)[C~?}L$]gWWJ^^v1Ϡ;Nm}./@ H94Lc+h8ݧ5r\Xo'HMLw:/(ffEK 9m$0 CS2OGɳq~L'ʋ*;_g_6`cԸi; .ۊҙ=z3x+6!:.' 3.Ku@Z+-+ D@\IIMgo-3QLJF߀vOg={|. OT:O6〓,YHږy4f ײ?~wb,{Gވ佗$NRqdu.97p8:k>rIaJUͣ:|I/a#O NΎiSoׁK 6R6bִ׍N™FN$eJ hz|xnD&]Tdw岯NPgoQn' tꈉp%.'d"5}w_NB;K>kf#:A:Ԏrخ̔]DKO;'EGw2pt$/w)? 7un[$':Sgn.tؘAsxÙJ3έV:ŦzrQ#Q^HT<֜N'.p怍Ȏ|>M̃*? P )Wqՠ] 9DEte5qjW,v.Bp#;-9cO*(>[pxDY& k;9y;3 z7)o ys qT{U\⥙T@QC:[<T'{S>˫' Oe&QKO}m3((PVDP_ӿ1SJfwbFR鋘"Uj>CAʾnKǡA{ =&y".,".cH &WW/r15K&H\LJMj}WD .dapAc2lT[|n83:k"muq>[2Nob%A?y+nQg|3V[RIpe6҄X^)-ŦrPr+rRT'zG`OM қ{ZnEG!:fmj" T+[9nzRaYEd.# XF{s!@ld.xĒiJbfgqG -evv¾h@Eu|xx} *މ<,7+ DY~/{IU:[DqxA)UF6(f٩q= %fM+ JBt-sx];35]g 6QI;~j<&oӫסSD"@pcv>m\C2-ox| %Ѣr4n1iO_^y~\) ŀNfȉ4_,&  +:܉82 [Hz4[>~HuJu[e¶+1p&hýܙ &o$JɑB f5ofQGzm[y)i&GG؉@RJxyH3^NKcP'!\\s$LUI)TR\ZBBiW"+j"KӦ5<*Ȣ;&fh(cF>Yj+%tH^&&,8yA׈Ž"κF-wRƨ`CqPNmx6un9oI+iӿd%uܗDҙN/."hΛ**IG f;x[go=teʵK'eӕ[ ~^ڇ8Ro4j&Ksg"xƳTZՌ]bFy)B)<Ά`I*;=깜; EUO?~`)=oM^ӏ/__:AOAr+n IpQk~㦌\i79=rֹOrx j& R3hSHJ^+5Yăנ׏㜔Oqj,$p|'^7 T|R K :B\`-=98/BR^$($ /k 0,;,܇EKٗ}sf'H<8S7]MUPA!j+s چ./,{e4岡):n<,`v@5ǵPanPbBU ߸ ;yK96rm34#J)?2%w0`9-rS[ޓBP$,}F|NĿNL#<3V2tW5 7.7vR8Qh+,ptj)aQ$jetUO4` %uhx-;R\!!Cyote:XYٱd5ڨ[ -r1 l F^ķߢ^1 H$=%$9 8XT׵T\k;?3z`95+UzClw⌽T. b#i@gENZ.m4r,6 !o`i<׸fK[=y)K;GO0Q,P:'Xj0¹"PrǷD"6/#&&RX~sr6Pek3<%&(|r~?36sAO37z]:gd!!4)# Nm׉$k , p ;i(&ti&68IDC{Jgz^HM.?33irYpw/$==5\RVRM؛>^̛:\p/ yӱ+(O'jU!%b@7ex8%=)K7_̄&^ cqJ#,2v"IܣEggr~)zy+N+]P_t4[?E/]% gYؒC1Ȑ+Vxy+UKƊ}EV I9O9NVi+aUdHa(Ep ep @@ 'GƄw@7)C{=5Qh`qT@:(?DzN;~kP0ߨmn=*~ŀ"SQέonđWAkꛤHЊP7U9\pE:DcK\NV9E;11Q?ԒLbLͣdt580=$D-A{nkh1F[Q@{zu^%&%WUj!4#Hܻ*Fl!OgFtʮ0[~ɗh^~wUMmvꋂG]yq"{͏/@OR1VЃm#=!)gZQ_5%!\__\!7'؇ĉ*na*;)7)&W]GTOe+Cnǖ;W.ӌmt} ޷_$BG?էgcx1pq/:qu+4y@/Ƃ L!J%K 8Xg8nmo-̈́U)b؏q2qM5?S׻)*RIA|9 kt)`lCIe:' \'{lY֪4r.6/aIsr|I/rPrJ<avVѮ #j ^WT&JN=2` ^vL3qi};M3wֲ)8+ :Pyރ^O4ʉRYէؾ=-`W"Ub*;oFgILΔÒ;6D P<>/m?J $ď MgxgtgǷy(bhxE󕢇7Y%3-6ͼSK&5уVQʁ`̚4X3&mtN0DCo ۷Bgu{:gto)8@ DCR_{8r3AXp&xUWa$L//q3C`^ߧ H/G4 勃?$zi ς9?|R~=QN <|.H-Łx7I; ynh(~^; #\攌?0DUMHMWd/2g٠kFDx|yj$OF'U+|err-Oe͡Ndz7)5}9vt$_/MTS0#bƅJVY+' -q)nc`zzX -upe4 ,I#cwȁ y3[=}TK>aQW]O#B/uP¥,^˸ ~?}S+h.5_(͛h>is.ݱFF5!j,::Es*ZFQv{)q*uɹRb=׆lMP 2{!@Hɀ$?3؁9(77h7 y蘃2`{+aQqS)JI9b| JJjĿMOKf$t;I[ǵܲ,gz!WQK]㪏o}׺q t%x@lKǻ␉O֡iMa輪[ּi(X h &Mz3ZM/$pg20>{{d9 &Ek88l,g>U mba/@@O.Ua`_-Ծ~-)X T5Dھh=Q3:[ZV3!z@ M6_`[ \3UMu"\Uv%ULcѝU,33in8''oy, GHV;.H8qa=ԇ^UCPi9a`o' 7~߹+B2ap tp8 [ܦ!A(&E~9NDQE]?H"5@CQNڡHt`Dm 3=JJ 8L}"hA~01jF]0WG j̕]ʹ7 Qj`vJ 9>D)ʱw(ҩo `$}1 )P<uˣ+u!t^hGݯUNNrrIp"VخLwow2g-c@b:9tj)WILMJSR5,7Bx`+mU*J8n2hs{7B[*mijmvzUDa1Y2J$N{ jE P7!߆#f %f>ՁNk0~0zApsLk @pY'rI艪 ^ݽpNxiˣh{IEW5h%7 妒~__d^6 J;D^i*P7h j_ dꏳp"#ҕq rmSU L+m%r/Lws f2떜ԆN:Qp:9Muӭ3gvD8ݝ2B@$o|gr<&H)U321[׹q_l#UD q;mhLkRpFu" rG75^' yb߈3QFvwotJfδ$SGhΛ{5 iE̶؁bYT VCǍ B=$ʑ~:s8%ϟ"5.aUcwnTg^35a?2L @,T$. ^%SC䇩Kj?[;@:U 4 FѨ)O4Dӟ>*oŽܼ 5',W%d*Upk~7 >l^rIяcwm`we'O#ܩ)ԿwHćxOB'ieߔLR ^pVQ qZ@뵃/9iR ԬZK3TH]4^SLT %,{N\ѵ]I(|[*n? џ8ŕx(t }qS SJZ^N6ƙ1~ߓbOrӛPdaK0ȾlP1/-3<]3ɏ8Fmc&Mq @&Md5x{ l &2'v@JxqHEy3b3כpv׽-.g"pob`nK9iX|ts2tjyq!jt.I;.Zұ2l=b|5' E륍Dpp7 [ BV8/?ʊD;.חX"ꛍ-Vױ5DPĴTASƶ+֚J(f!M˅[93o*)tsMUOܖ]a^SMobۇ&TW2kʼne4$;G Ue0ng*_~*B"̱c"Ӓݣ E`SE:[zx~-QO[K>H;zl`OMؕ`vE̿;|.b::`"9W V2^yFr)VIĖGZ #]/3q[3NKF j8M%3Jj@́U"Y ̫NFlho8(DڐLJ өvӯSS=6,/P%9jM4IA㠍R px9.~.6iNy$A@Ue8 c&&zf~ބKMoyo7!ԩtBCq^ Ms$rWL_~"ej!Ȕ\#ݼz>2癚ر>:O ֓2sZ*Z:ˏ?Z.8Pn%!բÙ|ئo%l}`#OR^ܚ3fH_F.bSRbQRC㦑ozf|I԰%azMtN|Nh-{XTEPXr>]NE3}[,}7q"ǎ9E Htt9Ċr w_KB&ۺ,KM(kwvե/F*(lE&pMY޲̫Ҥ2zRwǽͣ>+l%q_or v %2۰I% 7 &= H(:y 1&f(GzMg`؅eYD>P( vo(9)rW5" [Webc\P8crP3+7- ]Ӂt3 eeU N> 'JoHWO0/J[0T4qhrJebP5cLXWlxmuNRFQ-hL_rTcs7 ys(xg#]y^/il=^Si50<J4jےdsQiMH ,ڗ} )u'AӴ+=9͉~5Eг F|< a}Νw+M>DфWμ3FM 3Cqa|ƹƄaV\(Q]\ɻZjr:[;_I` /.xk0GdS_"XUN>\[*5*>Eww%9/FQ1oNG:ӺQ[b~ \EqS:7bE-/RP`~Uq0U@V8SU2&\NE'b _"&ajԿj *nXj)O@6Mӛq#wrojc&|u B%>@$ T՜`Wwd#]7]A*Y VX(>h!႖Ztݩ@T|u6SW[e'.<)׷tZMCQՒxM(gZOIV=Չ;*|sY&g3|7~;-lD|~47!8 lgXb(q)ЉF 3MY.0KMCu>G8vFwù:ge$%ʷW(J$z7՞st9,= cz+r\ȡ\ŻJ\*SR-*;,r'OFq=۬ 0+iE\nm ŷN Zp#rՍ5t1z-<5ـ:ђLCNmP7{gSǿLX8Nosv* %;Mħ>[YLuQ!F%fhD8G65>O|Ə #SӠ5rmܗ98u9÷Ttx]@_HXH&4V)OjCj@Pvv0O G=Ѿz ͋[w'#ݩ:̛>̙d#Vz nIz7J1hYh4_`OkCMrMPK Ȥ?*5CԄo 伣C<:Qj̲*<89[T3 89XG!k]Hȟ$J ve 6VoZޔ

4G/|TY-KJGv~ڳ+p0MZg/PLLLMq^O~L HÛsp\;6zDN$QZ8&djZRf5if sid0^4GL|L 0n ɑB@=2sxW˨fF\ݬB{5~YT#GTZcFRh~ 9h9OWUB*MP,]T)YM33ӄ@f8VtAKk@ACCw)sxM=uLlG}pqFN@JJky_<34-7A#mbf H%V.]zL `=;(q6+$9%墬uePiQVVz1ޯJR*R9ӭIHR`H0 vAUŹ (#/(8HQWWܻA1Eqպ )~u" Yq.BZA3+͢Lq"4EPB^{Dq \dB̈q[>8~:zv& Ft듉l1ĸ~HoH@rBi6YeRo4,7mXj/4<tPfH3HքU4Ka*JWj,xed%+805==URs!;LMFdh0%Tju۵ۚW@p ':pqi<ĩteI@=0<1Y3 o:dq bi" HN!HTiލJCyj0\| >Ky˺ WTPD:O(:?u] \E Ei\(T]ׂ׆f+l!܏Y- 8i`ER l(>eT:n1Z?`[`: ހ!oo{GfzWJG*[p\XHHG" "@rGzox[\u j3ɣN# K_qz(OF뉆~ƗQpؕiBKb"Z'pŷc2x!E PIZvy3AիW0H< )UX0'F bۣYX yZ3~2U>1qf͛ˢmNnkZy{~$It7e؆@jZDwE.l76s򋳆ep`kҁv8XCe >iԱAE,|UxV &[2 nŢ'! Ap(Ȅ%  `Mo<}gI# 9xULM zEדKG½ %\ϭ3ɀO@Қ ^+.(LU;#a ^T/Z`B`q=xP:oHW3ts͟?ABYQ gG^y4{dwPW ݶeQ q+: > p lqN8$9Y_=?T4ݣa5Ȕ>ʛڠԠaҴ/پ6 ||Y3갌riL:LuoMp_.+_*sLNkJ<*n3.bBjyc/;USl"q¿=,7 (]&n35KDa6 0-VmS4*\hzitTƁ7s&L`5ТSMY$8!Tؒ_JӇ_J!yʑ!8H\HB"h PR69qq*8_)pZFJWuڅ>V`EB%%UHM+I@張NC42Sl5PGki&R8@=3wC{u󐣸4hI~7?tڙybve~QhX;d4jrB͛GJ5#q[gC,f!skh󁯩b%ZxBV#LK~]%+ &HwrܩAgbK&9YD~ћҮTOgD8ӄkJSa XG/<m1-d[,ҪDͯ},xqScp7Bvn{h+b7$ FQe%$٢}.dz!cBTŚs1Jm͋L =jJ\x grrHf1kjuZ reX;?eD3;}PZ2Wpg%4_t0ot%%otl+t$^B΄~pki 3uXgꏭOxض ^h=9UrEf+;4.uVA'SflQtw@ű~0|d"hHwJ2IJ@Nd'7O`P3iSЎ )AB<0}L9Y{beqw(pӦmte](V.ycLw:-XC ijˡB)j ]L9L|$ێKrp'u3~k0 Ax'{յܵщ)6gUw4~>deJȱC&zvES U: ^oc^#ptp˼+Yl}iJ󺜊͛ MHwHt.klb誶Y^I'_..glٴtqD8T?Mq@hr4čGBh?dh? Ҹ q)5ʸ3?ݿݿOTʙLM$%01Cf+i)0UVJ(m|^o6T?5OSz@kr{T! Թy7 FRoтp8Y㏖,+q  ]\%Şܕ"~7aL5~E: {2٢04`Z" ݿv5>dD¦iChR@]Ƈ`Y1jlfsj(@mӰ53,@|@geE|z[OpbE7;vZ*"?)eo`3ޤĕv{9 ?$ϟ\%Zo?JM|Ip<&DEkg "CaOֹyS6sNV27ɣP.ry$'Axμ=t*ngO;ރ}ɀ@I܁><(. ܱ^ZaxPa]dSf5doU4 p8Tf&;8<T3S; _MSdXȭ9oUI8VEXF̷B|EgV&ˣ:LU7pWL5ű6c_<@hzwpAb88_ 0D៟ oo&3])IAq^W-'Lr\Mǡ)l EZm>D:ϝ# 7Gt$@*ļ>&7&1(c):T1Z \j.B]rkQE qs#S9e:|42(9mSRTDt zy$nh =P05`wm`w(6JX8ySB%pܩp,kv'2ٓua}g0>{"`$| Xu)ZKC osXՋd& 6Y-4* g͙._,ɺ $N4}\eRcǹ>4ˣ!)faȻq^.yZxp'&xǛLt%>&ħXS0F*Où,iGGzbGQ{^k>|pY~ljjJ{= cR9>ykG9էeE<.6/VYby#z(B{9I޹Rd7',eGI[]y*&23% aŒj'hnQ J;Gq1D!+˕I;Wc׊2p6Z"6zcޓ P\ e]VBΔhV"6^k, ҬFg(g.r~$Rf+n7&ޒ2TȩdJL>e/e^)1!`kNM4K$/  j }=үu#O@vD$3PE6=HGc 'c4׫,kEQ{T1BNG~3B\u{$Amv8>u5Dǎxc@`itdxo=#޸'àgs[V0wc&mD^@ļXԔe%{2 DXn' WDip%^L^Jt꘡p΁ f!Ḿ.Xw ΃Hxwqj\fqI搁M*Xj{*X`o|4l 1+?[+ ^R^#Y)z5%I|}~8$wc~1 Wr F) @wb0Gg+ewSoq HdDZaO< %uXsL:rrfb,U R1 _.&u "k3GfT>῅P~@sja+hQ^.TTA qC}aEm;%SגP4K:$ﳕDr`P ۡbIq|AT,N .1!%jiEbk4%(!ir8슧^0E%g|8b/o2`0(ǖpʻ7Oҩmg.\%^'aꀼtt,+ܫD1”-fRs8@'gɬdulPax8WHZGB p׷q_S $Ǐ#ڻd& p ;jzZJI'FK奴S,50Qh,έ!` 0# ʓ⨐0ºtTA$s&/$ 5S8;ufGADd&\_|5OT|̛QVyGvJH<05"" nHwU͎FV !t@Y?͕ jp]Î;#u698'xCGb r◈ފy ҃SFf"QծoflRx83%@yh<3ͣ=?ӛ3$ջDo` *)J%$HgD.)\<4 //4&5΄20 I Ő;`ep}iA9?ٶuH͞T #OvWqr&uX$ _H݊$ܮu3楆߼ ?eՋAvp&Tx'W F }"o3!AnX7`HtI9&5$aU}PBz G,_Q^C ![t2Eyidv cvW, X/E_v  ky ]PRwЭpBq9xrlKuƧ;v.1aJ>+p& x3^Y7/[)r{3@٬q \dbR!kN39G&<^eȫh ~|"aWp3^ $>Btu|dƀr?67H0C %,(ZUI>/ 1(>w@ \(I RҐr 4KW/ECQ N~a8H &b2Rڛ'%䨠,ć_YɞiRT=PЁ?]|A=KG:x3ŧB]:afniWB%`L= ށoGB/rf4˯ۚ=}BumC䴮R1ŧNn+nɩ:y[{d;AHe 2vP/u9L=? XȠʽJS?|ޔULxfpB K_K:Bt*,)YF h` @ŃF y9|2TA8ʢHceX=V`8& gJÓ)^2[s9im3AcU3p<6C4Unj)պ qzoxK3M"9JrqAP~. ,b*HVjS=IwR7(/#'%,a Bu'ujS^in\u`'[p2ڧ Kܝri_HU ;%<^.WLjF=Uw#ՂЃ dhYrRѲmo ^?G#wwj?jS"HA;SWwE3Ao]JT݀Mw# 2S*3BS0I4KGX${V(;SgX_ڔ 0+b~1& ^(i38|!d +Dcfqw`OW~?Q x~5NAc|wW:$4Iʻ{TbVzVP -+RSbߕR LWa)>?ڋ7G'JT2-8bۏSa ~ɞNewa .tˎ H0;<#M.<ۮHpk=z'18m"/IS TU=5:s%+|h= .|L H{u^ooNؐU3#ʛ`&.,t7Gd,v$#-=V.ہ UB$D⨠ւ0ޣ:DYrĘLsde@ǁ#qE} v UL)3,kESȊ&$&>xt~LP;|/LנMX+B^8CÙޜ 2Ip*?^f%u+pӅ ΖD* U&y>f% kqa69Kml1[Ui!tڴ`#]CJGalЋ.%K4EO(pb#pS0`=hVK"q|RVri`|LNL*l}X +97?{\|Kw$?Pe *̈́mߚ%dK SGբ<&OW$E A3/\̏.%hB_f\+Ā;iHr* 䅄KWǣxWo_ .rrI$wbL6;otBW*!1a-h0TF(.xwCEnX}Q0L&e3&_|!=w٬CU6i|Fe4YDf*t9Uuh-&DF}`8i{DfT~K wHVJѫZ gSAoEYIgzҖK|ObWK9@&1c$ Ύ+4V&d3ɛV\hz86K!e.`hz\O:n9Hl9§"/OyT `?JK\uDA74Ŀ[bJ>vb<9sx/JTw!Ը T݌FY d|gR"1љВk3oJO3)Y8pPdgJՐS4Hdx@>Ɍ˪OOf9&q3V.K E?4 iu4aI4HٰjơMʳإ5Mp% n;H/j~[*j]7*5܀ۛNn.BBByyoP7>>[w^ML&=%]٥[xMϛa0^v+t)B.9|OB޻0Gw3#@+ "\*~JZtS@&گ !-@x3He =1jߝNK~^?5TؾA OL>n _dҙd&d /vSwO[X|3|h5IgYok? ;ceE [R GHh=P܆rV )VK5j c4Jp80;ql,^]l-~J$qӂW~}(}!Z?Û; OLDo9:$蠳ofx/EZDfbwO0I:3G$.׮1'!LWx@_F6rEC;F q+qǙ8CL{_T!bxG݄=3I[@Xl_㰂vd$gV{$@aA r%&̛Iԥ8NGyWD{]= 7yqIvJM,}rx $nM{B$.Px,]y)݊$d$ :AzTCEg2_^r׃sußq]N󖂔hP}U Z_~: A{"./z6xf@- n8~jIDRJGxԘo"F^/=-^ ߷PDp!W_:kZɬxSfMJ/9;[1pptxfJMO2쨺$3CcRs-j%M$p7D ;ܴbRi`ռֲRz*U]E C5h}10c+#xW6x Rg4)/_<УKbzdPs!m"Lw $ ?K{Vckk˼ޅ!adD1Y kwM%;J{ǥTs"b lհlJNe_~F?Pq# 5B*b _`.^NIJD_I{{? ^ >&_Rē/L" 閞6˄~&CaflJ+ɵTƠl$'d3tux'L5j'C\ԊȎ]u+x## % N>2KVl,sQ*s_%T=}Ň=Rd/F{,o2faw^ngqK]U$&C+Ckv?>h=qC#<13Hb"+zF\7*11g鹮֊n|-Ѻ'USMTkj '!]2H, Yqb֐"BAt5rvJ9\k@<0Tc{}IGڮM͝H͛X o2ݐ{E]+IVϷl?ĢO䦟IoBY:cBft<כ(c8RO{ܹX1'Do 7]%VW'RPrϥ_.74]Upp dZ0ZwJJԢM]/!x80,8jozɍfHO=PBgO]!LcSO%w6,1ǟ"E#Dh$cV) 9l-Uc e<:Ӯ?! pHwPÀX9}n(wx"0ȫ &QO6JMqKXIhLu,$.xJ+❕k X !LF=6P{z>ǝIMC\vs<1xGU0 xLYjg:= 4IƃxԖ]ax@6?c-y,~ϝ+tH:,+Rϊvx۸XB bJROZ 3+/qEx7Èv]~-so)zx#L-(!dbag? ANrQj2PZ^G19-+ ᛡ;MIorf/Of)ΰbÈ?@$UeCEW LWfI,4PT_ODi"/mbDO<̰KKS)ZZ=%ƚω@9鏇C>Hoz3I;J ~nO<1) d?i3,Iޤ7y a,EG:i\ 4BRZD;_RG*,s8F'WdY4gaJ5 UxKبMy;$!IJZuu2Q(eBmԻɽ;5޴_Ayq¼?ucrZ7{ kZC%75\ zSg 4xDRJH/S&+n7bsD l&/K8,Z)@5t6hD1UN4D:]If f4.bvY>W.0t\F܉^#sф/>ię?1X5NF|@¢7ٮa9]֞VaA:i`x֨TVXB[]!RCi7¨h] FYy"9@ Y"=5^j:T/aCz^{(MNy џzon8 y[DECJUM`;<:{\(!K<;2b2_tuqߡJu%6릍6s4n8g6DקVg""hE2f/r!Si6@+9~8螤l$<ГLJ{>K=&`dt̟t&2ț^./0\א$B&wd"w(r5F7gTN 2VS@ua-9|G+ -\f;<m *a>r~O#Ou>jrx7P€{f SR$w3ËxYV6ʼӖ;'(Iĝ@ Z? ov*16A@yl"4U0 y˧ZbͺXzj_Ř' /+Oϐz*-E@~wiV?9xx{vkF79kWfI@ƛ00w ׇ2$gzͽU){N]ք_cܥ?7[u-䶫klHőNqc2X \:-cN")#ôi\8wg [4>`DdNФt&V>po3&֟MM<$/Z(ZG{ٜ&r|O=9~?8qN%Ԡ85}kH`TH Cf\\ng=V`>+*$@x-TFYL$otW-K}' k)JGl҉%JSu<0eMp:<_7@0Ab&WڈCWu 5Uц7x Y 2V_$ς').y y@ .`G>&o1;A/kz"OɧK#0j?\e.+ܑ[t`=ਏw2s[@H H\oҦĶ gHǮ3\FХhD>\[-0!^LdeغdL9PBج"``ٗhCҩaRw@FxLO!?bi-sA U h:L19VXKG(e]m!D$:?tݤw\4/P tO~D v8n+G>AΘΤǟa%iMB=:'}j8ҢWAVj<#.f"5X-hCL/S! 5;tBis9 rAco%vR Ed 8D*J샃V;J=(6da/N $0j]7 xٞci30 81b\ɧF8KS 'OE41 AD[^J o%t:f-6&묧>+ĺ\?zBb *>J:A@wƃ B(YI;d OtlCQ||{fchƼv+y=ރ8)ULJv:~- %)a ?C]C=X;VuhࡪR, OȐxA;5yBI{gke'tpd8$].b̲Q^+%ă셋 |}|wAW_^*aTԕ}J2lh$08 8^6?1套LV.^ E|pIp$+0r`8 b&IRI)z*c^ySUDQor$%nޜ@Y^ǿ1h O$+ zSYRf% q*'g͏Y!ZeŦE=s"+j{nӝpel*zA} (SAzcf_@"DZ|; wRI"wֻ4&Itfd in=SuxO`Dio}4+k'}Sn/(c744N"ͭ!Z`cj2R -:Žܪ1{AO)4\T鷾?d2@;Ar!0$hYqI}c@dQ$՛ԁ Dwߊ/2m=hTugn3ԬRjT :!3e>׮q[8v:^ۛ>|ō@zCrxFrx Ŷ]-|-ڄo|? g")H$9ݗl_ҐY=BgWvFO'OǞZaP'KVY3; ?> эo" Z">śR}7!Ie;:J AҬ/jhd+0L2bmrS{Stδ#gB>e})U S5OTv__ܼ/&ЇS 5&|?dgOvgJ2)ߍ _%WǝJg#Eדjwө_0M *gEWF~ KH:gnkO+(]=I՘oL^dn업惏H2Ϟvoļq7E6b61Ag*t B<g(RK X@^SCJ> fuhJ3,-g!U)>QJP"GďseAij$&&Mѫ Ɔ wIT[ʺ5I-bҤ4/|B6|kΥpk\VBT9kڟ/f:HE}Z0:A i%*c׉>o'b UB Ar/tpQ/P:Q$OX9iݥ8N(0 q!2/LUÝ@NW:PFbwq}x}7?t@ʖA*,{Da4-1rl[WN])C}!#4@c/ ,bX?O,9G'ԻѨPFxHv Ө&nJ:@RQStx[xt |H "0=hRkT=Ē?Aj}7%D;1rD{K| ] ɵ8vDz, >pόO8!%]ݯ9;.FJq'w+N`髚()uIXm$ wr gJ#\786>VOOaEuvok{ zʆ ? 0|U/?5ć( B$`iVo·dǵ?YBp٥6X,Pc!4PB$\qF)F]%)YX"Cꓖ'e]l+up`xo㥏/gUCS (Q߁D~PbLc#E"8D~(.?r~ڧgO 0!9 pD<&p"D o,:Vq\PI'1<ú ׋[1k򺴀'm>Oj|i[z>|kJ!`Pݵ$}Hm~FfzG|K2Vn$0!|0fv!FmCu/&(K*ܮp_>E_snL:gǪjDJՓ$tt੅!*! QфI5t& u5IE춃~Q%9s#S z KWɛsaK&q'rtSTsJ>Rߕr\_G]6}]E}6~.xcvJ-dZJS@fVH0GMKL`ExV=ᩐ\Z_+ y޺wY!|5܉7[X>AY(d*~(9Du$+I6ҽq\ά$#%:4 B*-.Itzr])ܜIxک 탴""|zV&sFIzl/A|ۆo {,05%إp9^k89Qrwu,T+uQjALxX ܀[>{"h01jB5%mB NJ2^4Kۛ3}G燃KGG<y/!o{dnBx͛7r-"YH3oZPGπ,Ǯ]GjXg8!T"3WCٳSޣxGO{DvꆘUroWH SuoɵLk}+mp oo *`JKIMJL.V e% yi.uNG 9&bpn𷣴ocYWV=o۝o򌱊ԇy3׀G; +jEWON5 jqXt;/\˗>ܫm xo}juz.vn*0|O3)pjnP>d9Bx?{9f9ބ)HI3mU=HNijX#%w)^ 'j7n8萺Zk(UOaꕮi&Wx ZkdBNޛ3QoRu[xBW͗魞p7;A#ڡ0 ;?xKbristol-0.60.11/bitmaps/textures/wood4.xpm.gz0000755000175000017500000000202611233572001015776 00000000000000fHwood4.xpmmV$5 =3_QsQ-3!]-7ǕV$8 X $ĿcgG+Uy΋U_}_]_??_\lqzi~{9Mt-O}8Jt?sz`w1-6`Oooۣ{wuNd"*5Zk{ymz4_Qqm| S`.WL0,ǟYMD;{0) /:ao#8Z46/V"i2IЇhLmXuz#aClm :梿,W\8Pa_GxȕiǙƥQvF8F%I!ac  8wA;A/UI076L9]!ChU 0}0F| BRq[g%Ý+m3JMoL*RPRGkU {ݻ|yj EJGgD\S0{z12a'yV~"5K`Fc[Bg1_Cʮuc17m2l zɅ/j) EbV/T{iɵXR(QqIOC4.F >`RKA%TR0ܳJZ.#8YJlV uGME~2U* 4iO9cҬbV[qQ<1QP#htQ&ZR,QFjIFeza]br\Wɶ%BJ{Mor<cqizmfԳASߞGOV^ݽԞvi/5G_y:i%m7O#{q޿W{Wu|w=:ސK{o;B 瑧 ;Bs{:{Ӊӹ=JJD x?=wi_pGKh59#  #dboQ0= _ݻjpeݒ7wq&J:uF=woQoxgW4qD{;`[Lhon0uq%FGqɞ&zj{Wve&{;tu=iO{O?;K}{/{n_v);:Fi{P,Z֪j,zeQ=f *{qGLX4G^}1n5l:nֺ^}=ҏ5[%3'`\Y-V؈nTaq^%na5b}g|[RLYyU_3kSÇj5REAeUJM4Z<,LFuc?9&IRSb|[҆-E>K&㥗ǭ[i5Cfn~x~jp~^؟ M 4i~z?~lOv[ }oZݾ<=3Oicgzxfej~>>Ƕ}Dn4(ݽ,C}A5l4Y Y2dtֻdX.D}+b-ynh ~w6OX/Ʊg٤2ꯋL}P=<?~ly׃A5=}iy_D@4e; ztZ>B'YߢW>mEmҸ:fn'th&aZw !ez$ֳY0$x2)U7x/D}"Ͼ!ZÃzT{Ϩàai5A?># 4 O yAQT'iEY jmȦyѯb"5b,vu^DCfkZ.[+ם!L Q`ynOrEyin>V0 . 2"M%tpc{0Ե $OC}"Ej^mÇ@Z3P/3$C PA슙w48 ҃VD+Q ݴ_j:|2K[cÌ[VK ϓVEl?=>d7?QPQ+ Ӻa:MStVf$ ,<$L|Pmo6/? 2~?/?x~F7}YTuN jF&U$XCm67v^lfKeߒ6Ћ$+f>KOHHZW<)T:48gGU{:u6_D5[JK<,qq_DLpT$Ž".E1Ka.0݉"e|~Dh~ 6,M`"ƢV$fX;Ea>d A c'>>ƾ(P͇CdMvӻ僁p<#=Xe}vRahUWQtWGa8dz ͥ0Db2t- 6Sv>Hk&A_,%սT*XUDI2KDOZ~҂[Y} 7i>|~qM}i,Bn !@4RZb&'w=+_5aK3\|7M[bRbT$y2KB1|I*6QmXd>DjJSGtMN]L$kVLM ʼx8| dzw4 dbZsD2-áPvS3Q`bp3( YzE={ ,g"(R9$wAHf.6^oMx+.aE35 y\= o&̋@P(-<θd7M4V{j/-:/ٖ9lH-V8 ?G  |0q8N ^J{|3H~leh4n CXX,-g 1ؿ R<cy&]Ao2o菠ذEm-I- %y2cj/M'ò}$qu5v*$ kvC)ЪpL' {o!.;J:t2w/d~[޹ a1u(eIy^- R&0* t7㐲@P$h- tWB:`kJKn|?ғIP.<<˸r'$ y.**,IuXBN$ $U-s<]Q'Yc v esKHԤR nm38)0)MNL'G%i`]iSا. D(蚯åi U?q$!!7`"~8:rt<s18H"^[ayH BsFGA8c6Ay)kUfc~H ʖʀdR A'2{/ *R^.uK~KB 7D4). Bʺ[TlCU0 Eh",Pwl,6 nMÔ(~</GGXL.&o+,'`Z^S4Kg$+Nag˺Qpá!NE}z -e0[Zbq` )-H‡擎Fda*Y1>8<~Gl>PC_qk$ ^NkA}_"-,  ?V \C9/5~*AC e'HARTX$ %ztW 4!rUA-W,6~x*>IC$%inU3/:ߨs-Ѡ!'N=oN< `O` LӆU0J4H'0MF-a1^o.2cf-Is6<h0EEyO/w2#ےRk/}]q[h,H- ! FX"u\4El[MvAF‰f~ mrkA MG_jCTJd HUD n0}8}bYޢE=s~ #9GjupPVO=~ `jenXLpEG^:n#viɍN!%"; Lb[tb:|4ma՛L]ya " 2ᵕ&|ѱG]p|Kq\Jk0qE|vOZ*ZZH#cx &fg/IMSŦۭww+x/9,#n)'X2 z Dtۃ*z33bpXQq=s0k˜Ģ+y>yzUp sv9t}I.ЭX<1T-bKMF'9A+7 VRz3iq/px mGCaj8 =IC]A깱IjșoyuDOeD 6|}~aT >pc sht>_HZAJWQoӓ:GDI"yYLEһtOoGDXHP5=h0.q"&{$lka."HQ.p(hȆ5 $k46 ^r4zhK'DH18u/2Sdih`wAt\vgçvu[|a&cЯȊ > [, 28 @0,Vuo|~~~:0ΣΥM3=buHq'+q_Fp0,7 L(fL$ !m X:Y`Z$r5q)Q/ F ᔬNDM] p{0{窵X8R<*ؑyXbB>{z 8?$?,g^㳳B.nӄF²R̂Y%r-*psY6"?t@A2Z^+D %l򄞬6} ᡺oĖdbhd Zuy35GRR|q3Cv8=i¯_ "/X ӌn?bsXR!8+dh$*P\AZce vO J>WU@o B4|X~? -Xh{h9 CHid)Ssz~$FOTZow aRm|#"T,$/ yl!'Yȅ|&7G4`{palxɢj70Di~׍ r7g"ђH&r<_FFR޻Qd]/e 0X%Io4?V4JI/BC#` ꔠVJnIl9_܁%cX,B˺O@7-L tRB%.%AmL$\r0$ LPA1噰z;YyĆ9@ȑEj.Q0Wǽra^Dz ԀCN#dՑ)CM 2e!EXTh=AeML,Bn̵ lmT3|]fL_A)$'Ib*(/S[tA X~M:2t'qWY6:Ųu6io#YaZ|O^ӗt~Oc1aH/'- ȃOVF(*h9oLȇ :i3R?A0A40>K^c ?2hr/VͣJƨKKQw &5!"&pL'l/) VdtP{ {K:6oMtM-q?h1^ɥD=4uv{ˍ2ߥٮ!p B6#hG b9J@&j"d/AV`)eQg$@A5fBr4I3>mbYFLd[,0,hF$(V7̥;6. :^@L&R|3&d Arm1!:s\g[e5x~"%"IA)j-Z-pRVںz a vDArf#,ܶ@lTr44Zx4{bU< S Cԭ5S% UP`Q".bACxd:_>%8Չi.Ky>.t({Ͱz5S 3ѲNlo`4bP~]|?,|sg͙0FxzF ; 9B?*j"{Mh@yo(i0}FzM2F)V Myi pV(mXU*UAMC8m6#z F=jnJiəQYD%~s4V Oh@$i@ʛlT:;) U۵Qۊy* OZN1pmhá,s[:l- u/' aqÙ,9T.(i:ͺHBXp8pzgfĩeJ#{ " #Hb>լ}EB` 14lx F^d?懩;<,+4I?Q&lWBRsf*(DAfk! 0Ud9Jfe=Kq&keww4$ ,"_#MDl7|V48^O2|:mJҺofO|~ŕTy+ t)3|O.Wh@h@,_}y84&_LagPp&iI@]0aCog~߿h/J %DG )WR{j}BAWNrB NWIpeD$"'6X.#եLIrVb# (QݖEéKL:TЏ%ҏh9ah(O_%Uw'˱Gb3$12 mʄ\}J Շ<ڪOfyx CӯcA9/E=< f.vJC6NgG*l~R"@YH л&@Ry(c⾬eVV2r𐟬*lj_ʑ«6 R:.EǾŊ~7Ⱦ "V~M~A4%fOU?Zaؗ:&~iSԨy3i,#P%2C)$q%f>(h `w<,\``Z56) "dq0[5s O Ѡ!uuGy>vAҩK^aܓ8Y%9HԐ7,9%? e8,"QyG$A֮bs^Y f,]G3`.{{8|P#F]9XX$`@EXؠ J~V໌i_;h0a@x c7x#~R^hj$WAP$2RFᰝь洤D0̵a4av*k\Ÿ 4H @ĭ~LeJf_vcܪԪÁP< xTSA/مqAS$ 6#oz*!2E^-&-j@XKrO^be\YXC6bp<&/Y.iz M ~<$p,0pՃX<,P{>K@ fP1C$1cɏ(,MBG$GeЊ_N)Q1aАGT+3Ǽڔ$tݲ.M5{_h?,N>UɏFoђ&᫉?tuՐPm0x`Ч+OKTL14( PJpi{82&e֨`ϵ5*z|$*>P0YfBNC:s*7F~XoV):a~s۩"u՚:IR"C]d:>84FYa@=XUur"Xc(}!^b DG/aHE2z)bAi}Vt>>>oFFoH!NgZJZiZ;lQhq)ݷ LC0PB.C?<B!4* iPC4]C.IY_m(Cʬ957jRtNiwIgSC4{]/<[3 N5-#g=h tՇR`4 nGR=>K Se[K{7tOw*8gA_4ܒ !uO"D(J?*`}?\@@8 % P[1iڷs>֓+{T % >| *vxH3 XIؖ>>qx]_g=dI1LK53ӈPK*LeeV:gTp0pQ5lW}1L.>}D-Fx~a0}6m34LSB BbJإT}j˲ I/[^hٿCu4(*O@;~&ֶYwݏ~ +?[| "|?%]Z=c?0Z-UdgWdҖD#H7F'}TS5MPpZ@ yd&򸡟S{' S/W{il6:MKDөA<0vk{Vt`y%~v40"#LQ8 HeX.󫡁@l&QJsa/ (U,`kٿ'bb@gO1idyu$̥S{uSl^]*X7l4:zɩSnh:OiFq}m J?SyryS@RY=5~C:aHVz o~Ga= SŸAźX\/PJ5*eO~~ Vi-f%"TP'D:^J\EI/nnEc:C@JSWd4 ԤQخA+:l.QԢ,,eBH:' |WKtLn} RM"wGb ,nu4IZ O_|_UV2"x,K1ցJyH@J Ѡ_sS S .(Th0=>N$tיp˿Bís0%:pH 5>YK hCJJ*}7ڭFbpp{ؙFafOoV^*ywn"/e}0  aM- )r0p6-`댷ƿ*8NB6Cjvd`Tl,DUYB^U3$9t2 m% Ɂr7a 6i[d80@~W^ΦFvtp|ExMpD < e8;}80yX%IXMѢl_"3 y3Otϐq:~s͈P^cyrIP@PRz59n /TvŽĝvSry:Ʌr)6XRbooE{^gs(bܮ H؝V`!4a՗Q]y~4vy}h@ǿ^ z.0ဘZuPun55!͒}V#  `3$#q i5 1/Fv7=`V[$f 1[R-Iқ FUq0UVc<>Z;BtdIDOg%8#SKh< ESѫ͕Љ|i #?նl#e!a(ua\ʫ"gcAM&.@|֩]XR>&S +p37IfŴɗi2lA[ͳqX%fi[`484׿;s ,[&ZlP\骙 pVFyqBsM^;#zA^CF4;OYUW p?h*=W*$"vE Ն9QFa,ָ 0.wfp ?&ij&&9(ؾ`G7Lgs,w09iѤ8 X?*p[\m(xZ%/Ox: %bCNŨı15h/k$IjU>p|CCS3nA&8>7x' G]vnHR/1f\AC 7i;B<)C&Ԇ6 >$h"6ɇ<Ke1QP~/5nILC1 2?@"1gM>VM*R,=d 8]Kn܈jM[ HecJ \?'@Ct#UͨS/0Ƨ>Kip.mb°XN1a Xď\ eO G<ݖYUc3tmܢTU}8R m ]L?N19<|`6WIEbC"p0$.yL}j,;l_@>ч0l=s; f3GPSQ&?Zp|cĹCKA,xkmHռ)_\K>3I4 U^D1(Ey|Vr2exȲA% t=hKcQK& Of1tʙ YrOos|o7o5$n8Mw6ŝyb4ZVM+YؾH>9.9-5Cn2K\ش[zdbR.*秸"3ge "8j OKI6vvI副<3hDd `bI"b/$+n9¸L#<}5h`4ZMKVJo'S.wh@p=|ip5s $8qC6=q ]4BA. :M AR!V5L鼔TЍl4<[l EO ,.SLb}0@NMt*HOQ떃Ŭ*RYb(fR$4ȩܚ0ܔ tn)[:zT-70x0 !-6n 0cVw  hYdVO_<.ض,d{vӔdZmO.*D<a=A ޸.OQO(Va+iz0ٲB6Ņ,ŒBǻގYeoYyB>cbQ* ',..n 9?9JC{)\H!eP=>ZЂqV=>9f,T)آá#Ϙ{hɚ"w S|ܖ28`X3/X:ٲˢ p|U<֭1mp[BBC6c%w wcRK*PM>7 B⾫;2xR6yGw%6 TqV*'JQ,80L ʶe{İ&>,aU% AXUNLUTYcGبc4܅vŽMT8&]-c}( qPxazm12cB~*4ښ`S1}* M\:]@~%,ui~Ag5{f:4OHپ2nL2 ifQ,  :n^% ;M+ &N麣f3)4ɴ `VbWO["C"۳Q#"6o-5l~ç3ؚ bXYUkل7kmW]%A$,a.Ta #hwF~ eN†5,dUOLS|膾4b [ d"iꔆUG2<"[ӁA͕bV^pY&WoV Ea;dz eG_%Ft˽Xw Lϖ܁y}P8xfACtqG۷qi8QֵP_T'a(fGkyZ+ "=Xu6^.C^s. " q81 ` |BÝ^UTڕOJ Y%FWW`,o!V?awά~NշרcY% X_cqI;k #eFS0߃X]u Ȓ(+le8!DsLJCk@bY?4p-y0^0sZUO -{_hdˣ^鿸:ۘ85zxJb[Ջl%"䶨fkj; !.UfFTf6R{}&^޳N)lD^LmlhV>%"oOaJNEZBAݗfeAdM(Wx&4V.NHM1!0jP#ϭ`$Z(| Y0 8dI@_Q{B.NBit:W;vPBE nNR-{( vf+qi e#ےƌ)-I0K>|J:\V3W>#834be&ZZx{,Um Hl0P誤؀)RٹI lY~ahǦ`0)*Ou6nc) _%`;2)LI% Lejm%~Ȋ(җ/P#Mfy4{cj2+|5]VMtDaJn6gٱސVJ邍P$Qܲed|0 7ZI>AA&O_"ClY[i<&PI:&$t*m˃ KMJ69u\tLV c"\ozY1&rǁM(R&:\+E%ۈ $ׄ=a>xd;s! (O{^4XmGĝ LX.H[+}nc`~SNľlH8bd(hs8Ae]|3|n z~GkM:M7&mÜ^Za2|7LAb9zV1a>Nu\n$v1th9Pm)mxm>X9nM }}&NXT=7+0c+x wjw I1ZrMER^0F;kBlaPNfA1 zM񑝨><ڤj^ f0 4@%G 5qFgBQVK-B=++:A:@I "^ p0AvǞL̍. ,ahJj2}XͰQ>2̂5"HEKfTfKvǣįӛ>4 {Ewu_i`KgJUu_h_6&l$el3d4N)no PFRU)[W/90çǡꌃ{sQ}:}q٭\zWTDž s7 dy1jhXǎ/=cm8LFHjqRWwZXӧX&Y 5&$jVG\$q.YE%d/4*Qb[\S<]Kqeɓժ~3o$`_/#lŧhO[X4SpkPeseJ]1G1蜌4O60qSFZb|cm1`Dp?4p EyMO[n`k{`={ER1EdyM' /lH{DŽu n8r)ӃZu6}wJi} q`|>ldKo 6og(` ȶYV7 -l| ԎY^~9m._nʟ ~km- N\G6e!ӊ! `2&4?TIaM9NgdLG7 kA)68AD _VIvoH N<1Km77 ~ c&n0n[hg04z-8ֺAO1.!̶WRj&9 kR%Vfe"$Р2FCZ!>|vM70P7Ȼ9\Oe:mh@ ْ0r㖲 ۍ]tЋ[i,~_͖H~ H{ԪXJ[j1vzM ֙UlHlZ>*TYZ5KV@$7͒JQlEycV3H}5NK$h1V_զ,#(14Zsg8Hz b%[`0NŲ2o2UZC>GukErV9 рfUEET$Xf9:Q@1.э\㈬#Sv W~Heш{A&UjƯo>%0 "YW yӰ<_(!`"m]I?JԐiu?dBEW[&N=f{t܍dH*/=>>>NMҮ7+q| $Яr>S|]XiU,BK~KR/i7Zڴ:&6Ӌr_F"Q,Z<,JIW2J'[}kf?3bO4(XQȞwc]$rƓBʱ@q 6K:?vR94rN%Ij,d, ~W&̛>'^სq|{(wVQH:e2$"⧩mQTP8 6Yeu1#|*߂B„C?<]yʉ%DA`GD`,0Yl=>t#1 NR# UzkACYyq4|Ѡ$e[4;!/O\4e6+M%"brPL:ccDUdUǵt"kM`MW'q?+v[0p&z,mx.  B/9ׇ3fnMY 뙽^fP3"CLu?25 сڃ:V1aA2{M(_?ӠD Nl-Y ۡ.ӦF-Jrf%{Qd_(k:$Xf؝ h < 9{:sϗc9GB,tӁ5pb-nT;.x( >ou"-elHeɄIvg1'ڳIfu 1GCzm nY0ðNj!X[&r;g?EI. $רB(DZSܖ:v 0LgQA HX<jE6ibD~.izHϤsD~!HD4]֝^iz#ؽGB$Qq3|=Q#jtdz#EO۹$B8WEoh@⦳ZFŝ Y2K |n(H;|kQx9wΗKO@:uym0jx<5n@l#jx%*[%RN_jKLn- g[f:W4M9l)06d%3QY3A%6a0y{PzfWvo2hDQI0j:3{HP` $ 1@b :]!U`в1BX,$ĺd]!a:ԮgHĩ PoH9Nfr!y~)i@ Epl {܎_Nͅ˧Q49I@bgpIoV,)HFرdcAI#R[D}2րMtFćFZ-:XZ–}im銨[a)2,ݞXC)d//.O8ÕFe9ۓ,Nc 4Ihq"'u!_?K+߭ڐZW@];$VN``GYx0>! ǝ¢ߎ`ei7 Wc{ҽNn߰&?ԛ|MCiN"A+v:,d5`kȌZ)ﺭBf2V"~290l0xUvy#F4ʁ{A=ѱs wO#kb`Ѡqei[$wI5+n^u`Wqzd>1/W ֻXrLDzF_*| mpzə/ YN#'ZIzܑ6x m[҂`壳*7 װe+_`Л HT||"xD3 fvFU?Pmƾ=?HPs~{ >3i0i^oMƖ酮]\?aj?VBӊcݭ*fƩ!Ŀ>u8ò;/2_+CH|h?XR`89Y whв'1C&bge2b[%oHV\qm-hp¾p|y%&n~<nstba峌?Zu@K$J% I&\Lh[ ^Dz,AXn 3 >H o BPhoR<6j-gja]Nt{؏md6%SnFI Sٓ=ž&\Dɽ% a&)AN(RJYɆ0{%9{'w/i!~8y/\a-6ˋa֕:@-Qon [}|rxMʚ_DYh!p9fC-1rh z/"cu2I2|;v\Q+ cA.FFkE?Q- bg9G;9[dL *,ٽl@KZKgX]2o{ >y5jEh 0dkf[>) ۚ-P>@q1rv V=K+<4YmP#yW3`%ShHȁ|e627Aе{tpt ~֗PTQ-kDˏU[e06"&fX 2Р'Y pΫ9{M`=ҡ ܰ>|Y$Z>#$,A/>a$7ج 瀝p90d 2~Y?c,mC*k-WJ;4,&t40qHt&9)K`w9/7q % 3-Ҏh \zeM'? yYŸCQXC<)Z͋ 5w+Y h00Nd˩n(Xֵl kh(q2˚pj `gt#d)QA,IdF:dx(FKReTধ 4  .M%BE(֓.$ ̸Rbuoc4Я5Gu,!Zjm3FXQbئh M-8%z#%Qo$L t %YH/ dQJXMͧT'kbg2$AFb>Zo`AZ[]Β,Rh*l4z5L@/~8ed2BCQwlA|ޜCIɓ6rn_b.|(M)~t]ژ""+|Z¦XZ$ %DHA-sdXqҔ& L04%豭3ap`7z4v =@)!9.1D:T. \:/!ˈLBmd݊?q{h>'46!;‹ XmRcy  *ZRbGHY:d;uOk\.ZWzd}ݻg=}="# {o-  ;J+ eA+\Z( \ lO v? Ii M, ;5Tw!ZDA KL-2dZ}1g+bCvф"lƕ*;b7 RBC٘=nzuMF5a_[[kYuɧw/ɴHZmr_osU1hlT\ąE iʛIea'J>i18<7ZH!4\UqrK!ݾX!PLQ˫NV]86yM( jlTbeExSR <07"akij,XFaC% B?d0>$ҎHX1LD6!rGr D"}1"fLށ+I3$H_.c#$W fi&RlTP<ּ`W&@(ZsLj"JŮU1˨ZY,lSjm)o\o| ,Kh2'Kԋ/,_˪ogjd.S/M<􂛍[#~AZiy,ԁr]@C w V'DF`\@Ƿ1l ڀyGy+=6:5շCe*y٨Oj T5 MZהmz4uYKf4tDZ(Hcv߄T~>Mvu?|M-$w7GdK.=fXD@"F(k2 SB.~` : Vt A(mM0M ?%!ƙuӈu"Jq-/o0` /AϬ 18ݵ~ 4H׋,Sd )lCk:X]WJ?(*6tCg99WhB_aRjё֭Jߐᕁu݇ T+}y:zB@w"7?$r& .YtlUֽ`EmXµiMnE@IJ4IRvv i=$!^\[)[N'.v,m4}r3ӹI 0kA 4H^)$~"Kc4j/_?ЩSFx:fp($Mx re '%q+G3wAD7apкZ(1LؘƞI1 TfJ^B htY0쇪d| R.ʨp]a"Gdei^}Y'LC k'bh< y:aG_ i3h&61JĥaCV2쉞I\,)/ 2-d@ٍ9pScP>I*WQ]둭b!@Nk&hrH*5Vu_]48GNjk%Н;872[j<$W!SaZ>QRWʙXu]@:{κsړyLfC  I+рqG>i|Z"G?R Ȣ ץ5gRytd*U]!Y:pbhPDB>e}Ҧxfr&f% UH:fH.ުu\CnY~5d4  WV/ibL 1ww.HA?IP,)2'-nno[ky[JP\ߎCx $wGQyr rQTeN@׻t]AO+&{K ojDakc9M8׈xʪBO/mZ?>kY%Z4{;%(Łf+`$'f.vu$p֛VI<! S)afߘ@x \fǷկR\.ɭHVaq C:,@#F?wr_Eo&? (?YLcha@mTPx{":htbOYhެֲ+^y₏a "+=&}˛ٰHq>1%E2 #[U_fl?X.D髙Z/&F" ΖOHȪO4"JȌh`vw cZֽ(}9i/)Zzq}z[S%nt^ĔMExWM u( 33kMږ)ST"LwYR9!i2F7Y(]%A<&6Z?ocfY .A@"Bt'فMmv*FvwrLY}'3FN! M6o,pD< Lqd$(rmҽP1)J=!$ҋZ2,`l뉗R+wO(}PQ.!aȅqT4t8Ts/@ΖiJ ?ڍkzh+곉6N䢯T2ICJ&SaXȆdEtqm?ꭦXW閈 fG@(gr -^R :D+]dxKm< {dd1 }& G!?OU1ρKQPdr|Gflecư$+U٘MmS1Z} \,>hՔ+ 03' gӐKhfr ~ ?>N\ŷG) =ڻX+˸gQjn43#0<ԠpƚaTY0LIV|. $U 7r&*ZQܜJiR Ae٭<Q+ϫhTgل5BtݺI/e u4=(*=H;m S)tWHeSuxh+ς1sg$,Ն=iJ8d9:)^mVb>K+Hb0Oa%uB8wfvʪGsSjPaGMR%6*V䞼 +ygh0ΠНN>>q9gҪW+rq'"d@i񴖈nݓeI0*"-0hYMOO/bBpըCԝz0ٸr΄y"\,^z~*뫿;rFaIa);Ԣܒ˰,eW'ʰE4ECØ)~Y(CQ~F# 4|9]pBpg,  hTX'^ˏ>#"2>耫ngAϺ{ t@e7x3.@e.k* ^9jz+3TMln7K!-2bYLF^ḡEi4Ô )!$ +ӡ\xQFy2*hϤh^:u)^ۘ\G ]T͂W"Lpl9-/W;.hPw{(lT3FF?్7|Sjl_MM&G:5n]\0V`zMq"AĜD}X⶚S>ÂV*kE kYӣ*Q٠XQOH "mj lKINcFQK9zql$[)&<}HK{&A>JP7fnuHXNHK ۋG0+"_ϝQNt7hY͝X5ʉV[$57jH $/U B՝L*c 1*_!e8Q+ְ>"2#طf=p#|&!+G%28X;[|˒I $2Zn(<9]hn]\}fJ(F'XNI&kӍӁV+#?m-Pqt97ARAc4WyBn?ͧ.Rv7rýM`"Z D{d9G |YOŴN_R>\*OyD!wD1`e;*Ղ~e:kRZoU%̋FOk(NL=uK"=@P/Y*dIt)vM|Gxl0j5^) ݓm> 3s=kц;\c/s)+h"=T\kY >M9~K2dĨ U6[٢T,Nٛ*+bRhb G*OlA\fqgغ'F 3fŤ[Lqd>līOn.1Y(dW *gaV<ؼãr?=RA&60=s f"iwz^wg#訬7Jp Gil@Z[l‰h06d$r>qKZ SOX4p=L#Q`5 M3k# .ZϖN\hC\cc Hщg^Q4$!#Y;M_&9 ,z )#r~v/'2SnU 2-J@tl+ `iH3ԘPf>nkh fd[@Qr'3k=4[He0g9[ 6Ԍ^"V#n䱾GhzvZ; 1;0CmXw80f5\-Pnbd-7IfCAVB4\YwI#!1ɘT8X΂6XYY^+ @;p[b $]e-ugWnxμ!;,JךBzDnd.DbIW? q_ gیEn},4ZTU犨|zx%%cP ŘG龘Ҟ>?)^iՈmKQ.q8w\1,厾'gZGzUh0wY9u gZˬY Y6mk |q&تjTTW*:ppiF,8d(}g tQ&ivBNe_V\!Zo2gB>mOY/$P`]^=;Q&V4@̗LR<[?Q\ab258*qr8xl9v % ,K\{E5+:RgbĜBIa=g94Lټ{(^0 5ޑ>yEi6Ld/jov"d" &V+_,lփG~ȚRЀ{3vfzȓ]l{|!hu;qŽaVZt}^ݯϵЁ5U(8%>,sd z]`>arwkf/1_F6Y,B $.+ӴrjSlT&VYaS)cª!6ʂ2hލ pľyw,XП`mFC{y?}uF -V*6FgmDV4]ץ#!%J97H0dYȩa lVG<`!bUa76S2_NBn**|uE}V'ԇL.e j'uQiC&epkƠ 1Ӽ.& eJVӱN{. ElN$zfzGT{ #sV^F- X*|0S?9=K& k SO0K;w0 Z2&󗜄o>cNlJF0~k0rL*6uCBD/1Σ316Sf@R}f`5ZU),#뱷5}󞗋hB[Dz"A fRG/ J9^n2drrNne]Ϟe,7JpdCTq+dA+ -~YQȶF% \M;< Y %;L]čU(9;h9*&?HaM6|-Ed9oo]n0 IVa-jGXEYf7%:zH uJo>ůC}o5g0bEWāܝ!f"%u6&L%*IBAqIK9Sb{z]mz%6ʳ[*ѷ&&T Fɽӽ旧~ZpVX?LW@|Ѳ5Wtћ藣T4ӈksVqG@*i,"hi5[s';bԱpD4fXEyE@=2 Q!t->nAXA԰08ޒHOJ/ I-OV|qp$(ϗ7; ^Z) \6ь6ug- Q v$Bx^6t4ӉS\N;HNSv$^ !]լ4,۶;zNGXlC!C& qg<+Z]W˙O{#7ܩH=Td Db"~#gW )x˙RGIk)YcGJ[9u+ h^΍ Rd26}Z_$zVd9eɈiis?˱Q rm7eQ: ArY>::&#m/va4ǓS ACXFӌ8vßnTa8;CzvQ5#T>{S("ɜ1s=kMޛeN]!Yߧԉ8ِ~:nCq;C8Q,ĵT[><%qt4h[B͞,֦Nd} \e㚇ژEVEa4  dA :$ʾ.+h\9n2a*ؚݑoмX}B꿳ch؉irFI&u3Q-Ɍ &mzGKlk1{լ7&>Hsju:vM1sx[_8E\kDƹGT%Bs.Md"PcN-\/)&?nl4Gj-JhVs"[m`s 4A2 Qr1mк~C2wb-m.1lޜa5@g/fE 6ɩ؀Va_]Xjo-A;cȦL+"Άa21ll L,JI@h*!p`f#B] nW#P~ zS9uP#L/ 00r蘢 4~.blgh}yC^ص$̍Rj3 B %lrމt&mv .J.gǏ}j j%O^^midh>o9'kKjg 6-Y1$ Su;UtlF 3BH4dtt0E;,KmG*1GGč\ z Nh(k4]om&Lp3`,*6,"[,ɵ2>au-ZGgGIǘ59712)wg:y,l&Cmw2:ZAA9vqu+1/!:UPo`^= Rl|vNgw_g5"Uv0Oƿi`[cϥmt~B7n!]WlЗ~.9FZ'KKD:ha"%9 8?:@ AMG,f!\%ëXw7W3|lzVz Na*,&F71dX{+Ro;Al`?ϝ0zYEpS?K߱Z3ٖ?l v}Up^RX=WP !5p`׈ڄjG'N,uZ7!n4weu]4Oeb6f*_>79rïn½Ý-uV~-u*#L5AqgcUgC-p2Bnhm]\q3,\vRض06*H}QF|͢E|hgB !G¢֨JF#3 gb~tQ.Hɪ6H^\8~ 6D J@*=\Jf`s9T`*[^!_A{Xk/MqfxuYvٜEz08t `2#Erd#Sm/g1x?%TYM%|I1v(ú$mƾF|FFNK@WӴA 7B)nvx{ۖ4 #渝t0_HQQ:?N!LJOVSqGgA24l`XI9l+ycK/2Y}[;<ˤd%C;#Fa͖r;='_U9@ p"=-F&Έ c+n3+gl6Ir4Io\.HfUkl :˛ulZ:S PAEGdN2Y?|vlZb&ȟmx0hǞyou._-km&Fk nP& r$0=A[o_ҹq?=l>+tΡF|q+L],Oң8# С`u@ŕS0vr8cYAn/a'F Lf3+’Oܞ"kqI.08xzװ >9daco5XWUzzݝK9d,LŊ0h+j:o7Rz߅"ȑݏ73dZվf f¼^tF[lO|d*ӈqvѨ eF+˹0̨x1┯O Vu ֖M&2wfm6o{fCC}|'Vl:+bJrjxw$"o!{f6([sZa]QzgvPQKrxMW pK +B1NuC: 3.qS궀( ;r=fj61Ö́itrMJi=?A4F^vhYJ_gpCxt[|}-/,F 9~,=%%k,[VbdJYE>D\, lIFRO{nY4bsB7u$m[*菢=fEdڝQRgyW6YNl܉f]`b₺_Ol\b3Q@OՂ.p8({ \l;m[dZͅ?ݺ2FEZP`DIFVy7$L3!c~$QVa@ȦFd6`)lY&ZR>tJvP6opծF,ЊlB3Mݞ4e6;Ro3Ϧ?#BC 1,ՍSy>W"ZO8 elqܗm1oa*yH#YZF<2ʖ? |G^:H>{?DB:ʟX'TW~UĐ }꿆Eؑ|h @C._Q(9Fr~ϾKhW?As]7L˙z^z^Ƕ5 fԋlk߾|nF0t5M&j4nAp͛ޮQyF|qh9}\7 6nض =\o[Ρ{0\-p@c4/O׋qax;W-n?WRE3[7lloW<^硡c08)A,@Bt~%t:;1`.CĔd .[5|l̀boS>¥`i_ճĶ w_ij<[o]@{Y0m{vmksoQ$9PpEçճ,յe};0.vL4;<\[(dW(cw?B!{hPa0g~:1foP]On-K^e8'`Vذs x w`CE8Yb_Y4rZ,fyɠ7naٓ^CD&8 zVٮ΍Pu BӶ'IgbOl`ܙLp@0nq8U qX*ۂۼ7rk``=u~9pt ?"r  |BԍbrܜpU]܂Nn3e[OZ,@7 EUx~3\@kv@|bfXx9U7@}3@(Z4Ouf}/5Dx5岿X&f rs^ī<`z,^@7ӜUDkڐSپ(IF$I 5cxE:܏IGot) ԿBPFaLOm////~,~WM^?k~r.ϵZZp~2`ɐ ^g": T|;tCpF7n #kG)ۢ\@$l.4 K? YH̄Yf^, HK+6nq R4;S^ EcP-odoY<‚ %ň-- ]\ib5"8w¹ 1 ( C|D ^9y*o(ZM|tڛ!Q,]$e!? o]2)ƶAiNyA`{Yf{޳ JBCzD\姣']tkfr& "} ZˀU|2poYO:xzfzj߸'30$HDt&ʃegkPh褣$L0qpONedyxAz{wqWqqSou\R3rX;q ^$aBAPzrKjLa4u:ZнwrAHQ(ܝK[Rk|M>.u[agv5OZE&oHgWtRJ{A_D2Hk@ JM,"/u .?.Y،$m3-!-4H|l(-f&!=CO u.0 /;8L=l[9g$L3 K\L"jC߶ٺHq nHq^4Hv>CPVv)1PYoS]9{ (Ri62G@m, [z2B50N!:kGBiOxqcOnGjP+6n[XK8syt 9J3<2۝'u7 !}(].%~]/m0;׸_NV9+a˥(5G\0 o3S?U'<>!@.)@; \Į&v7FlŽu5:A#i@l3Nt&s./ŋ4nW"# ׀ ʨAt>x( Ve;0_{ +֑O0E)ծr'HDʍ"?ZB:"nJ2@xm+<)zրyQ ԥJS:D+JPD Y-{7XͲY0 jRsp &_<]M "B'e ߟ!Ix2><`ӆ>g8hBZu#7LhJnӡW?UҨ =>?f`2 et pot87E{' 2yo K4nBhz?@I(nѩ" J+caLзbAJ - ۠ŏZz{[xw7X&\~يl CL@)zq=?&P" g'д.4L|[z(::UO>k\a^"'onWUN}E?TdVKs_,^ \N%P(AYS$|W:~(߸A0d}7aVdcs~EjOx:lٿ^@=l=C-Ї+ V~I>k{[4lo& I 4k:W{kS"o4C !"M,ꪸ!`HLCA8].?VeJ9z?dJBiz0S.|z´}<ۈ qr9u3Wjڅ[`=ڧg؝&? ܇$ANP2ZjAd>3ލvc0D0??w6Hw{~|F~U⿿>ebkxҢDZք%=)`,Ӻs6\p #1L bHLtprؒi tosN-)-PL'G'V##we(}]>zTu]7M! ʣ [4|,W+Ӭ߲l= \\~Q\!shٚX AĐ5jJR yt!U!V0x%k{j P7/ 3h?;と}O.%@a>V^V ]"WPfpHAf@ל`9h9C@,PRL^Vj`՚}>V@eHSa:b;nY-C;͊pԫiIee+#sۄushs|#ىb(OQsgU )2CVeӄ/ÆZA%ASyD7o nk8Մ-ph?/_ѢOkRfzS{_%˛rm wh^Xi*}n;hpM5ZhTy re$6,Qe$ cǭ'os@1y4+o"4 <)]B+u.P>d00'U?\0= 2_#UmhތIy ?Ԩ¤\j˜~hۡl:1mm B GVW 7`6*j;OyZqRj`1zItUzPZ$^1- ،Jz]C ` 6R>"r1dxVjkؚb%5@łb@WWst ϩ9Pr(nVA|~zjsUPqҁn꬞&)1 Ghɤ<}@]2|_S4aOz [퀉(, ͻQ0EhKnLYKZ-U5W0G=\F*x@VGs G5& e"V i@vc'~ep E2 .tõb]3 ,Zp=pzmKϤW7/vGC ut=#Y^͝d#H.?b89P?f5B̖#gat]9)]~$JvgEDl*J߆PGqLڳ`0~tzop6Z$K ~DZm~Z¶P v_.>^hb dxUYPu@w-Sx6mf ,5Rjcj+MY(e.FBԲ*2Z eqA&HK"d(1rc4 'q`//셧-  !FX;xOrH>M%$~fuŃJce3&+ 􊮟IӮM*yϣ*d:]a >'WK~W@Θ5W@z܃A쬿LlIBxAyk!V޺^o[vgOЀeaR~BL]_= @ܟq#JpBetn3&DeURNjRW!,fl[X8۶ٚ7,ŬZ`b`cqE^~%\0sfl\.2"O ׂzSgu|5@IE;׶CjXLw aPgA*z}{vAP!U=|1ѡ[ 9U(eVGCQ@KVNfCr786]ݽ$L>`S.xdx"^(1`GIAB|rW7(l9|n"mQOGUmF qSWw ZÝ؃]158β}/ {Rxx`nNk>`ap]0NMJC6"W`G^vrEmY/U<ȇ@p(J@>8'˥ r+a.wdYb0=ϲ;;q bgV94(5W%B'$XI OeCOO$<*VHNV'9HRJ:'{\ݛo8Tq٬/d tZ 7 |0=F#29oWyiѯbAQj\2u:AcA'!5`}ѝmA@} ChhA9Ry *+Mˠo>Gx!pY!wIb2) ecՂfcgؙ]MƇYDx?^^N*@0D*ԠiQn]Md 1LA!/Ⱥ~OOs&ӼYd.H}zJOܡErQ5Gef`ݽs g6W?n&CRxc;FbN\)bi5=z,qdR\`u X{ҚwLqǿ_o _+I7;p4Q*X _^by~Q{u7p_rK?܏Z2Yu0kڛ6?]1/n4ю"HNXzD*ͦd`lCafBhDzZF@kCitN)kX s2(@Xɒ1cUP- ctnBڅ$'IYSfG6@WتWԊ(.r9KМaz/#aٯAfs:[,SHAL Gw1(V k?oOI`lǗ.gȼdI5%B/³ Hыg0Kl;p`V zL 4Vad l }P02&iJfFv ݈j9/h* :7JgqF*>;-*WxJ@˒=xCfg^HDB5.b"Thu+SЍ{8f101uZF9bo ZTQjVY>NZW,n3~ԃK Ə\Ly?^—GI}8zu&H<`5.űDK=&0!guW$x&d :2d/}O8>Ns0ua;e^ )3NzUE)sꦂoQGOAaN!>O+؋",rMB,mѭXmehZL:- +mkPjQAeM 5NiMߞ+CtOI KZ[9SSH!/pyg9(D-k:̊˔JE8!YE+Ι_Wt%43۳BѼ^{wѠ0l*20xi|}SDsyIKл1j9T #F >`cy2"]! jJjQJs5ZxA4Yt6`҂J3` srECtB'i#N V1ɒ2MXk,RH"q@3ьKǨ+:0]f@©u V=N`v{qi1kd`̀Wu7q݂>OۿfZhmcT/˘3HG` OSHgJ4P9)w@Ɵ:{P2I-{Z>ŸR,}2θ,tvfW]vSΌ-ǹ)s!dsz^Nz;ʂ0ܗ8&@$P< @}YnWaiTSwG9{& ZZ3kMmYQؼ5q2=Hw__:]sgzF汳hsTUꤧb1j6'Lp *j˼0\ h9X!X taYvh*dBiZ *x.ara>C?w}Xpmnau#ܬ ,0-Sǰnx ̶AXu8L&^gHRJ¹dJ4p+(' [`-u!q7ww.ޑWJLd(VTSD n6>B"շF -(!MʼPHc^;22ACyP܅yXqʶkش0LȦ{qjV~d`@/66}"0 6x O& }u7VUĹ3,qfudljGz)n-n jspA=󲜻 . Y@ PgN +hK*cF2V 8MqﺱV< b<- dǁr̪NGᇨV ݐ0R~'K?6@ I\\ 0Rsn? 5x+,,aGB/*[qrTיM9!T C"SU#h` #'PP6Rd B7FW%@1?/;iT >l3SqN3a..0JX|5# lc=z=Hl^dA`Am;,vPDytяt$)&xe$%X.~X ÏXTQ2xhOojTIT|P;DҦFh? =,W\ɀI;'[ T:aׁmAXPuKծqXI7cBiŇG9WƸCkI喻:sMm?!;*}5h'أw_5RdۖkI"ovݩKn goofr\5΋Y^EL ˂߁#0'.L)F=/qI]is%Y 0󌠴Z'I3l%v1#m: c6y7fxy^#fܪ eSTdd][ww_2&AliXZٲ)xV_t( l Xql3K#|c79*tu3']gvNtD ]_8'_ h90(.JXL54w i`pPW3d+[jdr 4B\hUZfrJ[BV$HgErf=vhMGnꁏW`9+QJ,4Rhrm+OQ{ۤOH-Y2#Ho7^?T؟ÐTX~%s;dˌf (#fsS! IPNDĉ y DDb>bp6t@P sf%9.sDݼC@\ I q 2ONȿ-3 -Fx3Dڕ84 R:nEl]#w7(0&^%UG2 7ݵ{l#5q,'UE_A}yT-hdxt+E2/Jj1&sҪ }ê=HE@Z,IRD֤Z/X}N0u`<W*فaL0y5cNy70O`I+DԎ)Xb5ًq{3t|S4gTw& RXlHF ;; 9} /}h%@͔H?}$L~_|%tx0$bS'P{MGOi`X0﯏. ~ra8qȢ%~,X^= w%XR6 X=49U0DPsgo8l@;&S)"y37[HOK(~ E>77ΦC0rUg%yUlyb]&=wq4D)NydTWӔ^=tW )Ll!BI]yD`0\ъOvay7SWWFC% ~/3u>t+`{eބ=qw1+QoOtVX2iMuۗib;i^@ y1 qΥl>i^+#O{9H`Ԡ?9^uQXXXGr;1s:RDJ`@gdf:K,kt\T$x;ѶʛT&8K!fҐ?{Thf!{'^s5g ɛv.>t @x>@-鋹J*#u||H.;Ƣ_檟U,o'F0 6c!W-Č/lvcbCAP$$L65:j>X|McC!v9s/&df[+5"5T9X*ezy 2'Q6ǐDD.`>% ְ,1TE?_:QO61m01x2= %!!uV1g3@z 6@JLE33 u;42B$q߅*>2?i?8N^`T37- ve҄R u|'5`d:[Br-rXޥϐ0۴:u' iqib뷷G~]z{{i go,DzY|.fLTH˲ֵgյk<}x1[ _u 꺽Pb7\VAKn[Xm?bik&$I<.{]dK}&OxI.>|`,H]茬*vHeߴ@4/*&m\OYx3M&CVqb/p7oQ ^oc*++@ۉ] Jt3]j?jw׫\՞vˤf'(q)⩟DSwϷ6 V@E@ypֲJs.DdfA'U _ǃ3+b/ۙB,q+< zZM70ps/&,zsL#tlf ,}{ĦWug5YjR XB՝`3{2ttqNtϷ\:p y@*|lFX- ,áK/XSKd٬2ݚ^]N5cAD!K]L*}?gw V BH' ]@#`qhi3mv4q.Nf7w}s_9Z* =zyZELh|@cw\Co PJ `$ulN i 눠)✗韠0:Sie < 𨺆z@xMZE}҃1*  ӃLK!C[3λl\L-N3$pakƟGpq5;l' t{UOg&>8Rѐ%^طR}f֋zAGcxIL?M P¦ӗ;8H}p?ݝS狡y'L =,I<%AƜ9Wy(ZqӓvwXv|48Lځ^z`=TsJ &uӸtjo=1ޯlJ%49a3VqgMs7Ru7w9vL!bp3d/,rWFƀro9 *zeSE 1Ʊ6 Aשv;XTu{lm.nՕRv ؼ |oR<@.|gI; {4G>|p+z¡ACcDֹ9|*uur/6%ǒV.Q vɿԎe (Gݮ,fg]AcPq}`)nV' HӞ]ס6aUCa&=){[~)SހopqN%w+)0xMBn0uW/2hv`ɧW v $2(ף3ֲ=QO 8Uw.uܕm03!l6[.@-_̿,l)$wptO2sDm뺋ʉ0zԽ'y[%cӊT`K~[* Lڐ]*g"1Lx/m8) q{q1H2 :p&ӟ_ees+ߠqOW)#UsDaW@~bH`'pe^+dvwL]êNgFNurw.a*$2P4ݟt^*T .,{p.|19Ux)`ś0XN.,ç}V3~pԴ˴3u6}9!}+}nh{rl 7{vlZvv;Jڵco_sfI\UvkA!=)ҖOb#ْ͡J ^8vkW.Kb c9_|gX$myw}6f#}84 8a0J% =] ^4x(M`qГ\XE#Da'(Ul] έrOLIת$n Í4)KZB8zʘjڸ-O?tÇQwĊۄm0Tj&;0/TmN݅ن,6"#Kd!{j> 0yz5g ̄ʪRw6灞O A&Vt+ :lnUPw7~ZmOx讎$,c@x_˼`ʶ%t5s~ٟF;ji.PsL/0+V d]d,,rPc= .졵%ܶlssI펯D^7G_  /RQe8xUHd&)`$gі0_!]agq7??Hq޻ 2yR/n_fOv J+r C@Or|d"2'o*:%[&\tD!bדHl hfoJFeAUS3 3a;6tKRϰoh;9ad(}ytw]Sh_VSL܅[κ3[Ɲ}H?f1!Os |0Hϱ^ f]"W/.9 7 kY?ƺq++s|}L%CO<;5~}۞X,Suja#94Ըqdz;@8W+v'1"*ƃhz63{&@=1ZD@ y?Lß4@6PYPP?]nn89ſWԁvkxZ*FCLX,}Br^ЂsN1Ea.`5 {ƪx;NÑn3ԦV7;*b*cnbr^qqoCp}X9t&N`ɔu7IK|]6Ӕyy|y%D7d{nQbf1!~f n܀<{}r}TӅHKa0a6C@SXN$IP%K Ǻ2[z|}Ђ(/Fv+Irp~$r|}}HBw?18. b[2 岡HgbQnkA9@K!q_}JщyPx ^^Љj&dpm0NHj2(3HYQ5nWßߞ Ʉ] <^d}-|l*4%?*Os#j$m4tT77 M3u{G 0e`/&?ˤ;itt)0)yyolaTa6׳y5+ԩfڐN?4JJ[ icN5LN5I[)f2.if$ ȺzV<'XK6{VlGwv_YƔ6QpTڍ{sBa7>Oͥ z5R}F45v9aWWLҷSeOT}\'ye&~@- F/OPIلOCrq@{)oޟcAߢdr܀P!d[Db'P/Rz]Ֆ!N!7X+&uo`ёRQ6Љl]hmo^>!è9C&^4N2ɶI'4K?:XЋeX0=[E)mE@gV첾:bȎia/.QԺua; FmCl슇J ć.yv7iE4a'vBɖ+2ŢGo@>L]AP 7s5P:X3>וZAplcx0K` ĝ,3K bU&}@8' O\ǵ ?h)Ab +D+(>W[?aSP+$MȐ[f0S,g ؃sB4m&o>G(=gڕ F0tPv[fÞW=C)+~RM#5)%8[IW`[ł:WG%>[l$q?!$yJ^R.Gۭ `hMf%Q0m_H)}@fI0_$hD:kAر/-o @S8_XvB]^DzGGt<~jRߟtXe5s6@nuDBlVzӓ9A\2SZEOr/TgΤ%W*l@^ĺ$`FP$Rd6iJСfCnnQeONq\)U0׏׏FkG9Q5rJ22fpWUGuVRNv]4X$VvȪXSX7yG$ R~?VP:AFl89©u ag3SqS -T,-j{#K&ŐtziԚՅ4g$9+C}ʴf;Y-I1W ; a7l6ܹې]ta *Tɸa3.+zy&ˮ;Uu@o*P[+Bր1'38fl?1wXE9 L0n(!  qd8]Z sSE jȄ'f1 ;qx nKWR2L¹(ٱ#{襥b;*"N=[`&7]}Vp]7\$2v?Z,"_Ai=9L ςxhg@nsNdt̴S,ƙ6Fz>5tˇr epZVZ{҅x+=Û;v[q*U3g:\.V0$214N4G_bˈUr$1F:NλIå.-`Fq858___ %0nQю)!GȤ]W* u0›\|yK²'u/2jMzA7S9dN,Vumf|55IR!/)B$Sk0iٿx%iLE2 35Lo 0|$P Mߢ5{if4S)JD#/*Ȗ ^l=Rfo6W &p^p&L$fl\q~K7 '/Rq6 #9 X%/rftYc`]*ns@ 9"03U ev?3an2~ϣ۽~xKvM.qr@f*A;|RY.̺ea'uhϦc _r(5vW:Wr.,K'89['FM F^뙧}hѥź;p({To:ǙuIIfuئmx/0ʰl,Hi@e3p0@q,`CT}ARC:;6@%}0Zex $&}KbVנ^O0&L/<'.$* B<%}V-BX+/ dGk;cU9Ҝy.)KTx:ޱx>jr  WEX!jkTI+x"&*?1=Tۡ![NQ;\7wR *dQ4[u7h {寲=R +7p*X_9=%c6}zff +Ul<0 Rκq|1\m"(zȖz0 \Oj~촵NuY WܷjWaE}OJ7I(-7-VY^U, w^v0\6K -78+!.GI$?;g Œ [.ӾB=)HHUO#Pr%/]![t :X[:4e:4RW4Y[xlb! nGɹ(HU8GPO˽ GI&+V yx+`*)[zD'y ؍R^x$#6.Q%h(EmŬ{G07$y W< ^4E0_ʠi10i<ܯ;0Zzo]snOJ{\7 #PwJ`.FjEM kR3aΦ<[lbRG1i3HyGjHB3T_"M ã> Z-&,cu$2 F}_"(ɨGM?9 M8:CcKQģro19cJ=P!e9L;@K<*ij [e[O2QcZ lK̖} L `d2a d~ôwHCayL̶\rlkK$E8W&EUS ck8> aA'pfȤJ|=/ꅑ{b@/QHV|.㳮Ntzd>ٞcLFIޡʄ/~EENU$X=ա+-9aD\Iy) F-=$/JU3 nphi( tWj跳N݁]\s;k#| 8;,?>vMf+*+ {èup|';?am 6'0NmlWHX{t! ͟:ۮ}Rgt?e)㺪rNFSrSH9\Iб1B)- bG_78 ԘʊlMEO$BvS_%I7{y9I3dlJ!`-rs1^aA2%pn#VS{u@8bX9$2dKrfis.,0(@,[ 6RJ֊mC{VJR%i0 ?=, (,ݚ@ynqāOae}žDRNa4$EgԂ(=,a#x̲zy仚%0Bn6+P)2f#|9;&`a~ ?y8T$o2ˈ HQKO0yN>,Jt, OxkٓT'IRo.s%yL§4EC@c|`2ΐ:Yf,%K >!w!欹ra: 08P=&g}Z`ωp]g NK=ni@OCb:M[,ӳ=B&qtO6)PLߋeeb 50,۠;Ȥ<}h8J+6i=)4E?\rZKvdJ# y{ `F/{X MpaS:\}F_E,Kb!!BV%: YuM:X1QYP%ѹYȋ,L58^ʀ,BdKxe( 6 f-<6PAk ~ 3l a0;%^CL Hh'b d:/_z,)`UTT qaCr V])${|Ŀ,?gtXlej{`[LlJӏ^:N3X u&A ؽ2*IX%v'4eݹYP˗3#WO?}茫yˍW'aGLIC5j//Y>N@2YsaB >:q<=TJҫ-gnX@yn.p*@sU?S|L-҅W="dAV)-tgŸ46I=^k ӦCjd0 ։4I_, p_Z~ɔva{t0I%yZ" }>zomX~2Uw{EP|^{1>4=Vȫ>J¶|z/U 3S&L 3e2ƠkA4,} cV-*~"{,i`,FeC_NȽXRoI#[82$M:WeVc*gI٘@}NH 4fgP!!%D@`l֦q㼬:KIrfyӾUfoX ۬h0v8*{|74ZQh0iǷvT}y?b7Ǚjm6+Գfl.Oӌc=o6̓[S!D} c D:YB 3c#\/yMؒgy `"`8 uvс" 6@XJ d+|f۬.bZDGv7îj`tzV!p`/@8NePxlKڑy(Ȥ$-XTW;F&5AW{ҽlUxVzffpѧ+(`.*B pJQ.00S>30a7gەkhء: ݮs\@sNH_l$+lu`{HT! Z_څ:}Yl4+el9u  ]C m)a ѧ>a ⟛Ql0p3', 0i%G2]4Z8=C]O{D+%8'i~,: i1h.~ Дڠ9gjQ6a)%NE_ Ld4Y׿Q 6}R9jf a &WHSXx_i-ca!I><{ F$OʅP=cy5cNzT >dc1l 2D x} T<P/)57 pf({kOƘD@%oIEBD/ٴ!sYd=I2{{XQZ'#)aCYA4͙הCi8r/.4 p!!K8;ӓy&--j4d m|"*pFI<fr !J" )O%MQ0`5B5+;\͗ t#}M%={q?\9 }Sgtn0ly:RK-zGlk,L(gxgzOAˀW {qG~9pQa+ ~BAc.|2lѾ|2bڛV9%{~1`/AFX6TX4_ jPNMØd dD#۔'黎 m.ͪOP\ꩯ@HqUp:eAɺYݐD׷lf|L0NxnmQ? :BϻĞ:st7~ %Qr>'FCƆaFnAC^ ɕ\up3)N03吨{9OwZj'zb鞞N[DNyG>HLb,,-d: CH"kZO\g:wcp8|jGHpn"l_ɻDh)q)⏚c_rr\ƿ0S4  0m~"F4F[Z{ah.8Y@T,ap\ha 5#8&vXoԕ( OZ)PAb8k[C~>ߗxR$}i@HÑ2 ߿M#fƝlrxW2k (UcO:w[;,, X>) ,EN0&)AG^F,%79/!nkLCXsFac0x`k )٨J>~'ﰓ,h# HfPU@fѕM.?F{`>$ѹ?}MID~h$n_oׇx^ BcN#O5j>0P͉%GWKXjxrEb78d2렽 #[\bścW?V_6n= &"N_xq$Su<#YE .*!2;)L u;4Q~幔c Ƕ2/ Ej.b]̐f`Cxcg>iѤi33ʶE$;vw>8ՒY;IN$`*J y =?g~ʇUJJ)9WL]3`8 Q.jJvQ*g"gapTapG/Z&pLH/='vRMUy6oRBFζ*u2Eף4mdne:ƾ?i.p7:7.dyh^׵` 4wdvC8oƷ ?b0s S}[zYDAJXM4奥ULƏ8t^8瑝U1ngzr$ a۟>[`HvT[pN*UȪ>LXQ7b Xj>/ACFq0z+BUxa/=I YUWʝ$yjH3t,- QQoOTR  gЈdmNg^'8`?'UAi,O20y׾[tO$lUM+lm نrrYB`3zt֡D6^=J>2LߢLgM}*`^XӬ|9{F`:-V(tݰaC9.46Oa Mq4)&F7w/6RE_Cg:;N'L27\ne/dAWVbkvyG7)Bv>l.N@ ۱(] e+v\|lOT#E9@ '`Ѱa{="P=R:YV9e+yv4d } =@ 1b4خL?!:|$p33xdA6o,fϒ8pI:H**̅ʣc6}(\xϰEXSF;n;g0 WD4iOZ2Y]˿zi?^6!CpUAUvQ6aj˞>ʼn,H)y[%d .F#O# W;g> ;573ًzv ?6mWQֶNG#m'aA"u ;3j+NZv}U{Oسb¶Ń$,Dl TNbKnҀ|cG/\L"K6HB=-S'+` w2$'? `$]>%4LI>N2Ƿ& %rөAlu/q7xvZ)1*`l$ jb虓V0EMYB퇱/e`Gˬr)H[Una>|nȂr pRT-g:趢>K|Ӈ:y#58DSEҍ$g著>s;@KňqOD1 H FГbч,7fBOK*Eݏ%*U;Θ|0*ݘ$Nm D>]hڝgnp(J/`0 Mٍ924Jd攽✬߭Add_@,z;)wooS{X?wlYj3x']Pj; ^c?`ʹE!k>" tD]`~ҝo6 F3.<0;zHHl7 !64}FR ; ԬohV:>I@f b# C!JFQ?=ȴ|>ޒXx7B&0]4p7:epOEaH*7훌QfѵXE\F.'  Ǥ=tR82T: z7{`6ՇT@#3N?2+ڃ!}KO2q2a]Sbd9 bh~k&CEwYȎZTJbW|u~PawNS-鷨}8n'ۯ )x3]i_] HI3DxbﱾQ/_p%J汕lˑ-'L~ @ ǗdmWkF#"`}6h wXi9N$꜠H;B,l6L@cߺ`jJc)d=ְ4ҜtN *,[+؈ҭT2Tic(J 8 (@ڑlaG>u&7#XmN [}mv뺬hӱ':}x hOp9!d T =o6xX3g FCq0uW@!N(WUk,7|Sڇ~w27 ;} JTs4%qص0 - oYkMnm)\f[,x:q@%i 6:'’T { PLjVNlC2zL/(.Ӌ!{>xA %Tk-Vm= h|;v2>1(ٶמ?c)stF]l N6 6Jβ!}d̸f-˲`F:}UZxzͬVvf d'uQ0vN8jZl7 7l]01Y?!8FOHO*sx܏SBKf LL'N:Ϟ<2 r). >@慵`M=)a(Wd7QgXAG2n 5(&ﺖӳĝ)dg6bZ D9!.ڔҊ :}_>̀v?KwJ"UdHxOg^K7RmV0gg|sž7h[zg,XeA@9?>+Xxi|VM!mfJ@^ɍc eBW^%ԖS.94Y6HヂufTP /*e JH!*@4Y/P~GP!e qcbqy#OB.rQS`u뽽5pe;4og8i,IQ߈B=aM.-|"ҿe^Sşa`H ||HO4 DthΑnARKnq0H(jr'7VKb=_TRfg3/cF?}l^bL\ٖceJ;GLR#dBW 0 Bq bX3#W7,S@f#hƑw'vذ4VqY/!F ΐE~(6%|Zl`oŨUzV=5X s0)2w0Q ! UZ7 J(q \CS"{/RF~N! 2fWӄBh[E:I>M ~m, p\鯛%(hF8*$ǝl[%~Qe8$OY]~gf0G3h^rj'T=%%l?q3'_Hn^A1T~y)u~vR h䅏ݗ'?.VV9gƻJ{&,h*.SGT#p(Po捊6ov`'G%LV^A<Ɏ'葚)4+߿z~}wE1o|Plf_@_ Ǫ9otQIezX%4 ~ByKe̥ x_?׼vMxG3:#Dsz"ޔF򑝤Ε %“@$ 5⠔',ԫsZJ7V=.-3a m镚{$Q|  o:[Ģvth kx!*e@]UY0xixo d*Gh 3oi [f@tvNT&ɤ7ʴ$?0iYcBJL&@ =7Eqr[傍1=uL}ZHw2aܱǜ5K P;2kiS׎qIl\2Ґ@Խ76 [p"q44-1{[3EF#o,YC#Ӕ.)JLJ?iJ.j&!+mz [N 0PҤwO|Nݮt('CvFNo8l:R6#PB9#&łoP2l{o$]dϩgDlElwveot?f^s[ Q#xo_dIMrb)Zn\JX{@gO)Y.PX<|T)%t=V"sZdTLHa?*]a,\uc|-fc#}zIlj:3=ۛ+i.qe7`N@!b$| JuSϢA q%;0#KAC]v>FK,@!3y̠.M,dkk/n+A1LQPek&ph/X&fRq oM/b!=8dcE"^%"Z\逛֘Z5T*~|,jߛp*7M BK5uD`7.)ҙM];2=A]XEmmjpqեe a]c&1XGQ8V9>'U2D[.#-#%Y,)JX$13 ɼqIDw0Cu dd\R\BBv_ef,؀~ļ{%+w24bZŽ*9macTٯzomLh<(@l!FQnw`?6[`.~4f"lQD=\6TMD({I/θFLo0{ITGez]iɴҦ^?B$eH,Q&d~2}ii +dNܕVdH3(QRLO' b4h6X2G/ BLX!f2dzHu9--q/)T:dyTj-uaT߈k/[GJtS ŀ"{\SW2ѧBcC@tݮFWUq'~?ZЙ~#n=eނ}|C }\sswP TTʂ 9'{Dw2B+ې7@ރ]@7ʔpXU289qd2b;i@}Hp]+)RReYPx+$Pӕl%_+SjURrTzH@` L`Ft}8j8|qcsh"ZO{qrs4J֡Y >O0ؒ\*I`.).Ycv,.Je||'Ʒ!8K xƧr* >%!U] AS1e4{C,HI =@GS)~![]Ji@n#B<%'qW$u@&fsK(;Ž\‡q B[јi'x 3eԾẊ k~J=w/rQ*dW޳{vw1w+0Β/5Enm7f\b>$aI.B&xr+P8en}bpˈ8g52+6UP @VHN!8uI9G gl s‘2|蓠್ָKS')Hg<\CR~.%Hb9Vaf^ *vX^ba oi.كeSo ]Z+<.3# @㥌+۳~ z5Ύl:q@Ycuo SAi3dJCWAkC/S5(@.r_(4@ÚG ~ Nx{?5"r-\8*?^bZ1g*j`'Of{32) ӟf ibGNx 0< 6A`~^(3DGb&j6ӳsjsv,%3䥰.ο\=G'Y =OY񌹀Zs ijVdZ82/\:(:M9ÒNt(zpK{rgƠ"=0̈́>bP0-b 6o |R2?cC qT;,%n<CU肌V{wԎ0^#nYثI<P+~#q=_ˤ Jɩjg1iސ$ *KgJ"`icߜ.7t!!B%*L kѦZzote#6wwLՓ_lŝ`esq$8@3!X*y _'1/}8F|tmqY*[ֳޡ@GΊM^T_@}8~  ,"+b32ڴn*w$2x'I{.Kvų'ʕGAI#BN%C"}KY^2DOm1LO&e &// ul/ ##qe\abηU'B.9oVD|'zZ:%eki+p,#&t7k902k&oq0H %yH^zeoD{I Z HaxҩUkȉAOrdyG%JH=qa(9r)8:& [p)]i0znI 012E[=U Wp`A'I_FU|Y,Uen^2|(G0Y:JZc9D>#DE"&)P8Q|jMOAVl.~{  c7:R)=E%@‚~F/m2xm AKm95TlVD"VjmnPaic< Áy3s~ sV ["˗}jYn$ {㳱 f 3WȌK͌C%i8޳vez;ik3%66WZt,`k-3GlR<ԱPOޏi#!S#gUQ5&l#E3GtHL$zNK KeQ@AwZ媊U9o'flSWj2lDq VŌ)"@LKgY@?c-wBb"7΂z2Y0u^g 19`Lbɑ@E08S O/|߰l.CO2JUG5`I ;0*ۜ/Q,]媦%(ysd0 =g%p'HӺ^dD&XYCdeټ,<׌Ll&3KSSM8Rr|jL)eZۻJdl*~D4]S2yT aK~3PC: 417ő`BucjDi9|OϘe.VqYq}Iڋ\"}UDCӅe.]&lO!'r9''YEaD%Ǒ{^#8ZwK. [#bM'/lHIGS-92CuәGI,fJeDL$w09OgbK!x abyIQrf#e̶@gpd% Z>1'{hO%C>i ?r ~\E8`CL 2P}Ko 鲎a]˞eǵًYzx+'tC߀DpBd9a8!ku Q/ K57h,{Lk5ԒRf%D3@% 2Vۤh>*kPoRZ+҃h6\:;RgT6{RҟV kdqec1 xfT&taulzmL(fa 4 #.O2 k$Rx4ٗY-+V>B8E%kK].S@'Ѵ`zɍ,6\ A,35SN7Ct8,)&@#ȁtCh,HHǺ0=Iwu@">Q(^Gf{IvP8Ɩԇ*ҘT$T=f5YE2lcMU0ڧ]Ȼ/WwX8 3X`΃!G,k]Ufmo2Cgԑ-O'Y,xհT+x.E6170g*? RKŸت,H& +~A+5~;]s go= nO/Zn73Khӿ%di}AEpdP$ תw=/bԘO8"a,s{/'oh`,85~3Qk&.^.%4QڡU6q%/CS7L?{zXX&jxY u`{i|pxf# 4TC2ptVOz#1Ol osOqv$oj{׫.FdI;C}Yۄ[iǕnUAp,i`3 ]$COF}g6~pd–R k蓁{R~o2%tzi!'@D<NK m:yHMzbzsqTtB1"@$ Bz3Z?tP͘P^fKVHVl,(4۟6m C޲_ qfb[?1Tyog*jPcVT[0YJWb>'߄0cSAP`16&gweTȼY-@aZi!8rr0%mLVml BcviaK Me +~7K8^;qIJUkNs5Ԧ}g>ܪѽ61dwy {ؾZLq 򁶍1*Cmre񝲟9-Jh\GE$X|81luQA&0fQ`6J{p,vm`g;|3>8KOCζW IE%=y (.-;1K 2cΪ^ " {wWs>v $-e|Дl¯_tY,xuC4gWm{8dMQ6 ?:% 0vtc]oDC3cK4udTSuhkQ?=<]O&B ( tQ:>Qcc\熅x ֺ(g:)L; RYF dl62%3[hGM$Oi[cٞsiM$ivCAZþBl_n6!uh7&;F42&sYN&!p#͠o1G6+a3"5[ڣF#'Hh,u+~w6"z#}<.@&HA/}"0Pt͗e`܍ ѻ'j_hڭs;`ؙr26ԮW'^u_Ft}o JM 4F^.qʼn2O0Nf]2zUhІf|< ׁ>veBhV2 $Dё }֘OL؋maHh^+r sHI,b^{KaIM.QDv'2vD֚Gt<_bza+ %~gSluR_-ma& ͓d,>`<:a2}}Ew&Ke9G{w;rt9f7ޤ\Xr)Ϳ1Ws'_[@gpNK4 ?:x$G2}E`)}Ǯo %ivDtgjUK5P׍&Dv>R2#*hW4'<xJC\÷09*E׉&)x#p[hq&)LYM]* RlLqP`jٴTY%i,(1Ӯ'ޟWf0q?X_yβpQo'b~F~["˧p- |lu::y:Y\jv)?]s};҆6v#p-BQ~s~%>MxLYU)g(̶T!gPLHЛ\#O$mDttv>\ay*@BN!6وutԚK:4w%dǴHG`Sw9q;]EDyngkԪZİߠ#Ϟ|Kzݲ _ gJw&[V'hz 5þobmVe6iȥv5 Ex"|,`@zVi?Z;LwmK;-η/!5&.9[i'b4H^6cc?#1NM!W_ (q8 CrM3x(] n 2!3-}?cC^TvYC<"$GqY y:pCJ5U-r l=Kk0V|>:s߷tfe[9QZPNt[9ϟO $$a9AkdxZ,L7zwX؏6mz4C*(@|ʼoV0b4"ᅡEvJs aBl33:mma;X@e^őm!GV Y)bd29ohI3R7R[4ʵfņ1%;Mkz zZ~<^칅Yx_շpƎN8bɴSspC%Iؾfqy([246J2][J}7!crS'0K F{I~ Ch8x _a۰_>#F{h}} PD7@#6 a_uNZEgv"vneFWMCifv]JG+k $ЅKѴO 3Y&'w 3υ;/PU׷>qaJeMOs'"( fK}4k8IBKSӚQ& z\P =쯍㵂e^,g.C[=/lp4e0?a'cDn-Gc+ 0q.C?MQģON޳u5Z߳ӸܣEwHm{sV"Cyn%vdm`50m?eĽ-[Tl~ Cm V*jͰaM{W~A@V@lER0 tXBLiŦ`z+tX[/ ok#Fqbu<ė(vpofҲ6mG~phGCf2Q潀]Q1ܟ;JEXQ^$r=*B27rx(TVvJݖNW"ټ]*>kk!(4I:Ϯv΀hztAoÜu0 +ՔĬ+)ѓ'(TAyB9-r| (]a pj89RI#RYС}zPT{ԜҖA9Jf̂$6ݛ>i%P:m(2 d:p(<4[)`6yexMo[Mi:A 7McS7 vٶU@ևpO=8*]fӱX R t2uB%ݬ^Yw bPT@$&̸v6C#UnnK_NR:Cۉ>A;.nݦB D%լHq_QoXh]7fwGϓnV7If@>9 tSo}lv~҆p|1)Mu| wW62+_V8oCsKr %9PN E% [^~Cz$䚖,G 4Lk\q F-Olx:&y%(eV6, G%cz+/ޠ$Gb@ o?߉:uF4'_##WqH @}höXONMozlLIi-9䊞@RvSa4 ]9΁=s+GG)SiM_-FAN K|Е|H_W{9DQA լgOOw_gh^8Fy~Dqzk'q)4h A* z*"=j9Ͼ{j~?{p٭PP~b:ïoQkiV㯇/jXGH:j㟰ٛ~GVj5ɥ`| FEf8m{GMa+(c]hhћD?DǢ㗻' 3)z@ӒpOVzrt%~/yN5n@ )h4تE "J80Kpwi"kمE"}( PB}&(6&4O߶"0Xq/m-Ylˤ qS3hNJՖ^iYo(fc]:uizOdeaƑ$" *RT*G3e7ݿ J{܁p7r[c4!Sw Ig{$y;]_[axAn/S#xIϘ fcWnx}w.#ۺ~!_odNy.y-aL/h.ľp.0icm[6dWES\e=GDwd-yR5Ȍ7"4uSO ~; nP=JXKJt=A71aA) vvz͖ӣ Gpj0<,"zmKmNH^3sWȔn" eO0&Nה7ζp;X㍄2(Ujm[۩ǪBR 'G*dYՠx"Q VclfTYRp{O;9 [28&=Nt9k;gFfTY~[N>ʢ$x;-6f8^9{{y;=O8:.j͢Ң3k2ƴ9drtaT4u|s?Kvs1GKv=d;ۄhi3kƢioQFbQYG?IԵplN 0-35f|"ȢjHmyby4yt(5iY {jtw7IvzjahtO0mra PGN]-\PtDk7'^DM~L<\O޹@1`g߹f`ey+ xL>#3ԥbCHhtJIw<^FaD/ׯ 7Yf؁Z4܊F7 2hWѴ$)UG-!ItHI`=9yJv6!({P{ب'Ar5m;Z ZE;䃢r2d^uϮ*J  J{:ލ^ ܑw@?n%]vm^;5FW;X% /;_Lj%g%}&|MQn~[Qq½<LGfhGi9`B"#mfņ^=9.JvH$>J@ÉOPQҸ IЋjJdebLituD9|搩_.2Uu?\:Ss2\eF$I4A=ŝknӓIkl<Ǽ>[o_n;Q.3wx@r欺%&3Q؇xfHڍ\2ճ:MXS#/v چfs[j@X8) ľitXĐ&vfÜv]Z!)u.89K!H> 7UF̧Gި:]R-.$ Rss&jqbxp{L6&Nـ5k9O#cMfeQĉNFSZ4o%zE?iyrrvG=IG2y"fA* brpN19:Gz~?ΫX^E,P20~gw_NTY<^n~)C_)kE ^L]y\NcVzR!tbvXQbvy2Ѷ8D9%}kQ/- ̓WR 3T¶Go?eDL?YP13I aO<p,J8JʴP\gpV:+Q(VR0C,EiPDzP10X*dkPʼno/jrS+t(Ks p|p10j2%d]W[x\Np2m{Wᠽb$):6Kznjb+.ͣsJ6$60fMJ1-nK1@!z'* 1CVXY`+WKݰkptM+Epae*NyqƓJ@ cwߦ|䵔d܂EnO0ڥBֲa/'\w-s}Yg q'0kףh<^O ?3'Xm̙6=I3Oj]5owձP _-Q],Ƚk03EaP,Jm jL&1B^]i(9BOt%PR ۏhn -‚䊋'CY4$:K' u J ǮxcBeV8).ţ]im-$DZ$QL-хy&,]OՕ|idIzmkK'~Y03i=;bclFOsD奝8(+^λdcriև]Oo};N) sY3sm&fvAl]P*ϨeJ:a{!x8Lq U,vW71xuQ>.TY^ $[FYF7rD7ŏPQ MĮ8@t sJR̀Jr6Y]ISS99iEEv3IfU]#^ϭ ˭ mpvJ],rH.}F=Kfeh!{yhEkדx$m9n]*6'gYsD,]es$#ʐ27ru-dQ(Ɣ7D@c$6f >9'W2M@CՅOUzAU:̓ f`)yKnDž,z"Agv%5GZWYNQs4V%lb/#`f3#giN:Xz%/[W~I0͂`%볙 /nݼ  AFo`Y及n#.+ dJW6v' QswT9i6OW)0{@SUVsnJqrbUq *U7t7nZ4QtvY8=L"!>m 2mI"})JUM x?9D$$a1ɕpӺq7Y|fɵ|8Ow@&w_~|9B,.ff:r&a ԜDTS#]eg0PDks}S CU%,Px%w9z~TNOV YQ-l*©䜋h{OY-@v+}6a4sChJ@Dc&}k"bW>'= -)Sq+qgC\:X&)<P]քbg uC^$Tl(j]P6s?TAy C<'2"L?BKIڝ1EPe߿wwC^#/vPL^Gd@~90d{I!|d>uS;֩-0NhB<>c'ZB%mf-:Q/_TR ~)}֪qc!|gMɥ?wԘY\@eGSznK x*N͡R׆3StȬ>zGW Yي<"4ZiMFҎ N&!q|ao\㚙SN2_Q Z8}<p8 E- \caODCak>Ko Z{=]Mj7h8PrD^"xh+O`'m{pF]o8Qt2Jq-gs&7%dtlILd` ;M^LWŎ }8pi "2m| Ǧ-(o>7[pYIa &q'lugad11@IGlrgyNX|=VOp7לgvV.I4`~ ᩢ:Y/e,I4S~$~9m_IJ .yY0QEnK.;< Hq'<6: Up2qmyg11akDۂ3v5tO'(!!ʹMxcO>}osyq2RG1$LUyҜD2BlT-N`\f>ssخ o' ّ~Km'I|]]omS,R l7!j2rT2xuE'x⟱(C /JO 6[z҆F-Ou8 *"eٵ*hzb-mc'Z&N6cEic|iϪu4)wsrEq ?7/toty%I[BAMߜz*󜬢~ZQ^bK>WۚXjf5cb=1sui狄.Yew-kj;yyeijXn9Yk9w35p8]<֮_ۊNGH+ ofJeMĢ?Mn$TDUYEYO}7$r®i]@A5i1p\١;NjF(wB=hRi` ~j vsRڧmr'׃bristol-0.60.11/bitmaps/textures/voyagerpaint.xpm.gz0000755000175000017500000023240011233572001017453 00000000000000ŧIvoyagerpaint.xpmDrb;*`sΆ";lj 眳wQjvZVzn{==<_y=Qf{/SH{2T(T<# H_-:38B&p.` L?^08m8H =ouS8?iכb0;}ru \¥Rij<7 [{F(wMv87u9>,h>lz>\fEϗl3/gL?#x ;a5ѿ$䌾e<59;w3#`;f~y9agL'LosR+d{3J?;\w+us7C{?ѕל'kRV{bpq:Wer/w]|?SA-C-|z&>;ѡgWrd$S }_KsY׳߯?6t`[3+dnws弃}_UL6E[7W;߶2bɁw/):rSr~ߛ(G>~Y{ж+F?||vmT ړ`I^y3^6/:$зdǒ&?ͤ{$ N? %/$0c~Fu;V'apyft퇃CM?ICO$MOI_;08~C9{/F7u\ʓoM=cػvΑ狼?4~O26ϙ #opk{]_%2}* Ϳ>W?C%Gh8xeo'/|Owuܕ_߅!c~Z&o"tgp?W.8s?ѫk? |= ߾ό?/Spj7_}.=?4眾[?g;ssQW_Dח^Yt_B=^ W\{d[>9\~׆;wSl7m;iӇ?Cߟ'oKM_~cv}qYy'%?ipaXfc>ma?ÿLBsos/c% nO=-os~ .eEo [aяbLdpvq-sX{yuKyg>13gC;|s];=Q][/ߞ_4.[Ϳ]h~=յ8wN>ߊ-Gw_}Sa>3GOya_+揞c^ޱspC} %~w߷EϞkpgjį=_K?K.l23/}?i6ނ)~?_7gh>/s|sjgQߗ Jٻ~Og͟5 /~ `=m듦yC9>N׌ٯ [O§g+ˊ\ύ3y5;o_xiDhpExʗYoe87N~?| s]*oͿTsxQ2};T{Ho3يбߢO⽧?ow&`s>e]QW;ug?7G;{>WinoΫڋfo‡zSUv~v3Wg~]w|[ot~5%+7ݲ*g ^a3{!~/D6}G}Tm-/9>j|΃v=֑~1?༯駿 o6~ .j1|~g(OgoyU5o1zG?#kxſ <,epis۱HgMx/k|)_—iFmџNӞ3`oI){[E_scG!W2{l:8pW.VNGfo.؇K}qq k` n_k'c;:?zI#,})/;B z'->xPڋ3{?k~?;v?^?]-g Ns9XW &k|xǦU1zl/mo{#|ߙ9~qSt/v~Oa =/-8'Ӗ/poミ/ = xFM[ n绶;+po!@?.bHG.?,~^Lгbeا`Pq> t X[vkwB|KY[d=9'?ϫa>3`}io`*|Қ́!w(zfdzKcOgkיK+=J&W-s:ݠ߷t>tgpI{/ # O<#/gk ;}m6 "/3?A!Npq~)l:_ "OWDD_W__[F?O|F?>-K/krTҁ b?MS8߬Q<(ʧ3cy:Axyg.$e{~*Ov=ѣ/Uew_E?A'|p~v;}ۋ ?7o/'{ѾGi_~3i<r~xo}Y=7j|kA׿:ٔY stc6Oكx=~{w|8+|/s?'2>dW~K,*f7 .(_K3~??h3֭b" ={kD]˨KOQHԕ?g<`'QkEٟ =+_5ukco?n >Z EuEYdW毳Eڧao売džOM/#\5+?[;[pѓ|Cw|~9e p%k;]?X1§oAo}xxzYE?^?l&(]Cb)y`m|% }bW2ZƟegU5W~o̿ov۲__w?nOͧb_s֣ 狖Mљ\~gԱoydo%ÿY__|uɟ響gﺫVD^wÏ5?FqWH 7Yc@?]VbXp*;.l]7Okޟ2/f:p~No/gbyfX2xпƿJ{z1=zHg=q,ycuR~~j|1H/4_{9/5>!yύ~O>ϭx:ϸY?>?]coL/\,zv|-Y[{c&u+O?Hɟ^{ߗl:%VKS\>KޠEyS ~϶+^ܑ<s|S㱟Zj>U{Ǯ`5oc;!fLK".;m:pP蕜}<]T3@&\ÿyC"\|^ O|5@_Y=I xٯI~8 _?>oR g뉰&c,q豯8_8JEO'5OA㑯Q;㗌SmxDYר$\c'?KqG7Xſh[/j3W<\"?HR + }N_7sop~3oć9lo8?sڟE0Gm>ok&'ˁ[_i|:>u◽9e/ ?Y|V,79>V;G) -Ww;b#y&?Ÿ/G$ÿ7ٳ]ϕlg6L=5|4YCL5ukcT;?ZަM§Hw {~  o3-P7?|ZSe+5srv>~'y'aAkO|ث~O;l|KƯ| }BA|Hv}:O|߮ ‡C6G5cпѩ` J>5>!=W;f/nj~e ?:6+oFd|TeϓY/>w_jη^k#cߚ/C'S[v>g|ዿYjp_oI5_ˊ}UǚݶK֓?n_/rgm+گ3y!sS#\>R8 o}O7lc!{al?wn ?` w|=ؐ>jG?gٱֵch59߈dzIS]p?n@0e؀7ᆫ/v!`pKOm'֞yO۾oWM2 ڱ_1PyK_h,T,~ rõ*)<hÆkt?V}T?I~9OWKע777e:x</2*Z%g>O/ ן|#Ook!|8_z.O}/AG9׉a?~gȫcWʟ`֓Wt߰m{|8G]=o:_ZTܧxso>o&oOoW?/|^ ,ֳw?Y?,x᳢͞"oߵ>K"OZl_Z/mKȗرS9C|_}/ÿ>zdW?Yco3~!g/,_vYOcCЇ[Brg/}v^WBdl!+\o{݇#B+CMY{v*o?h ݒ?}_U0wB!C5͟|جG_.> |G"|_K?﹏_˃O5_ǎDόñ3ۏX'L05^G _ _ſN|fODCw.Lw}@GџOslEEk_V0}|a_S0i}ӖQw"$o܇KKf7O8] /k>[o?Z Oo◛DZ%*[?ڑ<S'W6[~^튿wI8'zt̞y"|tw4Ƭ똾4#O0ߚ0;A7gX ćW~yE\~Z???? ?"@ ߚOa~==[X;:߬o"2o*?|8OD?s:/By8>9=CC#yLʧ9r*X'~}hOsep[ݷ/?w=0"Ҏ>?U͟޾gvRepKՌWc οs,hnOETP#x8V'9 &>tNtv≗?+m_qV;HoǷ?;{xP#z#/Og8xx9yϙǜ=_P%^БQ}qiN?=H^J>ku}VJ06sɷV;k;WyO/z}sz;߳kNJs|z*.Cx&OLr"d66qՏ`ߩ`?10vgޟA_D'3u}wqKL~5&Ah6^?߲~>+DpW&;{ ~_To;M=|~Ow9'ݿ&{? PQ'eͯmb(8 us0'?ߌSw>ϙOԛ4|u%|G|vap'z(n 7;'Wț~|vr3 m#3_5z&h󒿒gy}VXa=&A>6Ev=HC0wN\cߒ_[?7Wxx[?9Y}g;]bpn7^ }[G>v0>ckc =j/|sH {ǮصvRyV+g?- ׾g=v'c}Ɏ]aOW{){C<"Kч݇_G?WǚKҩ%Ǚ~>cKkݧAcWo5?uF{`UthpI]\7}yV'Q;xODދzxc[[[s~X9|z/c'c}Doο%XcO*|?o!(4UbK͞l3g7z_sO{AveƯs{3p/a@^1}?Ok,> u-[_ؓkc\oc5>绑$_ǫd f\'z-djYa{? o#{|Uc߁ bdc/͗xYf }$d qZ.=Kv|д^E:`>O/N5ο_ޫ9` W^M~/]y4REOu0j~įDO?W=?O|U/Yj/'_Y9-y|[OG'߮+~s?5>..9,{+*~aM~i}a!z0\Gt۝;? ~B[͗/wC:ݫk{}T/寚7͏x׻c1ߑ|1~k+xKGi-^I{K>[cY߮|5џu+ O8ok~玫O3oW>;C?y+kۛ>Pؓ/BKa/ȇkY_/SQۊS,/S5 >fC)kWO{_c'4Hg~a>atΟj=9}2|k_,/?Υ_/^ؿ[ѣc 7{ˏ?,z1ދ`_sos[7WԻ}ϵRS_)юSzOԟG|tI|ٕ/\,[ȦȧN~?sdo}/Wg?+{tOz ?s|l:Q;a$u.|~!+|~N7a+_yF?[_^܏x?{ipIg|k/+5>'%E[c;_<]џ:z}Y.'_WDVO&{yѺg?!֜~xx9ا\o]3|^/J?[47o%=~2>~+aGЇ}`?oAz1i ~ZcѧᗝIcGgh7Ÿ|`qO=C{W)'4:/'}ہzB|Y[ogY9?,PǿG p #]#ÑvRpv's'x༵k<_ȵmt_n .Jn vwE??W< ?_Os"ģ$Os]~x#k?{ZS{>[k|ݿ4wOײ[_a(}'aޟGs_W?5.|mcM}ɖ9ݞ?#?_ {V>уyU;ߓ~+OU7yH>UuU>gzP*S1*z/Qߊݿdzoj'߫v礊w W7?OīU^:4R;WUC|j|Qzh}}7?ܗY1{?yї"+VcO͇R*{/w*:oʩOWy?g\^'?J'\([e{& REY?k>ij$y!_Y?^Og﮾x‡O߳lkԓF.o|;k_Ҝ}^Q~šc}!b_7fcEO ؇}y*lg˵fK$-[b߹o;Ov~)~׵= ׶Org n+^\v_?KΗ }m\pg'gU[OJ,?`cC0[[%ݷ.^O!ؗ6g #_GG>>h~>_G2n;oTNe)Pq(aOKS-cYVDλ;coTP^:B~o~-~}v3K}wDaגǍ[w—ʽQh|\_%^XZ{E)i|]yڇ)y$^YOJwj띾|/ ƾ/?ؿ-سчʪKr䥕k]՛s;sv迣c~ :7dOg??o^럿Í_߽}/=Ыo%ѯ2we/og7 v;7#_yV[yq (/ʿ6-<>ܧc_X =z8ON9[_}:xX0}ѳx}}co7fg2B9z*|9V_% e}?HhO_35'6nhT:T.^ҥ7;wƻ22]8Oq|г>o5?WwsyK|U_Q_/Þy1_N~\,vs~X5oG?슾Ϟډ/j|Ks{bo}E+*@s'Ζ-MW>Y==g /͟org_?(~2?œ$?fϒ_.-j<>Oܧ|?뇠Ϫ7~a/ֿ*̟Ծ{i|j "jg?U;O nn4:[O47B1y ;pP(X=ї_5>|c_'> ~ZO| &<#~jz }W^#ߣ zYyO^`Y0UD_꣦5/\r;B|,X.mqjYf~zv~r.y"B\j|ݮ .ԵCFSV O>Žo V>I>C_{u˫8wywښׂnK͟~{=C_ޟ)yc}$ Wd?gXb'=ag)lI^Y/oģv_|sOG?Qx?>޼?H7ɘ|Jy,!dG_?# f|hF>LÚڱ/ 3_ӆ˷- /L2;c3 L>Bʁgi su_ɷGOg?/f/\-9)ߌͧ72#룲`}%yIb F}#Bֻ'?}Ok;] 7wt'v'yy;W]32'[=EuN/?oI^û>49ѣp_G#k\}5z]7KKOe.䋕o'Ux~9[NJy ?[UPe~oE^Ӯ59[ɞ}ˆ_VE%dO f]`5?;lɡױS/3]?e}>Ey꥾<*0_/nDf]{w5>'z>~-ooc?:m?ڹ?g\"R?~QN|`IƲyĊkެD+뮽7c+mlD~CM٫ٳ_=l~=_bTw)}4x?G8Eg2|XpAO>n߀Ԡ=GGs|zy>QB1~//r"9UkЮ|}9 Ss)Vʖ_E7U~?[8[0/Bz?K2;o;7??[f_kze֯aoGϾ?Y/~8??ɡmޟg·7a/8߸?Ϻ1aȗ>/9$_ʳ _5_~y A/~S2_t]}%3_/✿~jY"`E1߯eox/sil)= #~O~;x/#~_ޞ S7 yގ_?q^W;YF4<͏qyn#?Q W#;[x[~[o|cͣ__y`G?yB%ч0=v/‡|KZ\VQ}Ι| w|ޟW;s| ,=?U=޸4܊^ԇX <^-ߣAI{F‡7#ޑYܱߢ7?EOΏZ'cef-}^{}EWm$~^.cofStU_[{65zu}A;S?[㑯G%Wm{xԞq?SSv$ {1noM9Pp퓽_\4~F ?zT+ڿՄ q n߷U!Tp'?֫N%?劬o .+42ƿ5 {EoGe%r`(X@xT?iASf]@Z&GW~N4^⻧v3./+}O*|7o~O'-E뛶m7Ou˘wk[o,Ji_r濖 =w4K?u?ӛ|-+mG>?)te˵_?gVv{7;믽PD_\tC缽~oN<ѯߓP;E-b'>P;-"G{%-^Do"h|{"tq"c߳~ T?zUGOm[[2E!@EE6}C/Up1|—7bpA뵴ѣ|yԡNc,Hcsh>'ZSmߟ[E)/.յ <~?ǹXw{{o;iG!_]Ӫi%շjIϴ'Q] ow";]n:+>}[5_%yLUϨRao͇CYų>)_OOKC ni=}>%/G+ї6^77qcp%_[>ǻ`o\^,+{&zQO]ыϹY~=_dz{Q9?[/ }%ዾ-K\?~K yXW;o6 M}b? >H>w_08OK2-z4/5kv%cD/z{Gɲk-xԏj/|k|eƣ[,O3~ǖM_f._oB{18޲;2G _[D?xO ;pThI罍oï0p8w.eEO·s—zS߰}uߣ$-?{# ~__ׇ|#͟q{A=}Oi}%L5_'eaz_.]ߚ޿>{уzt=jﲫߖ24藲~'i~.zl~'}͖7ͯm}OvoězW}Eч%eZgv[5}z?/\X߮ _q74ŏ7=⭹9ܖ悔d}_5TvU'?W/?CO+ci*Z~xU~1/ .2b]q8_&l\ߜ KCk/HS|0k8\zu?߾wyoq=0SA>_UзOY7H8) _ſ#+|3t~pϝ{% U7tnpYC:oȗB~z-|9__xN#OÃ%XrxozH^E /s}{{R{h=ZmW#8c x~O#/b?WGUݚx:FlT\g'g dXn>Ȟ}N?e&$ykOM흽_,!oW!?k^vy3/4b}g|ʇ}8tHI/v' ɷ[i9fpKFF>2?/+o$mL?i; 74TP?>vӮr]{fc/!S_%KdEOɥ?{aoU߷x38;