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/depcomp 0000755 0001750 0001750 00000050643 12073601233 011640 0000000 0000000 #! /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/ 0000755 0001750 0001750 00000000000 12100257365 012504 5 0000000 0000000 bristol-0.60.11/libbristol/opmgt.c 0000644 0001750 0001750 00000005273 11746476475 013751 0000000 0000000
/*
* 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.c 0000644 0001750 0001750 00000005371 11746476475 014555 0000000 0000000
/*
* 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.in 0000644 0001750 0001750 00000041661 12073601233 014475 0000000 0000000 # 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.am 0000755 0001750 0001750 00000000772 12073330071 014464 0000000 0000000 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
bristol-0.60.11/libbristol/mixroutines.c 0000644 0001750 0001750 00000005776 11746476475 015221 0000000 0000000
/*
* 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.c 0000644 0001750 0001750 00000020246 11746476475 015452 0000000 0000000
/*
* 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.c 0000644 0001750 0001750 00000002764 11746476475 015310 0000000 0000000
/*
* 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/README 0000644 0001750 0001750 00000620132 11412626667 011155 0000000 0000000
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/INSTALL 0000644 0001750 0001750 00000036600 12073601233 011311 0000000 0000000 Installation 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.sub 0000755 0001750 0001750 00000105327 12073601233 012246 0000000 0000000 #! /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/COPYING 0000755 0001750 0001750 00000000125 11233572000 011303 0000000 0000000 Files in this distribution are licensed under the GPL, as noted in the
file headers.
bristol-0.60.11/HOWTO 0000644 0001750 0001750 00000046730 11650531656 011123 0000000 0000000
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.in 0000644 0001750 0001750 00000065322 12073601233 012330 0000000 0000000 # 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.am 0000755 0001750 0001750 00000003502 11703613413 012314 0000000 0000000 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}
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/missing 0000755 0001750 0001750 00000024152 12073601233 011656 0000000 0000000 #! /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/NEWS 0000755 0001750 0001750 00000012641 12100257340 010756 0000000 0000000
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/ 0000755 0001750 0001750 00000000000 12100257365 012153 5 0000000 0000000 bristol-0.60.11/brighton/brightonMixer.h 0000644 0001750 0001750 00000003477 11746476475 015124 0000000 0000000
/*
* 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.c 0000644 0001750 0001750 00000160243 11746476475 015576 0000000 0000000
/*
* 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.c 0000644 0001750 0001750 00000105737 11746476475 015010 0000000 0000000
/*
* 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.c 0000644 0001750 0001750 00000110502 11746476475 015402 0000000 0000000
/*
* 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.c 0000644 0001750 0001750 00000046362 11746476475 014607 0000000 0000000
/*
* 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.c 0000644 0001750 0001750 00000075161 11746476475 014737 0000000 0000000
/*
* 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.c 0000644 0001750 0001750 00000063727 11746476475 015460 0000000 0000000
/*
* 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.c 0000644 0001750 0001750 00000125452 11746476475 016123 0000000 0000000
/*
* 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.h 0000644 0001750 0001750 00000011144 11746476475 014722 0000000 0000000
/*
* 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.c 0000644 0001750 0001750 00000171625 11746476475 015207 0000000 0000000
/*
* 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.c 0000644 0001750 0001750 00000071652 11746476475 014727 0000000 0000000
/*
* 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.c 0000644 0001750 0001750 00000070665 11746476475 014677 0000000 0000000
/*
* 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.in 0000644 0001750 0001750 00000060620 12073601233 014140 0000000 0000000 # 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.c 0000644 0001750 0001750 00000116030 11746476475 015162 0000000 0000000
/*
* 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.h 0000644 0001750 0001750 00000004722 11746476475 016307 0000000 0000000
/*
* 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.c 0000644 0001750 0001750 00000153613 11746476475 015476 0000000 0000000
/*
* 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.am 0000755 0001750 0001750 00000002727 12073330071 014135 0000000 0000000 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@
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.c 0000644 0001750 0001750 00000212762 11746476475 014507 0000000 0000000
/*
* 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.c 0000644 0001750 0001750 00000061756 11746476475 015264 0000000 0000000
/*
* 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.c 0000644 0001750 0001750 00000071403 11746476475 015260 0000000 0000000
/*
* 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.c 0000644 0001750 0001750 00000106504 11746476475 015230 0000000 0000000
/*
* 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.h 0000644 0001750 0001750 00000064646 11746476475 014775 0000000 0000000
/*
* 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 `