MusicLang / maidi

Work with symbolic music gen AI easily, based on midi manipulation.
Apache License 2.0
18 stars 0 forks source link
Known Vulnerabilities License

M(AI)DI

M(AI)DI

M(ai)di is an open source python library that aims to highlight the capabilities and usefulness of the Symbolic Music GenAI. It interfaces with the best symbolic music AI models and APIs to accelerate AI integration in music tech products. It came from the realization that artists need to manipulate MIDI and not only audio in their composition workflow but tools are lacking in this area.

So here we are, providing a simple and efficient way to manipulate midi files and integrate with music AI models. In a few lines of code you will be able to parse, analyze and generate midi files with the best music AI models available.

Here is where M(ai)di shines:

Disclaimer : We really focus on processing midi files and model inference calls. We don't implement audio features, neither model training, neither tokenization.

Read the official documentation

Getting Started

Installation

To install the package, you can use pip:

pip install maidi

Or to get the latest version from the repository, you can use:

pip install git+https://github.com/MusicLang/maidi.git

Usage

A simple code snippet to load and analyze a midi file :

from maidi import MidiScore, ScoreTagger, midi_library
from maidi.analysis import tags_providers

score = MidiScore.from_midi(midi_library.get_midi_file('drum_and_bass'))

tagger = ScoreTagger(
    [
        tags_providers.DensityTagsProvider(),
        tags_providers.MinMaxPolyphonyTagsProvider(),
        tags_providers.MinMaxRegisterTagsProvider(),
        tags_providers.SpecialNotesTagsProvider(),
    ]
)

tags = tagger.tag_score(score)
chords = score.get_chords()
print(tags)
print(chords)

Integrations

With MusicLang API

MusicLang is a co-pilot for music composition. It is a music AI model that can modify a midi score based on a prompt. The API is integrated into M(AI)DI to provide a seamless experience for the user.

A simple example: Generate a 4 bar score with the musiclang masking model API. Just set your MUSICLANG_API_KEY in the environment (or get one here) and run the following code :

from maidi import MidiScore
from maidi import instrument
import os
from maidi.integrations.api import MusicLangAPI

# Assuming MUSICLANG_API_KEY is set in the environment
MUSICLANG_API_KEY = os.getenv("MUSICLANG_API_KEY")

# Your choice of params for generation here
instruments = [
    instrument.DRUMS,
    instrument.ELECTRIC_BASS_FINGER,
]

# Create a 4 bar template with the given instruments
score = MidiScore.from_empty(
    instruments=instruments, nb_bars=4, ts=(4, 4), tempo=120
)
# Get the controls (the prompt) for this score
mask, tags, chords = score.get_empty_controls(prevent_silence=True)
mask[:, :] = 1  # Regenerate everything in the score

# Call the musiclang API to predict the score
api = MusicLangAPI(api_key=MUSICLANG_API_KEY, verbose=True)
predicted_score = api.predict(score,
    mask, tags=tags, chords=chords, async_mode=False, polling_interval=5
)
predicted_score.write("predicted_score.mid")

Generate a new track in a score : Start from a midi file and add a track.

import os
from maidi import MidiScore, instrument, midi_library
from maidi.integrations.api import MusicLangAPI

# Assuming MUSICLANG_API_KEY is set in the environment
MUSICLANG_API_KEY = os.getenv("MUSICLANG_API_KEY")

# Create a 4 bar template with the given instruments
score = MidiScore.from_midi(midi_library.get_midi_file('drum_and_bass'))
# Add a clean guitar track and set the mask
score = score.add_instrument(instrument.CLEAN_GUITAR)
mask, _, _ = score.get_empty_controls(prevent_silence=True)
mask[-1, :] = 1  # Generate the last track

# Call the musiclang API to predict the score
api = MusicLangAPI(api_key=MUSICLANG_API_KEY, verbose=True)
predicted_score = api.predict(score,
    mask, async_mode=False, polling_interval=3
)
predicted_score.write("predicted_score.mid")

Generate a track that has the same characteristics as an existing midi files : Start from a midi file and generate a new track with the same characteristics.

import os
from maidi import MidiScore, ScoreTagger, midi_library
from maidi.analysis import tags_providers
from maidi.integrations.api import MusicLangAPI

# Assuming MUSICLANG_API_KEY are set in the environment
MUSICLANG_API_KEY = os.getenv("MUSICLANG_API_KEY")
# Load a midi file
score = MidiScore.from_midi(midi_library.get_midi_file('example1'))

# Get a score with the first track and the first 4 bars of the midi file
score = score[0, :4]

tagger = ScoreTagger(
    [
        tags_providers.DensityTagsProvider(),
        tags_providers.MinMaxPolyphonyTagsProvider(),
        tags_providers.MinMaxRegisterTagsProvider(),
        tags_providers.SpecialNotesTagsProvider(),
    ]
)
tags = tagger.tag_score(score)
chords = score.get_chords()
mask = score.get_mask()
mask[:, :] = 1  # Regenerate everything in the score

api = MusicLangAPI(api_key=MUSICLANG_API_KEY, verbose=True)
predicted_score = api.predict(score,
                              mask, async_mode=False, polling_interval=3
                              )
predicted_score.write("predicted_score.mid")

For more details on the API, please refer to the MusicLang API documentation.

With other tools and APIs

See CONTRIBUTING.md for more details.

Contributing

We welcome contributions to the project as long as it fits its main philosophy :

Please read CONTRIBUTING.md for more details.

Next steps

License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.