A Closer Look At Console Configurations
In this section, we will actually break apart an in-service config file and look at each line, one line at a time. It will be explained, and anything that can be changed will also be explained.
Common Opening Header Statements
Header statements change things (controls, features) from their default value to the value you would like. They generally could appear anywhere in the files, but putting them in the header ensures that the changes are applied as soon as possible.
Opus_Remote = low Opus_Remotes = high
Mostly self explanatory. First line indicates that this is NOT a chamber and does not need to receive supporting data/material from other controllers to function. Second line indicates that it needs to generate said data so that other controllers can be synchronized with it and receive the data that is read here.
comb_mem_bytes = 13 pistons_per_level = 80 combination_action = high Opus_uSD_card ( 8 )
All combinations and internal sequencer data is stored in an external memory module. Have a memory map set up ahead of time assures that the system always looks in the same spot for the same thing. Adequate preparation at this stage for the size of the instrument (including any future additions) is critical to making sure organists NEVER lose combinations.
The comb_mem_bytes is determining how many bytes should be set aside for each piston on each memory level. This is important to get right the first time – a byte holds 8 bits (or stops). There is no shortage of memory – the combination actions are stored on the external SmartMedia or uSD card (lots of room). Make this big enough that you never have to change it again. If an organ has 35 stops, the number needs to be at least 5 (35 / 8 = 4.something). On a 35 stop organ with no anticipated growth, it would be appropriate to make it at least 8. This allows for storage of the state of any under the hood features that are created later that require memory storage, or any stop expansions.
pistons_per_level is the same sort of thing as comb_mem_bytes where you never want to guess too low. A common way is to count the amount of room for pistons, so that if any are added later, space is allowed for them. These do not take up much memory, and any reformatting of either of these two variables later will make pistons above memory level 1 scramble. If an organ has 10 generals and 5 divisionals on each of 3 divisions, that is a total of 25 pistons (coupler reversables and the like do not count).
combination_action = high is merely activating the routines that store and process piston presses. Without this (or with it set to =low), pressing pistons will not move any stops. This mode can be helpful when trying to get a console up and running.
opus_uSD_card tells the config how big the card is (leave at 8)
piston_transposing = high
This (when high) allows transposer settings to be stored with pistons. This setting defaults to low/off.
use_new_display ( high )
There are two types of displays that have been used on Opus-Two systems, one of which has a rather large backplane board (with built in control buttons), and the other has a thin backplane board and wiring headers for pistons. use_new_display is for the thin backplane board. The (high) determines whether the piston inputs are read from the backplane board or not.
crescendo_enable = low
As it appears, this line enables or disables the crescendo. It will still appear on the display if it is disabled, but will not function.
use_reits = low
When high, enables a special menu to adjust reit timer values.
use_digital_tuning = low
When high, enables a special menu to enable fine tuning of Hauptwerk digital voices.
use_midi_selects = low
When high, enables a special menu to select MIDI voices for an external expander.
Common Modifications To Home Screen
if ! lvl_up_dn then show_transposer = high else show_transposer = low end if
Hides the transposer unless it is active.
if cresc_step == 0 then show_cres_step = low else show_cres_step = high end if
Hides the crescendo indicator unless the crescendo is activated.
Reading Input Cards
card_in ( 1 , 0 ) card_in ( 2 , 0 ) card_in ( 3 , 0 ) card_in ( 4 , 0 ) card_in ( 5 , 0 ) card_in ( 6 , 0 )
The controller needs to know how many input cards are connected. Some O2 controllers have two different ports on them, which is why there are two columns of numbers here. The most commonly used C-I controller only has one port, so we only have one set of numbers. Simply add or delete lines and number them appropriately. The data is moved from the input cards to buffers named for this purpose and can be moved to final destinations any time prior to the first coupler.
Mapping, Moving, and Manipulating Data
There are a number of ways to move data, either in large groups, or individual bits. Think of this as cutting and pasting, or copying and pasting:
map ( 4 , 1 , 61 , Swell )
map ( card_number , pin , # , destination ) - This example will copy data from card 4, pins 1-61 to the Swell keying buffer. The # variable is not the last pin to move, but the number of bits to move so…
map ( 4 , 17 , 32 , Pedals )
…would move pins 17-48 to the Pedal Keying buffer.
Map_fragment_merge ( 5 , 49 , 8 , Pistons , 17 )
map_fragment_merge ( card_number , pin , # , destination_buffer , destination_starting_pin )
This example would allow to you move (in one command) pins 49-56 from card 5 to Pistons 17-24. Map_fragment_merge and map are similar, but map_fragment_merge allows the selection of where the data is pasted, as opposed to map, which always starts pasting at the beginning of the buffer. The pasted data is MERGED with the data that was there, and does NOT overwrite it (this is the other key difference).
Swell & Crescendo Analog Inputs & Rollers
There are four common ways to interface with a swell shoe:
- Reuse an existing roller contact assembly
- Install an Opus-Two Expression Pedal Sensor, mount a magnet to a moving part of the shoe, and measure it using the sensor.
- Install a linear transducer or potentiometer assembly and wire it to an Expression Pedal Sensor (each sensor can accept up to two external analog inputs).
- Connect a new swell shoe (such as a Walker shoe) to an Expression pedal sensors analog input.
Connect the roller contacts (in order ideally) to an input card. For the sake of discussion, we are going to assume that the roller is 12 stages and is connected to Input Card #6, Pins 25-36. We will also assume that we want to put the resulting value in exprb2.
convert_roller_values ( 6 , 25 , 12 , exprb2 )
Opus-Two Expression Pedal Sensor Interfaces
To read data from a pedal sensor card, first you need to initialize it. The initialization string includes a number of variables. Because these are essentially pedal contact sensors, and they work essentially the same way, we identify these as sensor #33 and up (sensors 1-32 can be connected to read pedal key status). The sensor values are read in pairs, sensor number, and then which input on the sensor card ( input 0 is Analog #2, input 1 is Analog #1, input 3 is the hall effect sensor). The initialization string allows for the reading of 6 unique values. As a matter of interest, only two values can be read from any single sensor card (not all three). The initialization string looks like this:
Set_Pedal_Sensor_Options_num_lin ( 33 , 0 , 33 , 1 , 34 , 0 , 34 , 1 , 0 , 0 , 0 , 0 )
When encountering this line, the system polls the sensors listed and reads the values specified for each sensor. The first value requested is stored as Analog #1 (internally), second as Analog #2, etc.
Now the analog values that have been read in need some housekeeping administered. Analog values can “flicker” (jump between two adjacent values), so that needs to be prevented. Its also helpful to analyze the range of the inputs and “expand” (or compress) them to fully accommodate 7 bit MIDI-compatible values. Lastly, we will set a “zero value” for the control, so that when the shoe is closed, the result is “0″ even if the shoe is reporting back a larger number.
For the example, we will read in Analog #1 (from above), scrub a value of 8 off to zero it, not let it go higher than 112, apply a corrective value of 150, store a reference value in saved_swell, and put the processed result in exprb1:
analog_expr ( 1 , 8 , 112 , 150 , saved_swell , exprb1 )
What this actually does is:
- Looks at the value that was read in from the Sensor Card and copies it to memory.
- Checks if that value is 8 or less, in which case, it declares it to be 0. If it’s higher than 8, it subtracts 8 from it (this prevents the first step from jumping from “0″ to “9″).
- Checks to see if it is at or above 112, and if it is, sets it to 112.
- Expands it by applying this formula: ( value * 150 ) / 128 … so essentially multiplying the value by 1.172.
- It then compares it to the last value (from the previous pass). If it is different, it determines the “half way” point between the last value and this new value, and that is where exprb1 is set. That value is then saved into saved_swell so that next pass it can be read for comparison.
The only thing that ISN’T explained here is where the values of 8, 112, and 150 came from. Using the cmn-mem screens, scroll up until Analogs are displayed. This screen allows the user to see the raw analog sensor values (untouched by any procedures). In this case, when the shoe was closed all the way, the display showed “08″ for that first sensor. If had shown “0A”, the value would be 9. When the shoe was open all the way, the display indicated the value at “70″. (fun fact – google will convert hex to decimal and back with the proper terms – try searching for “0×70 to decimal“). The hard part is determining the 150. Take the max value, subtract the minimum value from it. This is the total range of values from the shoe (104 in this case). Multiply this range by 1.44 if it is LESS than 125. If it is between 125 and 128, set the value to 128. If it is between 128 and 256, multiply the range by [unfinished]
Getting Into Combination Action
-- Ch 1 Ch 2 Ch 3 Ch 4 Ch 5 Bit_map ( pstnb3 , In4_45 , In4_46 , In4_47 , In4_48 , In4_49 , -- Ch 6 Ch 7 Ch 8 In4_50 , In4_51 , In4_52 )
Bit_map ( byte , bit_1 , bit_2 , bit_3 , bit_4 , bit_5 , bit_6 , bit_7 , bit_8 )
This enables pistons to be arranged logically. Also enables individual pistons to be put in correct locations so that certain things work out (moving pistons with manual transfers, etc.). Bit_map isn’t just for pistons though, mis wired keyboards, stop rails, etc. can be easily mapped that way.
If the pistons are wired in the correct order* then the data can moved en mass using map or map_fragment_merge to the Pistons buffer.* Eventually this has to be addressed: The first 10 general pistons should end up in the first 10 bits of the pistons buffer. This allows the “quick dial” feature for memory level selection to work properly.
At some point, we need to locate the set and cancel pistons with a bit_map:
-- Display Control mapping from external buttons -- Trns Trk Rec Play Up Dn Cncl Set Bit_map ( dsply_ctrl , low , low , low , low , low , low , In2_43 , In2_57 )
And now to look at a reversible control:
east_coast_coupler ( in2_53 , 53 , 52 , 54 , 0 ) -- s/g
The east_coast_coupler watches for the button to be pressed, and does this:
- Check to see if any of the stops are on (in this case 52, 53, or 54). If they are, it turns them off.
- If no stops are on when the button is pressed, it turns on the first stop. Only the first stop will ever be turned on by this procedure, the rest only turn off.
Another type of reversible is:
reversable_tab ( in2_53 , stop_53 , 53 )
This will toggle stop 53 on or off each tie in2_53 is pressed.