Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/atsushieno/augene-ng
MML + MIDI + Tracktion Engine XML manipulation tool for real production
https://github.com/atsushieno/augene-ng
juce kotlin ksp midi mml music
Last synced: 2 months ago
JSON representation
MML + MIDI + Tracktion Engine XML manipulation tool for real production
- Host: GitHub
- URL: https://github.com/atsushieno/augene-ng
- Owner: atsushieno
- License: gpl-3.0
- Created: 2021-08-14T09:42:39.000Z (over 3 years ago)
- Default Branch: main
- Last Pushed: 2024-07-16T20:08:49.000Z (6 months ago)
- Last Synced: 2024-07-17T00:14:20.970Z (6 months ago)
- Topics: juce, kotlin, ksp, midi, mml, music
- Language: Kotlin
- Homepage:
- Size: 65.5 MB
- Stars: 9
- Watchers: 3
- Forks: 2
- Open Issues: 7
-
Metadata Files:
- Readme: README.md
- License: LICENSE.txt
Awesome Lists containing this project
README
# augene-ng: MML compiler for audio plugins sequencer engine
[![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)
augene(-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.
You 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.
The application consists of the following software and libraries behind:
- 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)
- MML compiler [mugene-ng](https://github.com/atsushieno/mugene-ng) - compiles MML into MIDI 2.0 UMPs.
- [JUCE](https://github.com/juce-framework/JUCE) AudioPluginHost for editing audio graph.
- [tracktion_engine](https://github.com/Tracktion/tracktion_engine/) - music playback engine.
- [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.)# Usage
NOTE: before using augene, you most likely have to build things (explained in the next section).
There 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.
For GUI editor, launch `augene(-editor)` application. It is a cross-platform Kotlin/JVM Compose for Desktop GUI application.
![augene editor: configuration tab](docs/images/augene-config.png)
By default those lists are actually empty. It's a screenshot of the app that has loaded sample data that makes use of VST3 plugins.
To use this app, there are couple of things to do - Configure the app. Namely paths to two external tools are needed:
- augene-player (JUCE app in this repository, which is mostly based on PlaybackDemo in `tracktion_engine` repository)
- AudioPluginHost (can be found in JUCE extras)The next step is to build a list of locally installed audio plugins. Begin with "Plugins" button to start the process.
![build audio plugin list](docs/images/augene-player-plugin-list.png)
Once 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.To 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).
For console compiler, run `java -jar path/to/augene-console.jar path/to/your/project.augene` and `AugenePlayer` respectively.
# Building
## augene-player
There 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:
```
cd augene-player
ln -s ../external/tracktion_engine/modules/juce juce-symlink
mkdir build
cd build
cmake ..
make
```### Enabling VST2
It 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.
## kotractive, augene, and augene-editor
Another chunk of the application is the augene project builder (or "editor") which is a Compose for Desktop based GUI app/tool.
Due to current limitation of Kotlin Multiplatform project structure, there are 3 projects to just build one single app... :
- `kotractive`, which provides basic "tracktionedit" file data model using [`ksp`](https://github.com/google/ksp/), in Kotlin Multiplatform
- `augene`, which provides Augene project data model and manipulator API, in Kotlin Multiplatform
- `augene-editor`, which is a GUI application project using Compose for Desktop Multiplatform, JVM-only```
$ cd kotracktive && ./gradlew publishToMavenLocal && cd ..
$ cd augene && ./gradlew publishToMavenLocal && cd ..
$ cd augene-editor && ./gradlew package && cd ..
```## Android build
AugenePlayer 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.
# Augene project data format
An augene project is a simple set of XML described in a project file which looks like this:
```
MasterPlugin1.filtergraph
1
Unnamed.filtergraph
foobar.mugene
![CDATA[ 1 @0 V110 v100 o5 l8 cegcegeg > c1 ]]>
```
Here is a list of elements:
| Element | feature |
|-|-|
| AugeneProject | the root element |
| Includes | container of `Include` elements. |
| Include | include other project files. They can also be a bank list of AudioGraph. See description below. |
| AudioGraphs | container of `AudioGraph` elements. |
| AudioGraph | gives a filtergraph a name so that it can be referenced by `AudioGraph` element within `AugeneTrack` element. |
| MasterPlugins | holds a list of master plugins |
| MasterPlugin | specifies an AudioGraph file that is used as a master plugin |
| Tracks | holds a list of tracks |
| AugeneTrack | a track definition specifier which holds an Id and an AudioGraph file (so far only one plugin is specified. Rooms for improvements. |
| MmlFiles | holds a list of MML files |
| MmlFile | specifies an MML source file to be compiled and converted to the edit file. |
| MmlStrings | holds a list of MML strings |
| MmlString | specifies an MML string to be compiled and converted to the edit file. |An 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.
An `AudioGraph` can be referenced by its `Id` attribute, by (1) mugene MIDI track with `INSTRUMENTNAME` meta event, or (2) `AudioGraph` attribute on `AugeneTrack` elements.
All 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.
One 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.
## Controlling audio plugin parameters by MML via automation tracks
mugene 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".
To understand how augene supports them, we should understand how a `.tracktionedit` XML file represents audio plugin parameter controllers via automation tracks.
`` elements can be created inside a `` element, and each `` has `currentAutoParamPluginID` attribute that indicates a `` element by its `id` (not to be confused with `uid` or `uniqueId`), and `currentAutoParamTag` attribute that indicates the parameter index for the ``. The `` has no actual parameter data controllers though - they are in the `` element. It can contain `` elements, and each of them has a `paramID` attribute that indicates the parameter index, and a number of `` elements where each of them has `t` attribute (time) and `v` attribute (value) (TBD: there is also `c` attribute whose role is unknown).
Here is an example track (excerpt):
```
...
...
```Now, 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:
- `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.
- 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.Indicating 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:
```
#macro AUDIO_PLUGIN_USE nameLen:number, ident:string { __MIDI #F0, #7D, "augene-ng", $nameLen, $ident, #F7 }
#macro AUDIO_PLUGIN_PARAMETER parameterID:number, val:number { \
__MIDI #F0, #7D, "augene-ng", 0, \
$parameterID % #80, $parameterID / #80, $val % #80, $val / #80 }#macro OPNPLUG { AUDIO_PLUGIN_USE 11, "-1472549978" }
#macro OPNPLUG_MASTER_VOLUME val { AUDIO_PLUGIN_PARAMETER 0, $val }
#macro OPNPLUG_EMULATOR val { AUDIO_PLUGIN_PARAMETER 1, $val }
#macro OPNPLUG_CHIP_COUNT val { AUDIO_PLUGIN_PARAMETER 2, $val }
#macro OPNPLUG_CHIP_TYPE val { AUDIO_PLUGIN_PARAMETER 3, $val }
#macro OPNPLUG__PART_\1__OPERATOR_\1_LEVEL val { AUDIO_PLUGIN_PARAMETER 4, $val }
...
```Then you can `#include` this macro, and write your track MML like:
```
// not quite sure if this 127 works just as 127, you might need some multiplication
1 INSTRUMENTNAME "opn" CH0 @1 OPNPLUG OPNPLUG_PART\1_OPERATOR\1_LEVEL 127
```Wherever 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.
# License
The augene-player part (JUCE application) is released under the GPLv3 license.
The kotlin projects are released under the MIT license.
## Dependencies
There are couple of dependencies in this application:
- [JUCE](https://juce.com/) - GPLv3 (or commercial).
- [Tracktion/tracktion_engine](https://github.com/Tracktion/tracktion_engine/) - ditto.
- [lvtk/jlv2](https://github.com/lvtk/jlv2) - ditto (in jlv2_host).
- [SpartanJ/efsw](https://github.com/SpartanJ/efsw) - MIT.
- [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.