{"id":19269338,"url":"https://github.com/atsushieno/augene-ng","last_synced_at":"2025-04-21T20:32:39.306Z","repository":{"id":45225995,"uuid":"395961795","full_name":"atsushieno/augene-ng","owner":"atsushieno","description":"MML + MIDI + Tracktion Engine XML manipulation tool for real production","archived":false,"fork":false,"pushed_at":"2025-01-26T07:43:45.000Z","size":68800,"stargazers_count":9,"open_issues_count":8,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-01T15:56:25.748Z","etag":null,"topics":["juce","kotlin","ksp","midi","mml","music"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/atsushieno.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","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}},"created_at":"2021-08-14T09:42:39.000Z","updated_at":"2025-01-26T07:43:49.000Z","dependencies_parsed_at":"2024-07-17T00:02:20.096Z","dependency_job_id":"cb36196a-1159-4fc8-a8ea-0c8cb0e5eef8","html_url":"https://github.com/atsushieno/augene-ng","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atsushieno%2Faugene-ng","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atsushieno%2Faugene-ng/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atsushieno%2Faugene-ng/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atsushieno%2Faugene-ng/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/atsushieno","download_url":"https://codeload.github.com/atsushieno/augene-ng/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250128355,"owners_count":21379493,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["juce","kotlin","ksp","midi","mml","music"],"created_at":"2024-11-09T20:19:35.194Z","updated_at":"2025-04-21T20:32:39.293Z","avatar_url":"https://github.com/atsushieno.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# augene-ng: MML compiler for audio plugins sequencer engine\n\n[![augene-ng demo 2021-11-18](http://img.youtube.com/vi/GZWBkxWjDfM/0.jpg)](https://www.youtube.com/watch?v=GZWBkxWjDfM \"augene-ng demo 2021-11-18\") (links to youtube video)\n\naugene(-ng, next gen) is an experimental compound music authoring toolchain that brings old-fashion MML (music macro language) compiler integrated into modern sequencer that is also used in Tracktion Waveform DAW (so far). It is the tool I (@atsushieno) use it for own music production in 2021 and onwards. Check out the youtube video linked from the sshot above to find out what I have achieved with this tool, as well as the actual project files under [`samples/mars`](./samples/mars) directory.\n\nYou can also have a quick glance at the project by [my slides for lightening talk at ADC 2019](https://speakerdeck.com/atsushieno/create-music-in-199x-language-for-2019-sequencer) for a bit more details, though I went far beyond from there.\n\nThe application consists of the following software and libraries behind:\n\n- The project model implemented in this repository which contains a set of MML sources and associated audio plugin filter graphs, converts MIDI 2.0 UMPs to audio plugin based songs (.tracktionedit)\n- MML compiler [mugene-ng](https://github.com/atsushieno/mugene-ng) - compiles MML into MIDI 2.0 UMPs.\n- [JUCE](https://github.com/juce-framework/JUCE) AudioPluginHost for editing audio graph.\n- [tracktion_engine](https://github.com/Tracktion/tracktion_engine/) - music playback engine.\n- [Compose for Desktop](https://github.com/JetBrains/compose-jb), cross-platform desktop port of Jetpack Compose. (The application itself is desktop-only, so far, as it depends on a lot of desktop filesystem idioms.)\n\n\n# Usage\n\nNOTE: before using augene, you most likely have to build things (explained in the next section).\n\nThere are two ways to use augene tools: (1) use GUI editor to create a project, compile it to `*.tracktionedit` on the UI, and play the outcome it with GUI player, or (2) run project compiler and pass an augene project as an argument to generate `*.tracktionedit`, and play it with GUI player.\n\n\nFor GUI editor, launch `augene(-editor)` application. It is a cross-platform Kotlin/JVM Compose for Desktop GUI application.\n\n![augene editor: configuration tab](docs/images/augene-config.png)\n\nBy default those lists are actually empty. It's a screenshot of the app that has loaded sample data that makes use of VST3 plugins.\n\nTo use this app, there are couple of things to do - Configure the app. Namely paths to two external tools are needed:\n\n- augene-player (JUCE app in this repository, which is mostly based on PlaybackDemo in `tracktion_engine` repository)\n- AudioPluginHost (can be found in JUCE extras)\n\nThe next step is to build a list of locally installed audio plugins. Begin with \"Plugins\" button to start the process.\n\n![build audio plugin list](docs/images/augene-player-plugin-list.png)\nOnce you are done with above, then you're ready to use the app. You can open a `*.tracktionedit` file and play it. Note that if you don't have the audio plugins specified in the edit file, you are unable to play it.\n\nTo compose your own music, create new audiograph and new MML for each list, which can be performed via the buttons on each tab. Then use \"Compile\" command from the FAB (floating action button).\n\nFor console compiler, run `java -jar path/to/augene-console.jar path/to/your/project.augene` and `AugenePlayer` respectively.\n\n\n# Building\n\n## augene-player\n\nThere are two primary steps to build the whole \"augene\" application. The first step is \"augene-player\" part, which is a JUCE based C++ application. It is a typical JUCE application project. You can build it with the following steps:\n\n```\ncd augene-player\nln -s ../external/tracktion_engine/modules/juce juce-symlink\nmkdir build\ncd build\ncmake ..\nmake\n```\n\n### Enabling VST2\n\nIt is not confirmed in augene-ng era, but if you have VST2 SDK and would like to add support for VST2, edit `CMakeLists.txt` which follows JUCE convention that I don't explain by myself. And probably `CMakeLists.txt` for AudioPluginHost too, especially if you try to build it from build-lv2-pluginhost.sh.\n\n## kotractive, augene, and augene-editor\n\nAnother chunk of the application is the augene project builder (or \"editor\") which is a Compose for Desktop based GUI app/tool.\n\nDue to current limitation of Kotlin Multiplatform project structure, there are 3 projects to just build one single app... :\n\n- `kotractive`, which provides basic \"tracktionedit\" file data model using [`ksp`](https://github.com/google/ksp/), in Kotlin Multiplatform\n- `augene`, which provides Augene project data model and manipulator API, in Kotlin Multiplatform\n- `augene-editor`, which is a GUI application project using Compose for Desktop Multiplatform, JVM-only\n\n```\n$ cd kotracktive \u0026\u0026 ./gradlew publishToMavenLocal \u0026\u0026 cd ..\n$ cd augene \u0026\u0026 ./gradlew publishToMavenLocal \u0026\u0026 cd ..\n$ cd augene-editor \u0026\u0026 ./gradlew package \u0026\u0026 cd ..\n```\n\n\n## Android build\n\nAugenePlayer is being ported to Android as [aap-juce-augene](https://github.com/atsushieno/aap-juce-augene). It still does not successfully run, and player only.\n\n# Augene project data format\n\nAn augene project is a simple set of XML described in a project file which looks like this:\n\n```\n\u003cAugeneProject xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\u003e\n  \u003cIncludes\u003e\n    \u003cInclude Bank=\"1\" Source=\"Banks/SfzBanks.augene\" /\u003e\n    \u003cInclude Bank=\"2\" Source=\"Banks/SF2Banks.augene\" /\u003e\n    \u003cInclude Bank=\"3\" Source=\"Banks/SurgeBanks.augene\" /\u003e\n  \u003c/Includes\u003e\n  \u003cMasterPlugins\u003e\n    \u003cMasterPlugin\u003eMasterPlugin1.filtergraph\u003c/MasterPlugin\u003e\n  \u003c/MasterPlugins\u003e\n  \u003cAudioGraphs\u003e\n    \u003cAudioGraph Id=\"GrandPiano1\" Source=\"sfizz_city_piano_1.filtergraph\" /\u003e\n  \u003c/AudioGraphs\u003e\n  \u003cTracks\u003e\n    \u003cAugeneTrack\u003e\n      \u003cId\u003e1\u003c/Id\u003e\n      \u003cAudioGraph\u003eUnnamed.filtergraph\u003c/AudioGraph\u003e\n    \u003c/AugeneTrack\u003e\n  \u003c/Tracks\u003e\n  \u003cMmlFiles\u003e\n    \u003cMmlFile\u003efoobar.mugene\u003c/MmlFile\u003e\n  \u003c/MmlFiles\u003e\n  \u003cMmlStrings\u003e\n    \u003cMmlString\u003e![CDATA[ 1 @0 V110 v100 o5 l8 cegcegeg  \u003e c1 ]]\u003e\u003c/MmlString\u003e\n  \u003c/MmlStrings\u003e\n\u003c/AugeneProject\u003e\n```\n\nHere is a list of elements:\n\n| Element | feature |\n|-|-|\n| AugeneProject | the root element |\n| Includes | container of `Include` elements. |\n| Include | include other project files. They can also be a bank list of AudioGraph. See description below. |\n| AudioGraphs | container of `AudioGraph` elements. |\n| AudioGraph | gives a filtergraph a name so that it can be referenced by `AudioGraph` element within `AugeneTrack` element. |\n| MasterPlugins | holds a list of master plugins |\n| MasterPlugin | specifies an AudioGraph file that is used as a master plugin |\n| Tracks | holds a list of tracks |\n| AugeneTrack | a track definition specifier which holds an Id and an AudioGraph file (so far only one plugin is specified. Rooms for improvements. |\n| MmlFiles | holds a list of MML files |\n| MmlFile | specifies an MML source file to be compiled and converted to the edit file. |\n| MmlStrings | holds a list of MML strings |\n| MmlString | specifies an MML string to be compiled and converted to the edit file. |\n\nAn Augene project can include other Augene project files using `Include` element. It is useful to represent a bank of preset filtergraphs. On an `Include` element, `Bank` and `BankMsb` attributes indicate bank select MSB, `BankLsb` attribute indicates bank select LSB (`Bank` is equivalent to `BankMsb` here). `Source` attribute indicates the *included* file path, relative to the *including* file path.\n\nAn `AudioGraph` can be referenced by its `Id` attribute, by (1) mugene MIDI track with `INSTRUMENTNAME` meta event, or (2) `AudioGraph` attribute on `AugeneTrack` elements.\n\nAll tracks in either MML format (file or string) are converted into tracktionedit. Then audio graphs in the project are interpreted and converted to `PLUGIN` element in tracktionedit and then for each defined track by `Tracks` elements, if there is any graph whose `Id` is identical to the track's `AudioGraph` then the audio graph is attached to the track.\n\nOne thing to note is that while mugene supports track number in double (floating point number) SMF does not have \"track numbers\" and numbers are counted only by sequential index (0, 1, 2...),  the mappings could be totally different. It is always safer to indicate audio graph by INSTRUMENTNAME meta event in mugene MML, or supplementally use `AugeneTrack`'s mappings.\n\n## Controlling audio plugin parameters by MML via automation tracks\n\nmugene is designed to generate music as in MIDI files, which has no concept of audio plugins and their parameters. augene (namely its `Midi2TracktionEditConverter`) has special support for controlling them via Tracktion's \"Automation Tracks\".\n\nTo understand how augene supports them, we should understand how a `.tracktionedit` XML file represents audio plugin parameter controllers via automation tracks.\n\n`\u003cAUTOMATIONTRACK\u003e` elements can be created inside a `\u003cTRACK\u003e` element, and each `\u003cAUTOMATIONTRACK\u003e` has `currentAutoParamPluginID` attribute that indicates a `\u003cPLUGIN\u003e` element by its `id` (not to be confused with `uid` or `uniqueId`), and `currentAutoParamTag` attribute that indicates the parameter index for the `\u003cPLUGIN\u003e`. The `\u003cAUTOMATIONTRACK\u003e` has no actual parameter data controllers though - they are in the `\u003cPLUGIN\u003e` element. It can contain `\u003cAUTOMATIONCURVE\u003e` elements, and each of them has a `paramID` attribute that indicates the parameter index, and a number of `\u003cPOINT\u003e` elements where each of them has `t` attribute (time) and `v` attribute (value) (TBD: there is also `c` attribute whose role is unknown).\n\nHere is an example track (excerpt):\n\n```\n  \u003cTRACK extension:InstrumentName=\"opn\" id=\"1\"\u003e\n    ...\n    \u003cAUTOMATIONTRACK currentAutoParamPluginID=\"1997591454\" currentAutoParamTag=\"4\" id=\"-1507545692\"\u003e\n      \u003cMACROPARAMETERS id=\"212771437\" /\u003e\n      \u003cMODIFIERS /\u003e\n    \u003c/AUTOMATIONTRACK\u003e\n    \u003cPLUGIN type=\"vst\" uid=\"a83aaba6\" filename=\"/home/atsushi/.vst3/OPNplug.vst3\" name=\"OPNplug\" manufacturer=\"Jean Pierre Cimalando\" id=\"1997591454\" enabled=\"1\" programNum=\"0\" state=\"...\"\u003e\n      \u003cAUTOMATIONCURVE paramID=\"4\"\u003e\n        \u003cPOINT t=\"0.0\" v=\"4096.0\" c=\"0.0\" /\u003e\n      \u003c/AUTOMATIONCURVE\u003e\n    \u003c/PLUGIN\u003e\n    ...\n  \u003c/TRACK\u003e\n```\n\nNow, its our (augene's, particularly its `Midi2TracktionEditConverter`'s) role on how to generate them from an SMF. We use system exclusive messages that indicate \"we are augene-ng automation controllers\". To identify that, system exclusives with `7Dh` sysex manufacturer ID (general research / development use), followed by 9 bytes `augene-ng` characters, is used. Then the next byte is used to distinguish two different controls:\n\n- `00h` to indicate the actual parameter control: the next two bytes represents the parameter ID by LSB and MSB, then the next two bytes for the parameter value LSB and MSB.\n- non-zero byte to indicate a string length, followed by the actual ASCII string that indicates the plugin's unique ID (`uid` or `uniqueID`) that is being used from there in the track.\n\nIndicating plugin's unique ID and parameter index is not intuitive for MML authoring. It's better to use some macros that wraps those constants. There is a helper Node.JS script `generate-automation-helper.js` that parses `~/.config/augene-ng/plugin-metadata.json` and generates a bunch of `.mugene` MML files for each audio plugins that are listed within the JSON, into `~/.config/augene-ng/audio-plugins` directory. The generated MML looks like this:\n\n```\n#macro AUDIO_PLUGIN_USE nameLen:number, ident:string {  __MIDI #F0, #7D, \"augene-ng\", $nameLen, $ident, #F7 }\n#macro AUDIO_PLUGIN_PARAMETER parameterID:number, val:number { \\\n    __MIDI #F0, #7D, \"augene-ng\", 0, \\\n    $parameterID % #80, $parameterID / #80, $val % #80, $val / #80 } \n\n#macro OPNPLUG { AUDIO_PLUGIN_USE 11, \"-1472549978\" }\n#macro OPNPLUG_MASTER_VOLUME val { AUDIO_PLUGIN_PARAMETER 0, $val }\n#macro OPNPLUG_EMULATOR val { AUDIO_PLUGIN_PARAMETER 1, $val }\n#macro OPNPLUG_CHIP_COUNT val { AUDIO_PLUGIN_PARAMETER 2, $val }\n#macro OPNPLUG_CHIP_TYPE val { AUDIO_PLUGIN_PARAMETER 3, $val }\n#macro OPNPLUG__PART_\\1__OPERATOR_\\1_LEVEL val { AUDIO_PLUGIN_PARAMETER 4, $val }\n...\n```\n\nThen you can `#include` this macro, and write your track MML like:\n\n```\n// not quite sure if this 127 works just as 127, you might need some multiplication\n1\tINSTRUMENTNAME \"opn\" CH0 @1 OPNPLUG OPNPLUG_PART\\1_OPERATOR\\1_LEVEL 127\n```\n\nWherever you have the same set of audio plugins installed on your system, you can generate the same set of macro definitions and therefore the MML should be compatible across environment, whereas the plugin unique IDs might be different.\n\n\n# License\n\nThe augene-player part (JUCE application) is released under the AGPLv3 license.\n\nThe kotlin projects are released under the MIT license.\n\n\n## Dependencies\n\nThere are couple of dependencies in this application:\n\n- [JUCE](https://juce.com/) - AGPLv3 (or commercial).\n- [Tracktion/tracktion_engine](https://github.com/Tracktion/tracktion_engine/) - should be the same.\n- [SpartanJ/efsw](https://github.com/SpartanJ/efsw) - MIT.\n- [dogla/filesystem-watcher](https://github.com/dogla/filesystem-watcher) - Apache 2.0. The sources are converted from Java to Kotlin and directly embedded in augene-editor-project.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fatsushieno%2Faugene-ng","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fatsushieno%2Faugene-ng","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fatsushieno%2Faugene-ng/lists"}