KORG BLE MIDI Guide

Optimized settings and workarounds for KORG Module Pro and other BLE MIDI devices using MIDI-CI and Property Exchange.

Overview

KORG Module Pro is one of the few iOS apps that supports MIDI 2.0 Property Exchange over BLE MIDI. However, BLE MIDI has reliability challenges that require special handling.

Quick Start: Use the .korgBLEMIDI preset for automatic optimization.

let client = try MIDI2Client(name: "MyApp", preset: .korgBLEMIDI)

Compatibility Status

Tested operations with KORG Module Pro over BLE MIDI:

Operation Status Notes
Discovery Works Device discovery is reliable
DeviceInfo Works Single-chunk response, very reliable
ResourceList May timeout Multi-chunk response, BLE packet loss can cause issues
CMList (Programs) Works Direct access without ResourceList
GET/SET Works Use extended timeouts

The Problem

BLE MIDI has inherent reliability issues:

Solutions

1. Use the KORG Preset

The .korgBLEMIDI preset applies all recommended optimizations:

let client = try MIDI2Client(name: "MyApp", preset: .korgBLEMIDI)

This preset enables:

2. Manual Configuration

For fine-grained control:

var config = MIDI2ClientConfiguration()

// Extended timeout for BLE latency
config.peTimeout = .seconds(10)

// Warm-up helps stabilize BLE connection
config.warmUpBeforeResourceList = true

// More retries for BLE reliability
config.maxRetries = 3
config.retryDelay = .milliseconds(500)

// Lower concurrent requests to reduce BLE load
config.maxInflightPerDevice = 1

let client = try MIDI2Client(name: "MyApp", configuration: config)

3. Skip ResourceList

If ResourceList times out, you can access known resources directly:

// Instead of fetching ResourceList first...
// let resources = try await device.resourceList

// Access known KORG resources directly
let programs = try await client.get("CMList", from: device.muid)
let deviceInfo = try await client.getDeviceInfo(from: device.muid)

4. Implement Fallback Logic

func getResourcesSafely(device: MIDI2Device, client: MIDI2Client) async throws -> [ResourceListEntry] {
    do {
        // Try ResourceList first
        return try await device.resourceList
    } catch MIDI2Error.deviceNotResponding {
        // Fallback: return known KORG resources
        print("ResourceList timed out, using known resources")
        return [
            ResourceListEntry(resource: "DeviceInfo", canGet: true),
            ResourceListEntry(resource: "CMList", canGet: true),
            ResourceListEntry(resource: "ProgramList", canGet: true)
        ]
    }
}

Warm-Up Mechanism

The warm-up feature sends a small single-chunk request (DeviceInfo) before attempting ResourceList. This helps:

// Warm-up is automatic with the preset, but you can also do it manually:
_ = try await client.getDeviceInfo(from: device.muid)  // Warm-up
let resources = try await client.getResourceList(from: device.muid)  // More likely to succeed

Diagnostics

When debugging BLE MIDI issues, use the diagnostics API:

let diag = await client.diagnostics

// Check which destination was used
print("Destination: \(diag.lastDestinationDiagnostics)")

// Check communication trace
print("Trace: \(diag.lastCommunicationTrace)")

Known KORG Resources

Common Property Exchange resources available on KORG Module Pro:

Resource Description GET SET
DeviceInfoDevice informationYesNo
ResourceListAvailable resourcesYesNo
CMListChannel/Program mappingYesYes
ProgramListAvailable programsYesNo
ChConfigListChannel configurationYesYes

Best Practices

Summary:

  1. Always use the preset for KORG BLE MIDI devices
  2. Cache aggressively — MIDI2Device caches DeviceInfo and ResourceList automatically
  3. Handle timeouts gracefully — provide fallback behavior
  4. Minimize concurrent requests — keep maxInflightPerDevice low
  5. Use warm-up — it significantly improves reliability
  6. Access known resources directly — skip ResourceList if it's problematic