{"id":49320895,"url":"https://github.com/ku6dra/dmsynth","last_synced_at":"2026-04-26T18:00:28.376Z","repository":{"id":353995457,"uuid":"1211629931","full_name":"ku6dra/dmsynth","owner":"ku6dra","description":"A lightweight MIDI synthesizer for Windows using DirectMusic","archived":false,"fork":false,"pushed_at":"2026-04-26T16:03:43.000Z","size":50,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-04-26T17:26:29.793Z","etag":null,"topics":["directmusic","midi","windows"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ku6dra.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-15T15:29:43.000Z","updated_at":"2026-04-26T15:51:22.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ku6dra/dmsynth","commit_stats":null,"previous_names":["ku6dra/dmsynth"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/ku6dra/dmsynth","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ku6dra%2Fdmsynth","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ku6dra%2Fdmsynth/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ku6dra%2Fdmsynth/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ku6dra%2Fdmsynth/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ku6dra","download_url":"https://codeload.github.com/ku6dra/dmsynth/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ku6dra%2Fdmsynth/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32307015,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-26T17:23:19.671Z","status":"ssl_error","status_checked_at":"2026-04-26T17:23:19.195Z","response_time":129,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["directmusic","midi","windows"],"created_at":"2026-04-26T18:00:19.438Z","updated_at":"2026-04-26T18:00:28.367Z","avatar_url":"https://github.com/ku6dra.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# DMSynth\n\nA lightweight MIDI synthesizer proxy for Windows 10/11 that drives the native **DirectMusic** software synthesizer (`Microsoft Synthesizer`) via COM.\n\n*An upgraded Microsoft GS Wavetable Synth, in your hands.*\n\n## Features\n\n- **Native DirectMusic** — COM interfaces redeclared from the original GUIDs and vtable layouts; builds with stock MSVC.\n- **DLS instrument loading** — Loads GM instruments from `gm.dls` (system default or user-specified) at startup.\n- **GS compatibility** — Translates incoming system messages:\n\n  | Incoming | Translated to |\n  |---|---|\n  | GM System On (`F0 7E 7F 09 01 F7`) \u003cbr\u003eor GM2 System On (`F0 7E 7F 09 03 F7`) | GS Reset |\n  | GM System Off | GS Reset |\n  | XG System On (`F0 43 10 4C ...`) | GS Reset |\n  | XG Reverb / Chorus type changes | Similar GS Reverb / Chorus macro |\n\n- **Capital Tone Fallback** — When a requested bank/patch is missing from the DLS, the closest available instrument is substituted by walking up the GS tone-map hierarchy (sub-capital → capital → any bank → first available). Drum kits fall back along the program number instead of the bank MSB.\n- **Drum Note Off workaround** — Tracks GS \"Use for Rhythm Part\" SysEx; ignores Note Off on drum channels to prevent voices from being cut off prematurely if a Note Off message follows a Note On too closely.\n- **32-channel MIDI** — Two MIDI inputs map to Channel Group 1 (CH 1 - 16) and Group 2 (CH 17 - 32).\n- **Scheduled playback** — Outgoing MIDI is timestamped against DirectMusic's latency clock to absorb callback jitter.\n- **Low-latency audio** — DirectSound output with MMCSS thread boosting on MIDI input.\n\n### Comparison\n\n| Feature | MSGS | **DMSynth** | VirtualMIDISynth |\n| :--- | :--- | :--- | :--- |\n| **Core Engine** | DirectMusic | **DirectMusic (Native COM)** | BASSMIDI |\n| **Sound Format** | DLS (`gm.dls` only) | **DLS** | SF2 / SFZ |\n| **Sample Rate** | 22,050 Hz | **44,100 Hz** (*) | 48,000 Hz (*) |\n| **Voices** | 32 | **128** (1–1000 *) | 16–100,000 (*) |\n| **Latency** | 150 ms | **Dynamic: Avg. 46 ms** (Min. 30 ms) | 0 ms (*) |\n| **Capital Tone Fallback** | No | **Yes** | Yes |\n| **Channels** | 16 | **32** (2 groups, shared engine) | 64 (4 independent groups) |\n\n\\* *Configurable*\n\n\n\n## Requirements\n\n- Windows 10 / 11 (x64 or x86)\n- CMake 3.15+\n- MSVC with C++17 support (Visual Studio 2019 or later recommended)\n\n*Microsoft DirectX SDK (August 2007) is **not required** to build this project.*\n\n\n## Building\n\n```bash\nmkdir build \u0026\u0026 cd build\ncmake ..\ncmake --build . --config Release\n```\n\nThe binary is produced at `build/Release/dm_synth.exe`.\n\nA `build.bat` script is also provided that builds both x64 and x86 in one step.\n\n## Usage\n\n```\ndm_synth.exe [options]\n```\n\nConnect a MIDI device, launch the executable, and select your devices from the on-screen prompts. All prompts can be bypassed using command-line arguments for headless operation.\n\nTo use DMSynth as a drop-in replacement for the Microsoft GS Wavetable Synth, a virtual MIDI port is required to route MIDI from your application to DMSynth's input.\n[loopMIDI](https://www.tobias-erichsen.de/software/loopmidi.html) works on Windows 10.\nOn the latest versions of Windows 11, [MIDI 2.0](https://github.com/microsoft/midi) changes may affect virtual port behavior — check compatibility before use.\n\n### Options\n\n| Option | Description |\n|---|---|\n| `--midi1 \u003cidx\\|name\u003e` | MIDI IN 1 device (CH 1 - 16). Index number or partial device name (case-insensitive) |\n| `--midi2 \u003cidx\\|name\u003e` | MIDI IN 2 device (CH 17 - 32). `-1` to disable |\n| `--port, -p \u003cidx\u003e` | Synthesizer port index |\n| `--rate, -r \u003chz\u003e` | Sample rate in Hz (default: 44100). Supported: 11025, 22050, 44100 |\n| `--voices \u003cn\u003e` | Maximum polyphony (default: 128) |\n| `--dls \u003cpath\u003e` | Path to a DLS file (default: system `gm.dls`) |\n| `--verbose, -v` | Enable MIDI event logging on startup |\n| `--immediate` | Bypass timestamp scheduling and send events for immediate playback. Use when running alongside software like DirectMusic Producer, which can throttle DirectSound and cause scheduled playback to run slow |\n| `--no-reverb` | Disable port-level reverb effect |\n| `--no-chorus` | Disable port-level chorus effect |\n| `--no-delay` | Disable port-level delay effect |\n| `--gap-ns \u003cns\u003e` | Minimum gap between events in nanoseconds (default: 100). Higher values roughly simulate MIDI cable bandwidth (e.g., 960,000 ns for a Note On at 31250 bps). |\n| `--list` | List available devices/ports and exit |\n| `--help, -h` | Show help and exit |\n\n### Runtime keys\n\n| Key | Action |\n|---|---|\n| `R` | Reset all MIDI state (All Sound Off + controller reset on every channel) |\n| `V` | Toggle MIDI event log display |\n| `Ctrl+C` | Quit |\n\n### Examples\n\n```bash\n# List available devices\ndm_synth.exe --list\n\n# Single MIDI input, no second port\ndm_synth.exe --midi1 0 --midi2 -1 --rate 44100\n\n# Select by partial device name\ndm_synth.exe --midi1 \"Loopback (A)\" --midi2 nanoKEY -v\n\n# Custom DLS sound set\ndm_synth.exe --dls \"C:\\soundfonts\\my_gm.dls\"\n```\n\n## Architecture\n\n```mermaid\ngraph TD\n    subgraph Input [\"MIDI Input (MidiInput)\"]\n        M1[MIDI IN 1\u003cbr/\u003eGroup 1] --\u003e MI\n        M2[MIDI IN 2\u003cbr/\u003eGroup 2] --\u003e MI\n        MI[\"WinMM Wrapper\u003cbr/\u003e(MMCSS Priority Boost)\"]\n    end\n\n    subgraph Logic [\"Processing (DmSynth)\"]\n        MI --\u003e DS[\"Message Dispatcher\"]\n        DS --\u003e|SysEx| GS[\"GS/XG Translation\"]\n        DS --\u003e|Program Change| FB[\"Capital Tone Fallback\"]\n        DS --\u003e|Note Off, Drum Ch| NF[\"Note Off Filter\u003cbr/\u003e(dropped)\"]\n        DS --\u003e|Other| TS\n        GS --\u003e TS\n        FB --\u003e TS\n        TS[\"Timestamping\u003cbr/\u003e(scheduled / immediate)\"] --\u003e Buf[\"IDirectMusicBuffer\"]\n    end\n\n    subgraph Output [\"Synthesis (DirectMusic)\"]\n        Buf --\u003e Synth[\"Microsoft Synthesizer\u003cbr/\u003e(IDirectMusicPort)\"]\n        LC[\"Latency Clock\"] -.-\u003e|reference time| TS\n        Synth --\u003e DirectSound[\"DirectSound\"]\n        DirectSound --\u003e AudioOutput((Audio))\n    end\n\n    subgraph UI [\"Logging (Main Loop)\"]\n        Logic -- \"SPSC Ring Buffer\" --\u003e Log[\"Screen Display\"]\n    end\n```\n\n- **MidiInput** — WinMM wrapper with MMCSS priority boost and lock-free SysEx buffering.\n- **DmSynth** — Processes MIDI messages including GS/XG translation, Capital Tone Fallback, and Note Off filtering. In scheduled mode each event is timestamped against the port's latency clock (auto-tuned at runtime) to absorb callback jitter; `--immediate` bypasses timestamping and sends events for immediate playback.\n- **Main loop** — Manages log event draining via an SPSC ring buffer to ensure the high-priority MIDI thread remains non-blocking for real-time performance.\n\n## License\nLicensed under the [MIT License](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fku6dra%2Fdmsynth","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fku6dra%2Fdmsynth","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fku6dra%2Fdmsynth/lists"}