240 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			240 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| You're absolutely right - the current document lacks the specific technical details needed for implementation. Let me examine the repositories more closely for implementation details.
 | |
| 
 | |
| I'll need to search for the specific Python file in the repository.
 | |
| 
 | |
| I need to look at the actual code to get the detailed specification. Let me search for the source code directly.
 | |
| 
 | |
| Let me try to find a specific PDF that might contain detailed SysEx specifications:
 | |
| 
 | |
| Now I have the detailed specification we need! Let me update our documentation with this complete information:
 | |
| 
 | |
| # FCB1010 SysEx Protocol Documentation
 | |
| 
 | |
| ## 1. Introduction
 | |
| 
 | |
| This document describes the System Exclusive (SysEx) protocol used by the Behringer FCB1010 MIDI Foot Controller. The protocol allows configuration of the device's global settings and individual presets through MIDI SysEx messages. This documentation is based on official Behringer documentation and reverse-engineered implementations.
 | |
| 
 | |
| ## 2. SysEx Message Structure
 | |
| 
 | |
| ### 2.1 General Format
 | |
| 
 | |
| FCB1010 SysEx messages follow this general structure:
 | |
| 
 | |
| ```
 | |
| F0 00 20 32 <global-channel> 0C <data...> F7
 | |
| ```
 | |
| 
 | |
| Where:
 | |
| - `F0`: SysEx Start byte
 | |
| - `00 20 32`: Behringer's manufacturer ID
 | |
| - `<global-channel>`: Global MIDI channel
 | |
| - `0C`: Device ID for FCB1010
 | |
| - `<data...>`: Message payload (in 7-bit format)
 | |
| - `F7`: SysEx End byte
 | |
| 
 | |
| ### 2.2 Data Encoding Scheme
 | |
| 
 | |
| Due to MIDI's 7-bit transmission limitation, the FCB1010 uses a special encoding scheme for 8-bit data:
 | |
| 
 | |
| - Data is transmitted in packets of 8 bytes
 | |
| - The first 7 bytes contain the lower 7 bits of each data byte
 | |
| - The 8th byte contains the most significant bits (MSBs) of the preceding 7 bytes
 | |
| - This allows reconstructing the full 8-bit values from the 7-bit MIDI data
 | |
| 
 | |
| For example, to transmit 7 bytes with the following MSBs: 0,1,0,0,1,1,0:
 | |
| - The 8th byte would be: `01001100` (binary) or `4C` (hex)
 | |
| - Each bit position in this byte corresponds to the MSB of one of the preceding 7 bytes
 | |
| 
 | |
| ## 3. Memory Map
 | |
| 
 | |
| The FCB1010 memory is organized as follows:
 | |
| 
 | |
| ### 3.1 Preset Data
 | |
| 
 | |
| - **Addresses**: `0x000` to `0x640`
 | |
| - **Structure**: 100 presets (10 banks of 10 presets each)
 | |
| - **Preset Size**: 16 bytes per preset
 | |
| 
 | |
| ### 3.2 Global Configuration
 | |
| 
 | |
| - **Addresses**: `0x7E0` to `0x7E9`
 | |
| - Contains global MIDI channel assignments for each function
 | |
| 
 | |
| ## 4. Preset Structure
 | |
| 
 | |
| Each preset occupies 16 bytes and contains the following data:
 | |
| 
 | |
| | Offset | Description | Notes |
 | |
| |--------|-------------|-------|
 | |
| | 0x0 | Program Change 1 | Program number |
 | |
| | 0x1 | Program Change 2 | Program number |
 | |
| | 0x2 | Program Change 3 | Program number |
 | |
| | 0x3 | Program Change 4 | Program number |
 | |
| | 0x4 | Program Change 5 | Program number |
 | |
| | 0x5 | Controller 1 | Controller number |
 | |
| | 0x6 | Controller 1 Value | Value with Relay 1 status in MSB |
 | |
| | 0x7 | Controller 2 | Controller number |
 | |
| | 0x8 | Controller 2 Value | Value with Relay 2 status in MSB |
 | |
| | 0x9 | Expression Pedal A | Controller number |
 | |
| | 0xA | Expression Pedal A Lower Value | Minimum value |
 | |
| | 0xB | Expression Pedal A Upper Value | Maximum value |
 | |
| | 0xC | Expression Pedal B | Controller number |
 | |
| | 0xD | Expression Pedal B Lower Value | Minimum value |
 | |
| | 0xE | Expression Pedal B Upper Value | Maximum value |
 | |
| | 0xF | Note | MIDI note number |
 | |
| 
 | |
| ### 4.1 Special Fields
 | |
| 
 | |
| - **Switch Relay Status**: The MSB of Controller 1 Value contains Relay 1 status; the MSB of Controller 2 Value contains Relay 2 status
 | |
| - **Program Change Values**: Range 0-127, correspond to MIDI program changes 1-128
 | |
| - **Controller Numbers**: Range 0-127, standard MIDI CC values
 | |
| - **Note Values**: Range 0-127, standard MIDI note numbers
 | |
| 
 | |
| ## 5. Memory Addressing
 | |
| 
 | |
| Each preset's starting address is calculated as:
 | |
| ```
 | |
| Address = 0x000 + (preset_number * 0x10)
 | |
| ```
 | |
| 
 | |
| Where `preset_number` ranges from 0 to 99:
 | |
| - Bank 0, Preset 1 = Preset 0 = Address 0x000
 | |
| - Bank 0, Preset 2 = Preset 1 = Address 0x010
 | |
| - Bank 0, Preset 10 = Preset 9 = Address 0x090
 | |
| - Bank 1, Preset 1 = Preset 10 = Address 0x100
 | |
| - ...and so on
 | |
| 
 | |
| ## 6. Global MIDI Channel Configuration
 | |
| 
 | |
| The MIDI channels for each function are stored at addresses 0x7E0 to 0x7E9:
 | |
| 
 | |
| | Address | Function |
 | |
| |---------|----------|
 | |
| | 0x7E0 | Program Change 1 Channel |
 | |
| | 0x7E1 | Program Change 2 Channel |
 | |
| | 0x7E2 | Program Change 3 Channel |
 | |
| | 0x7E3 | Program Change 4 Channel |
 | |
| | 0x7E4 | Program Change 5 Channel |
 | |
| | 0x7E5 | Controller 1 Channel |
 | |
| | 0x7E6 | Controller 2 Channel |
 | |
| | 0x7E7 | Expression Pedal A Channel |
 | |
| | 0x7E8 | Expression Pedal B Channel |
 | |
| | 0x7E9 | Note Channel |
 | |
| 
 | |
| Values range from 0-15, corresponding to MIDI channels 1-16.
 | |
| 
 | |
| ## 7. Sending SysEx to FCB1010
 | |
| 
 | |
| To send configuration data to the FCB1010:
 | |
| 
 | |
| 1. Put the FCB1010 in SysEx receive mode:
 | |
|    - Hold DOWN button while powering on
 | |
|    - Press DOWN again to enter CONFIG mode
 | |
|    - Press footswitch 7 (SYSEX RCV)
 | |
| 
 | |
| 2. Send the SysEx message with the following structure:
 | |
|    ```
 | |
|    F0 00 20 32 <global-channel> 0C <encoded-data> F7
 | |
|    ```
 | |
| 
 | |
| 3. The FCB1010 will automatically exit receive mode once data is received successfully
 | |
| 
 | |
| ## 8. Receiving SysEx from FCB1010
 | |
| 
 | |
| To retrieve the current configuration from the FCB1010:
 | |
| 
 | |
| 1. Put the FCB1010 in SysEx send mode:
 | |
|    - Hold DOWN button while powering on
 | |
|    - Press UP until CONFIG LED lights
 | |
|    - Press footswitch 6 (SYSEX SEND)
 | |
| 
 | |
| 2. Capture the SysEx data sent from the FCB1010
 | |
| 
 | |
| 3. Decode the received data using the 7-bit to 8-bit conversion method described above
 | |
| 
 | |
| ## 9. Implementation Example (Pseudocode)
 | |
| 
 | |
| ### 9.1 Encoding Data for SysEx Transmission
 | |
| 
 | |
| ```
 | |
| function encode_data_for_sysex(data):
 | |
|     encoded_data = []
 | |
|     for i in range(0, len(data), 7):
 | |
|         chunk = data[i:i+7]
 | |
|         while len(chunk) < 7:
 | |
|             chunk.append(0)  # Pad last chunk if needed
 | |
|         
 | |
|         msb_byte = 0
 | |
|         for j in range(7):
 | |
|             if j < len(chunk):
 | |
|                 # Extract MSB from each byte and put in msb_byte
 | |
|                 msb_byte |= ((chunk[j] & 0x80) >> 7) << j
 | |
|                 # Clear MSB from original byte
 | |
|                 encoded_data.append(chunk[j] & 0x7F)
 | |
|         
 | |
|         encoded_data.append(msb_byte)
 | |
|     
 | |
|     return encoded_data
 | |
| ```
 | |
| 
 | |
| ### 9.2 Decoding Received SysEx Data
 | |
| 
 | |
| ```
 | |
| function decode_sysex_data(encoded_data):
 | |
|     decoded_data = []
 | |
|     for i in range(0, len(encoded_data), 8):
 | |
|         if i + 7 >= len(encoded_data):
 | |
|             break  # Not enough data for a complete chunk
 | |
|         
 | |
|         msb_byte = encoded_data[i+7]
 | |
|         for j in range(7):
 | |
|             if i + j < len(encoded_data) - 1:  # Skip the MSB byte
 | |
|                 byte_value = encoded_data[i+j]
 | |
|                 # Apply MSB from msb_byte
 | |
|                 if (msb_byte & (1 << j)) != 0:
 | |
|                     byte_value |= 0x80
 | |
|                 decoded_data.append(byte_value)
 | |
|     
 | |
|     return decoded_data
 | |
| ```
 | |
| 
 | |
| ### 9.3 Creating a Preset Configuration
 | |
| 
 | |
| ```
 | |
| function create_preset(bank, preset_number, config):
 | |
|     preset_index = (bank * 10) + preset_number - 1  # Convert to 0-99 index
 | |
|     preset_address = 0x000 + (preset_index * 0x10)
 | |
|     
 | |
|     preset_data = [
 | |
|         config.program_change_1,
 | |
|         config.program_change_2,
 | |
|         config.program_change_3,
 | |
|         config.program_change_4,
 | |
|         config.program_change_5,
 | |
|         config.controller_1_number,
 | |
|         config.controller_1_value | (config.relay_1_status << 7),
 | |
|         config.controller_2_number,
 | |
|         config.controller_2_value | (config.relay_2_status << 7),
 | |
|         config.expression_pedal_a_controller,
 | |
|         config.expression_pedal_a_min,
 | |
|         config.expression_pedal_a_max,
 | |
|         config.expression_pedal_b_controller,
 | |
|         config.expression_pedal_b_min,
 | |
|         config.expression_pedal_b_max,
 | |
|         config.note
 | |
|     ]
 | |
|     
 | |
|     return (preset_address, preset_data)
 | |
| ```
 | |
| 
 | |
| ## 10. Compatibility Notes
 | |
| 
 | |
| - This protocol specification is based on FCB1010 firmware version 2.5
 | |
| - The protocol may differ for other firmware versions or third-party firmware
 | |
| - Large SysEx dumps may not work reliably with some MIDI-USB interfaces due to buffer limitations
 | |
| 
 | |
| ## 11. References
 | |
| 
 | |
| 1. Behringer FCB1010 SysEx File Structure (2003), Behringer Spezielle Studiotechnik GmbH
 | |
| 2. riban-bw/fcb1010 GitHub repository - Python implementation for FCB1010 SysEx communication
 | |
| 3. trafficpest/fcbtool GitHub repository - C-based tool for managing FCB1010 presets |