Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

osmid is a lightweight, portable tool for converting between MIDI and OSC (Open Sound Control) protocols. It consists of two main executables:
- `m2o`: MIDI to OSC conversion
- `o2m`: OSC to MIDI conversion

The project is built with C++14 and uses CMake as the build system. It's used as the MIDI communication layer in Sonic Pi.

## Build Commands

### Initial Build Setup
```bash
mkdir build
cd build
cmake ..
make
```

### Platform-Specific Build
- **Windows**: `cmake -G "Visual Studio 16 2019" -A x64 ..`
- **Linux/Mac**: `cmake ..` then `make`

### Code Quality Checks
- **Whitespace check**: `python utils/check_whitespace.py` (checks for trailing whitespace and tab indentation)

## Architecture

### Core Components
- **src/m2o.cpp**: Main entry point for MIDI-to-OSC converter
- **src/o2m.cpp**: Main entry point for OSC-to-MIDI converter
- **src/midicommon.h/.cpp**: Base class for MIDI device management with sticky ID system
- **src/midiin.h/.cpp**: MIDI input device wrapper using JUCE
- **src/midiout.h/.cpp**: MIDI output device wrapper using JUCE
- **src/oscin.h/.cpp**: OSC input handling using oscpack
- **src/oscout.h/.cpp**: OSC output handling using oscpack
- **src/midiinprocessor.h/.cpp**: Processes incoming MIDI and converts to OSC
- **src/oscinprocessor.h/.cpp**: Processes incoming OSC and converts to MIDI
- **src/monitorlogger.h**: Singleton logger that can output to both console and OSC
- **src/utils.h/.cpp**: String utilities for OSC address formatting

### Key Design Patterns
- **Sticky ID System**: MIDI devices maintain consistent IDs across disconnections/reconnections via MidiCommon base class
- **Template-based OSC Addressing**: Customizable OSC address patterns using variables like $n (port name), $i (port id), $c (channel), $m (message type)
- **Singleton Logger**: MonitorLogger provides centralized logging to both console and OSC destinations
- **Processor Pattern**: Separate processor classes handle the conversion logic between MIDI and OSC

### Dependencies (all included in tree)
- **JUCE**: Cross-platform audio/MIDI framework (JuceLibraryCode/)
- **oscpack**: OSC message handling and UDP networking (external_libs/oscpack_1_1_0/)
- **spdlog**: Fast logging library (external_libs/spdlog-0.11.0/)
- **cxxopts**: Command-line option parsing (external_libs/cxxopts/)

### Platform Support
- Windows (MSVC 2015+)
- Linux (gcc 4.9+, requires ALSA)
- macOS (clang 5.1+)

## Development Notes

### Code Style
- Uses spaces for indentation (no tabs)
- No trailing whitespace
- C++14 standard
- Headers use `#pragma once`

### Testing
- No formal test suite for the main application
- External libraries include their own tests
- Manual testing via MIDI device interaction and OSC message monitoring

### Logging Levels
0-6 scale where smaller numbers = more verbose output

### Version Management
Version numbers defined in src/version.h (currently 0.8.0)
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
cmake_minimum_required (VERSION 3.5)
project (osmid)
cmake_minimum_required (VERSION 3.0)

set(CMAKE_VERBOSE_MAKEFILE ON)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ static inline ReturnValue ObjCMsgSendSuper (struct objc_super* s, SEL sel, Param
typedef id (*MsgSendSuperFn) (struct objc_super*, SEL, ...);
static inline MsgSendSuperFn getMsgSendSuperFn() noexcept { return (MsgSendSuperFn) (void*) objc_msgSendSuper; }

#if ! JUCE_IOS
#if ! JUCE_IOS && ! defined(MAC_OS_VERSION_11_0)
typedef double (*MsgSendFPRetFn) (id, SEL op, ...);
static inline MsgSendFPRetFn getMsgSendFPRetFn() noexcept { return (MsgSendFPRetFn) (void*) objc_msgSend_fpret; }
#endif
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ For build instruction see INSTALL.md.
osmid is built using C++14 features. The build system is based on cmake. Tested target compiler in Windows is MSVC 2015 Win64, in Linux is gcc 4.9 or later, and on Mac, clang 5.1
or later. Under Windows, prepare using something like: `cmake -G "Visual Studio 16 2019" -A x64 .. `. On Linux and Mac `cmake ..` should be enough.

**Note for macOS users**: The CMake minimum version has been updated to 3.5 to support modern macOS builds. Additionally, a fix has been applied to handle the removal of `objc_msgSend_fpret` in newer macOS SDKs.

osmid uses the following libs:
* JUCE for the midi handling and OSC handling (included in the tree)
* oscpack, for the OSC handling and UDP networking (included in the tree)
Expand Down
2 changes: 1 addition & 1 deletion external_libs/oscpack_1_1_0/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 2.6)
cmake_minimum_required(VERSION 3.5)
PROJECT(TestOscpack)

INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR})
Expand Down
7 changes: 6 additions & 1 deletion src/midiinprocessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,12 @@ void MidiInProcessor::handleIncomingMidiMessage(MidiInput* source, const juce::M
break;

case 0x90:
message_type = "note_on";
// Note-on with velocity 0 should be treated as note-off
if (nBytes == 3 && message[2] == 0) {
message_type = "note_off";
} else {
message_type = "note_on";
}
assert(nBytes == 3);
break;

Expand Down