# Touch phone -> Studio turns on and starts recording

## AKA: One-Click Mobile Studio Automation

This page outlines the end-to-end architecture, API integration layers, OSC/Lua communication protocols, and execution plan for triggering studio power, booting the DAW host, instantiating timestamped Ardour sessions from templates, arming target tracks, and rolling transport from a single mobile button.

---

## 1. End-to-End Workflow & Pipeline Architecture

The objective is a zero-touch "Quick Record" pipeline: pressing a single button on a mobile phone (iOS Shortcut, Android Widget, Telegram Bot, or PWA) triggers an automated multi-stage turn-up sequence across the studio network.

```
+---------------------------------------------------------------------------------------------------+
| Mobile Phone (iOS / Android / PWA)                                                                |
| [ 🔴 ONE-TOUCH QUICK RECORD ]                                                                     |
+---------------------------------------------------------------------------------------------------+
                                                  | POST https://studio.drheck.dev/api/quick-record
                                                  v
+---------------------------------------------------------------------------------------------------+
| Host: ul (Gateway Orchestrator & Fastify/Python API Service)                                      |
| 1. Dispatches RF power turn-on command to pikvm-studio                                            |
| 2. Triggers ATX power / Wake-on-LAN for DAW host (bmo95)                                          |
| 3. Polls bmo95 SSH & RT audio stack until ready                                                   |
| 4. Dispatches Ardour project instantiation & OSC track arming commands                            |
| 5. Pushes confirmation webhook / notification to phone                                            |
+-----------------------------------|---------------------------------------|-----------------------+
                                    |                                       |
                   SSH Command      |                                       | SSH / OSC (Port 3819)
                                    v                                       v
+-----------------------------------------------+   +-----------------------------------------------+
| Host: pikvm-studio (Sub-GHz Transceiver)      |   | Host: bmo95 (DAW Host)                        |
| - Runs: sudo studio-power all on              |   | - Boots PREEMPT_RT kernel                     |
| - Engages YARD Stick One at 433.92 MHz        |   | - Auto-starts JACK + zita bridges             |
| - Powers: Rack, Monitors, Moroccan Lamp, LEDs |   | - Launches Ardour with Session Template       |
| - Pulses ATX power header via GPIO / Relay    |   | - Arms selected tracks via OSC UDP 3819       |
+-----------------------------------------------+   | - Rolls global recording transport            |
                                                    +-----------------------------------------------+
```

---

## 2. Technical Integration Layers

### Layer A: Studio Power & DAW Wakeup (`pikvm-studio`)

1. **RF Outlet Switching**:
   * API calls `pikvm-studio`: `sudo /usr/local/bin/studio-power all on` (switches the Moroccan Lamp, Recording Rack Gear, the Subwoofer, PA Monitors, the TV, and Neewer LEDs).
2. **DAW Host ATX Wake**:
   * `pikvm-studio` triggers the ATX power button on `bmo95` via PiKVM ATX header.

---

### Layer B: Audio Stack & Real-Time Engine Initialization (`bmo95`)

When `bmo95` boots, its systemd user units initialize audio backend:

```shell
# Auto-launched on bmo95 user session login:
$ systemctl --user start jack.service
$ systemctl --user start zita-a2j-blue.service zita-j2a-blue.service
$ systemctl --user start zita-a2j-green.service zita-j2a-green.service
$ systemctl --user start zita-a2j-yellow.service zita-j2a-yellow.service
$ ~/git/audio_config/profiles/jack-alsa/set-port-aliases.sh
```

---

### Layer C: Ardour Headless/GUI Instantiation

Ardour natively supports automated session creation from templates via CLI:

```shell
$ DISPLAY=:0 ardour9 \
    --no-splash \
    --no-announcements \
    --template "48ch_Studio_Master" \
    --new "/data/sessions/Session_$(date +%Y-%m-%d_%H%M%S)"
```

*   **`--template <name>`**: Clones track structures, input/output bus routing, plugin chains, and monitor matrices from a predefined master studio template.
*   **`--new <path>`**: Automatically creates and locks a timestamped project folder without interactive GUI dialogs.
*   **`--no-splash` & `--no-announcements`**: Suppresses startup modal windows that block automation.

---

### Layer D: Ardour Remote API Control (OSC & Lua)

Ardour provides two remote control APIs:

#### 1. Open Sound Control (OSC) — UDP Port 3819

Ardour includes a comprehensive built-in OSC server that can be queried and triggered over UDP.

| OSC Address | Arguments | Action |
| :--- | :--- | :--- |
| `/strip/recenable` | `i: strip_num`, `i: state (1/0)` | Arms or disarms a specific audio track |
| `/track/recenable` | `s: track_name`, `i: state (1/0)` | Arms or disarms track by name (e.g. `Red_01`) |
| `/rec_enable_toggle` | *(none)* | Toggles global master record arm status |
| `/transport_record` | `i: 1` | Sets global transport record arm to ON |
| `/transport_play` | `i: 1` | Rolls transport (starts playback/recording) |
| `/transport_stop` | `i: 1` | Stops transport |
| `/save_state` | *(none)* | Flushes and saves session XML to disk |
| `/access_action` | `s: "Action/Name"` | Executes any internal Ardour GUI menu action |

#### 2. Native Lua Scripting (`ardour-exec` / OSC `/eval`)

Ardour includes an embedded Lua execution engine. Complex automation scripts (e.g., auto-detecting connected microphones, verifying input levels, and arming only active channels) can be evaluated dynamically:

```lua
-- Lua script to arm all capture tracks matching prefix
for r in Session:get_routes():iter() do
    local track = r:to_track()
    if not track:is_null() and track:name():match("^Red_") then
        track:rec_enable_control():set_value(1, PBD.GroupControlDisposition.NoGroup)
    end
end
Session:maybe_enable_record()
Session:request_transport_speed(1.0, true, ARDOUR.TransportRequestSource.TRS_UI)
```

---

## 3. Implementation Plan & Execution Phases

The automation will be rolled out across 4 distinct phases:

### Phase 1: Ardour Template & OSC Server Configuration (`bmo95`)
* [ ] Create master 48-channel template (`48ch_Studio_Master`) with calibrated input routing (`Red_01..12`, `Blue_01..12`, `Green_01..12`, `Yellow_01..12`).
* [ ] Enable and persist Ardour OSC server on UDP port 3819 (`Preferences -> Control Surfaces -> Open Sound Control`).
* [ ] Build a Python helper script `/usr/local/bin/ardour-control` on `bmo95` using `python-osc` to test track arming, session saving, and transport control via CLI.

### Phase 2: Host Wakeup & Readiness Polling (`ul` & `pikvm-studio`)
* [ ] Configure Wake-on-LAN and PiKVM ATX power button trigger for `bmo95`.
* [ ] Write an orchestration wrapper script `/home/luke/bin/studio-quick-record` on `ul` that:
  1. Sends RF power command `sudo studio-power all on` to `pikvm-studio`.
  2. Sends ATX boot command to `bmo95`.
  3. Polls `ssh -q bmo95` until the PREEMPT_RT kernel is responsive (timeout: 45s).
  4. Confirms `jack.service` and all 3 `zita-a2j-*` duplex bridges are active.

### Phase 3: Automated Session Launch & Transport Trigger
* [ ] Extend `/home/luke/bin/studio-quick-record` to invoke Ardour session creation via SSH.
* [ ] Send OSC burst to arm user-selected tracks (e.g. Drums, Vocals, Master Stereo Bus).
* [ ] Roll recording transport and log initial take time.

### Phase 4: Mobile Webhook & UI Control Endpoint
* [ ] Deploy a lightweight authenticated REST service on `ul` (Fastify / Python Flask on dedicated ULA IP).
* [ ] Expose two endpoints behind Authentik OIDC single sign-on / API token:
  * `POST /api/studio/record/start`: Powers studio, boots host, opens session, arms tracks, rolls recording.
  * `POST /api/studio/record/stop`: Stops transport, saves session, optionally powers down.
* [ ] Configure iOS Shortcuts / Android Widget / Telegram Bot webhook for single-tap activation from any smartphone.

---

## 4. Python Ardour Remote Controller Reference

```python
#!/usr/bin/env python3
"""Ardour Remote Control Client via OSC (UDP 3819)"""

import sys, time
from pythonosc import udp_client

ARDOUR_IP = "127.0.0.1"
ARDOUR_PORT = 3819

def get_client(ip=ARDOUR_IP, port=ARDOUR_PORT):
    return udp_client.SimpleUDPClient(ip, port)

def start_recording(client, tracks_to_arm=[1, 2, 3, 4]):
    print("-> Arming tracks:", tracks_to_arm)
    for track_num in tracks_to_arm:
        client.send_message("/strip/recenable", [track_num, 1])
        time.sleep(0.05)
        
    print("-> Enabling global record arm...")
    client.send_message("/transport_record", 1)
    time.sleep(0.1)
    
    print("-> Rolling transport...")
    client.send_message("/transport_play", 1)
    print("-> Recording active.")

def stop_and_save(client):
    print("-> Stopping transport...")
    client.send_message("/transport_stop", 1)
    time.sleep(0.2)
    print("-> Saving session...")
    client.send_message("/save_state", [])
    print("-> Session saved successfully.")

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("Usage: ardour-control <start|stop|save>")
        sys.exit(1)
        
    c = get_client()
    cmd = sys.argv[1].lower()
    if cmd == "start":
        start_recording(c)
    elif cmd == "stop":
        stop_and_save(c)
    elif cmd == "save":
        c.send_message("/save_state", [])
```