commit 3dc4f0b7f7b42a200b736b78e3181f3bf4ce46a2 Author: Sylvain Schneider Date: Sat Jun 13 00:41:01 2026 +0200 initial commit diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..4b659bf --- /dev/null +++ b/.clang-format @@ -0,0 +1,37 @@ +ο»Ώ--- +# This configuration requires clang-format 3.8 or higher. +Language: Cpp +BasedOnStyle: Mozilla +AlwaysBreakAfterReturnType: None +AlwaysBreakAfterDefinitionReturnType: None +BreakConstructorInitializersBeforeComma: false +AccessModifierOffset: '0' +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: 'true' +AlignConsecutiveDeclarations: 'true' +AlignEscapedNewlines: Left +AlignOperands: 'true' +AlignTrailingComments: 'true' +AllowAllParametersOfDeclarationOnNextLine: 'false' +AllowShortCaseLabelsOnASingleLine: 'false' +AllowShortFunctionsOnASingleLine: Empty +AllowShortLoopsOnASingleLine: 'false' +AlwaysBreakBeforeMultilineStrings: 'false' +BreakBeforeBraces: Allman +BreakBeforeTernaryOperators: 'true' +ColumnLimit: '0' +FixNamespaceComments: 'true' +IncludeBlocks: Regroup +IndentCaseLabels: 'true' +IndentPPDirectives: AfterHash +IndentWidth: '2' +NamespaceIndentation: None +PointerAlignment: Right +ReflowComments: 'true' +SortIncludes: 'true' +SortUsingDeclarations: 'true' +SpacesBeforeTrailingComments: 5 +TabWidth: '2' +UseTab: Never + +... diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a7549ef --- /dev/null +++ b/.gitignore @@ -0,0 +1,95 @@ +# ---> C +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Kernel Module Compile Results +*.mod* +*.cmd +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf + +# ---> C++ +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# ---> Environment +# Executables +build/ +*.exe +*.out +*.app + +# Editor's mess +.vscode/ +.vs/ +*/.idea/copilot* + diff --git a/README.md b/README.md new file mode 100644 index 0000000..ea8fb5b --- /dev/null +++ b/README.md @@ -0,0 +1,85 @@ +# volaTileMidi 🎹✨ + +A high-performance, cross-platform MIDI visualizer and interactive piano trainer written in modern C++. + +The name is a geeky nod to the C++ `volatile` keyword and the smooth, cascading visual notes (**vola-Tile**) that stream down to your keyboard. It connects directly to your USB MIDI piano to offer real-time interaction with zero perceived latency. + +--- + +## πŸš€ Features + +* **Real-time MIDI Input:** Connects to any USB/Midi keyboard instantly using `RtMidi`. +* **Lock-Free Architecture:** Uses a custom Single-Producer Single-Consumer (SPSC) lock-free ring buffer to forward MIDI events from the driver thread to the main loop without blocking or stuttering. +* **Modern 2D Rendering:** Powered by `SDL3` leveraging GPU acceleration for perfectly smooth rendering at high refresh rates. +* **Accurate MIDI Parsing:** Pre-calculates MIDI track events from `.mid` files using `libremidi`, converting native MIDI ticks into absolute time seconds while fully respecting mid-song tempo changes. +* **Resolution Independent:** Uses a logical rendering viewport size ensuring the falling tiles and keyboard stay perfectly proportioned regardless of your window size or monitor aspect ratio. +* **Cross-Platform:** Built from the ground up to compile and run natively on both **Windows** and **Linux** (ALSA/PipeWire). + +--- + +## πŸ› οΈ Tech Stack & Dependencies + +* **Language:** Modern C++ (C++20 recommended) +* **Build System:** CMake +* **Windowing & Graphics:** [SDL3](https://github.com/libsdl-org/SDL) +* **MIDI I/O:** [RtMidi](https://github.com/garyscavone/rtmidi) +* **MIDI File Parsing:** [libremidi](https://github.com/jcelerier/libremidi) + +--- + +## πŸ—οΈ Architecture Architecture Overview + +The core design centers around a `CoreManager` class that orchestrates the engine lifecycle, ensuring a strict separation between hardware input, logic updates, and presentation: + +``` +[ USB Piano Input ] ──> (RtMidi Driver Thread / Lambda) +β”‚ +[ SpscMidiQueue (Lock-Free) ] +β”‚ +β–Ό +[ SDL3 Main Loop ] ──> CoreManager::update() ──> CoreManager::render() +``` + +1. **Hardware Thread:** `RtMidi` captures key presses via a low-overhead driver callback. It instantly pushes lightweight events into the lock-free queue. +2. **Main Loop Thread:** The `CoreManager` pumps OS events, consumes all pending live MIDI events, updates the scrolling timeline based on a precise delta time, and renders the active shapes to the screen. + +--- + +## πŸ“¦ Building from Source + +### Prerequisites + +Make sure you have a C++20 compliant compiler, CMake, and the necessary development packages installed. + +#### On Linux (Ubuntu/Debian example): +```bash +sudo apt update +sudo apt install build-essential cmake libasound2-dev libjack-jackd2-dev +# Install SDL3 from source or repository when fully available on your distro +``` + +# Clone the repository +git clone [https://github.com/yourusername/volaTileMidi.git](https://github.com/yourusername/volaTileMidi.git) +cd volaTileMidi + +# Configure CMake +cmake -B build -DCMAKE_BUILD_TYPE=Release + +# Build the project +cmake --build build --config Release + +πŸ—ΊοΈ Roadmap / Todo +[ ] Initialize SDL3 window context and abstract coordinate system viewport. + +[ ] Implement the SpscMidiQueue lock-free ring buffer. + +[ ] Bind RtMidi with a non-capturing lambda callback forwarding to CoreManager. + +[ ] Render the basic 88-key static virtual keyboard. + +[ ] Integrate libremidi parser for absolute timeline conversion (Ticks βž” Seconds). + +[ ] Implement the interactive "Practice Mode" where the scrolling pauses until the correct key is pressed. + +πŸ“„ License +This project is open-source. Feel free to use, modify, and distribute it as you see fit.