Bristol (software)

From Wikipedia, the free encyclopedia

Bristol B3 on Linux
Bristol B3 on Linux

Bristol is an open source software synthesizer for Linux.

Bristol consists of two components, the emulation or synthesis engine itself called bristol, and a graphical user interface called brighton. As of 2007 there were about 25 keyboards implemented, a range of organs, electric pianos and synthesisers. The thumbnail image at the side is an example of the graphics, from the Hammond B3, one of the more complex emulations. This image was taken from release 0.10.10 and implements all three manuals.

Contents

[edit] Bristol history

Bristol Mini on Linux
Bristol Mini on Linux

Various parts of the bristol software were taken from a previous project by the same author, a direct to disk recording application called SLab. That project is now pretty much defunct, the main component that was kept was the audio interface library, although parts of the MIDI library were also salvaged. The original intention was to combine the two applications and the user interface for a mixer is available with Bristol, albeit without the engine support behind it. This is now unlikely to happen as the author has other ideas concerning mixing techniques that are more likely to be built into Bristol from scratch. SLab was programmed in C with TCL/TK as the graphics toolkit. The latter was overly cumbersome and tended to be rather ugly, using the usual grey boxes similar to most GTK and Java interfaces. Each new release of the toolkit required reworks to the integrated application as the interface was not that stable. It worked reasonably well for a mixing application, albeit with a few extensions to the Tk Toolkit, however for the Bristol project it was deemed insufficient for a graphical interface. Consequently a new toolkit was developed and given the name brighton, almost a pun, but in line with the bristol naming of the audio engine.

The image in the thumbnail is from the first GUI. This had been modeled in TCL/TK prior to writing an own graphics library, however the image of a Mini Moog as a set of greyish boxes and circles obviously does not do justice. The graphics library was built to maniplulate bitmaps, able to do stretches, tesselations, rotations, layering and moving of arbitrary images to create the whole interface. It took a while to develop the library however it now allows for reasonably fast interface prototyping.

The author of Bristol is Nick Copeland. The program was first released in 2002 and remains under development to date, 2007. The project is in no way affiliated with any of the original manufacturers and the names and trademarks referred to here are sole property of their respective owners.

This page will cover a few aspects of the implementation that are not covered elsewhere - there is no manual available for Bristol for example, and although this page will not really be that manual it will give more information on implementation. As far as possible this will not cover the same material available on the project website and numerous references will be made back to the Bristol homepage hosted on SourceForge.

[edit] Bristol architecture

The application consists of two multithreaded programs, the audio engine and GUI. The engine uses 3 threads at different priorities, one to do the real time audio generation, a second one to respond to MIDI messages, and a third control process that does not really have much function other than being a rather unwatchful parent of the two other threads. In hindsight it would have been wiser to make this thread manage non-realtime MIDI events at low priority, and this may be encoded at a later date. The issue is that the engine can be quite intensive and needs to run at high priority to ensure that audio can be delivered in a timely fashion. This results in the MIDI thread having a lower priority, something that works quite well generally however it is possible to envisage some MIDI commands that should also be fielded with a high priority (note on/off) events for example, and others that are not quite so real time and can be potentially handled at a lower priority. Examples of these are the parameter controls from the GUI. Parameter changes are not executed by the audio thread, but by the MIDI thread, and consequently changes to any parameter - which can sometimes invoke quite intensive subroutines - will not affect the audio processing but can still delay sequential MIDI events.

The graphical user interface is another process entirely. This means that grapical operations will also not affect the audio process with suitable prioritisation. Consideration was given to the possibility to have a more typical single process multithreaded design where the GUI was just another thread of the same program. This would have been considerably easier to implement, at the expense of a small degree of as yet unused features - the ability to distribute the GUI and engine on totally different systems linked via any TCP network. Either way, even though the extra complexity of a networked solution was a challenge it was also fun to implement (the author is a networking technician) and the project had to be enjoyable and didactic to maintain interest. Quite large parts of the networking code were already available from even earlier network programming projects.

With the application consisting of two main components, the engine and GUI, it is noted that the single engine will emulate all the different keyboard simultaneously. It does this by accepting either multiple requests from a single GUI process (currently lacking a good interface specification), or alternatively accepting multiple TCP connections from different GUI. As such, the engine can run on one audio processing system and any number of users can connect to it to invoke emulations - it acts as an audio server.

Bristol Startup Options
Bristol Emulations
Bristol News

[edit] Engine architecture

The engine consists of several main components. There are the audio and MIDI libraries, the former implementing interfaces to OSS, ALSA and Jack for audio IO. The latter implements a raw midi interface, the ALSA SEQ interface and MIDI/TCP for the GUI connections. Inclusion of Jack MIDI is a likely development.

There is a base content of operators, these are the building blocks of each synth. There are about 4 different filter implementations, perhaps 10 different types of oscillators, a pair of envelopes and a variety of other component required by the different emulators - ring mods, amps, mixers, etc, and there is a set of effects that can be used by any emulation, reverb, rotary, chorus and such like.

After the libraries there is a control plane that is responsible for starting/stopping the emulations and receiving MIDI messages before passing those off to the operators or emulators. Each emulated keyboard has a buffer sequencing code that is responsible for signal and mod routing, passing buffers of data to the different operators for processing in the same order as the keyboard itself did.

The emulations are all bespoke, which is to say they were written to provide the capabilities of the original emulated keyboard - its not quite as flexible as csound where arbitrary connections can be built (see the Bristol ARP 2600 below, though). Even though the code for each synth is bespoke, that his not to say they necessarily sound accurate, they are an extraction of the original and bristol has always maintained that if you want to have the original sound then you probably need the original instrument. The website also references diverse OEM that have their own very respectable emulators that you can argue sound better than bristol, all for a respectable price, too, and very few, if any, available on Linux. Any single emulation consists of one or more synthesisers. Typically just one is needed however the dual manual Prophet-10, Oberheim OB-Xa, B3, and VOX 300 use two emulations, one for each manual - in these cases the GUI requests that the engine start two emulations on its behalf, specified which ones are required, and the GUI then manages them jointly from a single interface. Each synthesiser consists of a list of the audio operators and effects it will be using, a 'PreOps' code that is called just once per audio buffer, a 'Poly' code section that is called once for every key that is pressed, a 'PostOps' section called once per audio buffer after all the polyphonic notes have done their work. The final stage is for the engine to take a list of effects, which can be unique per emulator, and apply those effects to the net output of the emulation. This structure allowed for the relatively easy implementation of the Realistic MG-1, for example. This was a monophonic synth with a polyphonic organ divider circuitry: the monophonic synth was implemented in a mixure of pre and post ops, and the organ circuit in the poly code to emulate the design of the original instrument.

So, the engine is fully polyphonic. Each emulation is defined once and can be used many times - once per voice. For layering it is possible to put two emulations on the same MIDI channel. The engine can be started with a number of available voices, the default is 16 as it was the limit of one of my older development systems, however 24 or 32 would be a reasonable default and that may change presently. These 16 voices are the maximum number of simultaneous keys that can sound at the same time, however they are assigned dynamically which means the voice can become any of the emulations that has been started in the engine. At the same time there is a second limit that can be applied to an emulation, for example, when the Prophet-5 is started it requests just 5 voices as its own limit. The engine decides to start with 16 voices since that is its minimum, however it will never allocate more than 5 to this emulation so that it appears more like the original. The remaining voices are available for other simultaneous emulators. In the event that no free voices are available when a new key event is received then one is stolen from the active set. Preference is given to a voice from the existing emulation, and if a synth was started monophonically, ie, with just one available voice, it will be left alone and only be preempted by itself.

The engine is written totally in the C programming language.

The engine probably has four main emulation techniques:

[edit] Analogue emulation

Bristol ARP 2600
Bristol ARP 2600

The analogue emulations use all the different operators coded into the engine to provide a signal flow through each of them that conforms to the design of the original equipment. Since many of the operators are shared then many of the emulations sound rather similar - most of them use the same Chamberlain filter, the same envelope generator, etc. Having said that, many of the original instruments were also quite 'samey', the Korg Polysix competed with and had the same feature set as the Roland Juno-60 and they have a similar sound. The various Sequential Circuits Prophet synths competed against the Oberheim OB series, they even used the same chipsets (SSM and Curtis, depending on serial number) so the main differentiators between these were the mod routings that changed the way the sound was manipulated. Bristol maintains these mod routings for controlling the sound.

The most complex of the current emulations is undoubtably the ARP 2600 engine. The 2600 was a preconfigured synthesiser, just as the other emulations were, however it could be repatched to totally reorganise the signal flow through the synth and included voltage processes such as mixers, inverters, electro switches, lag processors to modify or distort signals. This is all emulated in the engine and a graphic is shown in the thumbnail. All the different sound sources deliver a signal into their own buffer space, and then all signal routing for inputs is done with pointers to these buffers. This means the patching basically comes for free, however the implementation of this synth required related alterations to the GUI to support the transparency layer required by the patch cables. Prior to implementing the ARP 2600 there was a freebie ARP Axxe and then an ARP Odyssey implementation. The Odyssey included some of the signal routing mechanisms later extended for the 2600.

[edit] Frequency Modulation

There is an emulation of the Yamaha DX7 frequency modulated synth. It implements an operator with its own envelope and wave generation, each taking numerous parameters, and then allows 6 of them to piped together in a selection of algorithms such that the output of one operator will define the frequency of the next one. There are better DX emulators available on Linux, some that even accept the original DX voice memory files. Bristol is a totally bespoke implementation that exacts an FM synthesis technique. The frequency modulation emuluation is also used for the two Rhodes electric pianos, much like the old Yamaha PF series.

[edit] Organ Circuitry

Bristol VOX Continental 300
Bristol VOX Continental 300

There are two families of organs and two main circuit variations emulated by Bristol. The organs are the Vox Continental and Hammond B3. The circuit variations are the ARP Solina string machine and Crumar RoadRunner electric piano - these both originally used organ divider circuitry with additional envelope support to modify the dynamics of the sound.

Bristol first implemented the VOX and Hammond really just as the analogue variations as described above. Each voice is a synthesiser with an oscillator, although in each case the oscillator was bespoke such that it emulated the drawbar characteristics. This method is used by a large number of hammond emulators, but it has a number of drawbacks that detract from the quality of the output. The Hammond B3 had a mechanical gearbox of toothed wheels (you can find plenty of references on the Wiki page) with electromagnetic pickups next to each tooth, and all were driven by the same motor. When this is emulated as a distinct set of voices then certain qualities are lost: there is no phase constant between the voices, there is no crosstalk between the wheels, and most significantly there is probably no waveform degenerations in any way similar to the different toothwheel designs as used in the mechanical gearbox, where different wheel designs produced different harmonic content.
To overcome this, to improve the emulation, the Bristol B3 has two emulation techniques, one is a set of synth voices, and the second is a monolithic gearbox that generates all 92 tonewheels and then taps them off for each drawbar bus and key. Selection between then is from the Preacher button in the options controls and in the later releases this has become the default - too many people complained that the sound was rather thin using the synthetic voicing, so emulating the gearbox became the default. The Preacher is a rather hefty lump of code as it runs all the time, irrespective of whether any given tonewheel is being used, but this allows some very exact crosstalk circuits to be programmed and constant phase relationships between the different wheels since even if a harmonic is used twice for different keys it is taken from the exact same source. It also implemented the not quite evenly tempered Hammond frequency scales that arose due to using cog wheels that have integral numbers of teeth hence cannot produce perfect frequencies. The preacher gearbox is controlled, or rather defined, by some configuration files that provide two completely different setups. Building the gearbox is quite intensive, so two of them are cached during initialisation of the algorithm and the selection between them is from the 'Bright' button on the interface. The gearbox parameters include all of the following:

  1. Waveform degenerations
  2. Tonewheel output signal strength
  3. Tonewheel frequency
  4. Compartment crosstalk
  5. Filter/Loom crosstalk
  6. Drawbar equalisation
  7. Drawbar gainstops
  8. Drawbar bus crosstalk
  9. Drawbar tapering resistor circuits
  10. Frequency division ET scale

All the above are defined individually per tonewheel, per compartment, per bus, etc, to extract a typically hammond sound. The waveform degenerations are used to emulate the toothwheel designs of the various tones and a per wheel frequency table caters for the very slightly offscale frequencies, caused by using integer division using cogwheels - both for the general gearbox and the wheels with 192 rather than 256 teeth separately. The default gearbox is quite clean and although the tonewheel equalisation is similar to the B3 box it is smoothed out over the keyboard by the corrective resistor tapering circuit. The bright selection increases the output signal of the higher frequency tonewheels, the gain of the higher harmonics using different drawbar EQ, adds in a bit more crosstalk, and degenerates the lower tonewheels to emphasise the 3rd and 5th harmonics, not by adding in the harmonics, rather by 'slicing' the tonewheel profile slightly differently.
There are several other pieces in the emulator of course. Key click is selective and uses a couple of different emulation algorithms, either per key or per drawbar bus. The Hammond chorus implements a phaseshifting filter scanned delay line as per the original, with a bypass for the percussive harmonics, a reverb unit is in the output effects chain, and a leslie emulator ends the signal path.
The Leslie emulation uses 2 independent rotations, separating the final signal with a Butterworth crossover filter into the bass and horn processors. The rotations use three differently phased stereo signal components to spread the sound. The three different components are direct signal variation by time, indirect (reverberating) signal variation by time, and signal aperture filtering by time. These signals vary over time with different phase shifts between the stereo channels. Add in a bit of overdrive and inertia between rotation speeds to add a bit more realism. It also emulates the various leslie modifications that are typically seen - independent rotations, synchronised rotation, and selective bass rotation. The Reverb control uses a separate set of feedback delay lines, independent of the Leslie code.

[edit] Granular processing

Granular processing is currently under development and was not available at the time of writing.

[edit] User interface architecture

Bristol Prophet-52
Bristol Prophet-52

The graphic user interface is defined in several main parts, those actually belonging to the emulation, those belonging to the Brighton graphics library and finally those of the X11 shim interface. These components in their entirety are known as brighton, the bristol graphics toolkit.

[edit] Brighton

The main part of the interface are the graphic designs specific to any of the keyboards. This is a piece of code that places requested textures (wood/metal, etc) onto the screen, places silkscreened blueprints of the text onto the layers, and then places the movable devices onto another layer. Internally to brighton there are extra unseen layers used for drop shadow and transparencies. The user interface then waits for callbacks from the brighton library when device values change and sends the changed values through to the engine using MIDI/TCP such that the engine will alter its emulated parameters.

A single page showing all the currently available interfaces can be found here.

What is not immediately obvious is that the images generated by brighton are composite, they are not complete pictures but rather a collage of images placed together to represent the finished piece. The backgrounds are created by panels whose content are textures - wood, metal, leather, etc, and whose foregrounds may have silkscreens (or blueprints) for text and then devices are placed over them, the devices themselves being manipulated images.

The interface supports different color qualities, the lower the quality the faster the interface, naturally, however since the brighton color cache code was added, a sorted list of buckets of sorted colors implemented in the 0.10 stream, the difference has flattened out since the color lookup rate is far higher. It supports antialiasing to smooth out the image, and they can be scaled however the results are subjective since the antialiasing is done after the image generation rather than before it, something that may change in a future release.

[edit] libbrighton

The brighton library implements a set of layers and devices that can be used to define an image of the original instrument and allow the components of the interface to be moved or manipulated by the mouse or other input device. The library takes XPM formatted bitmap files and renders them onto internal bitmap formats by scaling/stretching, tesselation/tiling, confined motion for sliders, rotation for potentiometers, and replacement for buttons. Sounds simple. Its not really that difficult, and it could be argued that bristol could have used any of numerous other existing toolkits rather than develop its own. The author maintains that writing his own graphics library was a load more fun than learning another one, and some of the features are simply not easily implemented in other tool kits, such as the patch cable transparency layer - this allows devices to overlay other devices whilst still be accessible. The transparency layer was also used for the Bristol Logo watermark that has since been dropped.

[edit] libB11

All the internal structures are proprietary to brighton, it does not rely on any X11 definitions. All the internal rendering and shadowing is onto privately formatted bitmaps, and then another library is called to render those onto the actual display - this is currently just the brightonB11 shim into X11 window system structures. The shim can use either X11 pixmap or XImage structures, the latter being considerably faster. The change from the initial pixmap to XImage implementation required no reorganisation of the brighton library due to it being separated from the actual windowing system, that was the main reason for using internal data structures. This does add a slight overhead however the simplicity of the internal structures allows for very fast pixel manipulation and the use of an ordered color cache maintains its speed. It is noted here that the initial implementation using the pixmap interface was slow, and during the 0.10 software stream this was all changed for performance enhancements.

[edit] See also

[edit] External links