5.6 KiB
		
	
	
	
	
	
	
	
			
		
		
	
	
			5.6 KiB
		
	
	
	
	
	
	
	
FCB1010 Looper Pedal - Interface Specification
System Architecture Overview
graph TD
    FCB1010[FCB1010 MIDI Controller]
    UMC404HD[UMC404HD Audio Interface]
    JACK_MIDI[JACK MIDI]
    JACK_AUDIO[JACK Audio]
    AudioEngine[Audio Engine Process]
    Display[Display Process]
    FCB1010 <-->|MIDI DIN| UMC404HD
    UMC404HD <-->|MIDI USB| JACK_MIDI
    UMC404HD <-->|Audio USB| JACK_AUDIO
    JACK_MIDI -->|CC messages| AudioEngine
    AudioEngine -->|MIDI Clock/Click| JACK_MIDI
    JACK_AUDIO <-->|Audio Data| AudioEngine
    AudioEngine -->|OSC Unix Socket| Display
    
    subgraph "Hardware"
        FCB1010
        UMC404HD
    end
    
    subgraph "Software"
        JACK_MIDI
        JACK_AUDIO
        AudioEngine
        Display
    end
MIDI Interface
Input: FCB1010 → Audio Engine
Button Mappings (State-Independent)
Button 1:   CC #20  (Record/Arm / Tap Tempo)
Button 2:   CC #21  (Play/Mute Track / Click Toggle)  
Button 3:   CC #22  (Solo Track)  
Button 4:   CC #23  (Overdub)
Button 5:   CC #24  (Clear Track / Clear Column)
Button 6:   CC #25  (Column 1 Select)
Button 7:   CC #26  (Column 2 Select)
Button 8:   CC #27  (Column 3 Select)
Button 9:   CC #28  (Column 4 Select)
Button 10:  CC #29  (Column 5 Select)
UP:         CC #30  (Row Up / Mode Switch)
DOWN:       CC #31  (Row Down / Mode Switch)
Expression Pedals
Expression A: CC #1 (Track Volume / Click Volume)
Expression B: CC #7 (Master Volume)
Note: FCB1010 sends identical CC messages regardless of current system state. The Audio Engine interprets these based on its internal mode (Menu vs Performance).
Output: Audio Engine → External Devices
MIDI Clock (Continuous)
Clock (F8H): 24 PPQN, sent continuously while application running
Transport Control
Start (FAH): When any column starts from all-stopped state
Stop (FCH):  When all columns stop
Song Position Pointer
SPP (F2H): Reset to 0 on Start message
           Increments during playback
           Stops incrementing on Stop message
           1 MIDI beat = 6 MIDI clocks = 1/4 quarter note
OSC Interface (Audio Engine → Display)
Transport: Unix Domain Socket
- Protocol: OSC 1.0 over SLIP-encoded stream
- Direction: Unidirectional (Audio Engine → Display only)
Message Categories
1. System State Messages
/looper/mode <string>
   Values: "menu" | "performance"
   Update frequency: On change only
/looper/tempo <float>
   Range: 50.0 - 200.0 BPM
   Update frequency: On change only
/looper/click/enabled <int>
   Values: 0 (disabled) | 1 (enabled)
   Update frequency: On change only
/looper/click/volume <float>
   Range: 0.0 - 1.0
   Update frequency: On expression pedal change
/looper/master/volume <float>
   Range: 0.0 - 1.0
   Update frequency: On expression pedal change
2. Navigation State Messages
/looper/selected/column <int>
   Range: 1-5
   Update frequency: On change only
/looper/selected/row <int>
   Range: 1-5
   Update frequency: On change only
3. Matrix Cell State Messages
/looper/cell/<column>/<row>/state <string>
   Column: 1-5, Row: 1-5
   Values: "empty" | "loading" | "ready" | "recording" | "playing" | "solo"
   Update frequency: On change only
/looper/cell/<column>/<row>/volume <float>
   Column: 1-5, Row: 1-5
   Range: 0.0 - 1.0
   Update frequency: On change only
4. Column State Messages
/looper/column/<column>/beats <int>
   Column: 1-5
   Value: Number of beats in column (set by first recording, 0 = not set)
   Update frequency: On first recording in column
/looper/column/<column>/beat <int>
   Column: 1-5
   Value: Current beat (1 = start of loop, 1+ = beat N)
   Update frequency: On change
5. Metronome Messages
/looper/metronome/position <float>
   Range: 0.0 - 1.0 (position within current beat)
   Update frequency: same as PPQN midi signal
OSC Implementation Details
Initial State Synchronization
OSC is stateless - there's no "subscription" mechanism. When the display process connects:
- Display connects to Unix socket
- Audio engine detects new connection
- Complete state dump sent immediately:
- Regular updates begin (position updates, state changes)
OSC Message Bundling
For efficiency, column-beat messages are bundled:
Session Persistence
Single Source of Truth
- Timing authority: samples_per_beatin state.json
- Track existence: WAV file presence in filesystem
- Tempo: Derived from (sample_rate × 60) ÷ samples_per_beat
- Column beats: Derived from wav_length_samples ÷ samples_per_beat
- Delete files:
- If it's not a multiple of samples_per_beat
- If it doesn't match the sample rate
- When a track is cleared
 
- If it's not a multiple of 
Auto-Save Triggers
- Track data changes (record/clear)
- Tempo/timing changes
- Volume adjustments (when constant for 5 seconds)
- Application shutdown
Directory Structure
~/.fcb_looper/
   ├── state.json        # System state and timing authority
   ├── col_1_row_1.wav   # Audio tracks
   ├── col_1_row_2.wav
   └── ...
State File Format
{
  "version": "1.0",
  "connections": {
   "midi_in": [
      "sendmidi:midi_out"
   ],
   "audio_out": [
   ],
   "audio_in": [
   ]
  },
  "ui_state": {
    "selected_column": 3,
    "selected_row": 2
  },
  "user_preferences": {
    "click_enabled": true,
    "click_volume": 0.5,
    "master_volume": 0.8
  },
  "track_volumes": {
    "col_1_row_1": 0.75,
    "col_2_row_3": 0.9
  },
  "timing": {
    "sample_rate": 44100,
    "samples_per_beat": 105840,
  }
}