{"id":19437695,"url":"https://github.com/mganss/midimorph","last_synced_at":"2025-09-01T16:44:02.640Z","repository":{"id":49855176,"uuid":"193363513","full_name":"mganss/MidiMorph","owner":"mganss","description":"Max for Live device to interpolate between two MIDI clips","archived":false,"fork":false,"pushed_at":"2019-06-25T20:37:36.000Z","size":888,"stargazers_count":22,"open_issues_count":1,"forks_count":1,"subscribers_count":0,"default_branch":"master","last_synced_at":"2023-04-10T14:42:36.610Z","etag":null,"topics":["ableton","interpolation","maxforlive","maxmsp","midi","morphing"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","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/mganss.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}},"created_at":"2019-06-23T15:18:19.000Z","updated_at":"2022-07-27T09:53:00.000Z","dependencies_parsed_at":"2022-09-14T15:31:12.338Z","dependency_job_id":null,"html_url":"https://github.com/mganss/MidiMorph","commit_stats":null,"previous_names":[],"tags_count":null,"template":null,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mganss%2FMidiMorph","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mganss%2FMidiMorph/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mganss%2FMidiMorph/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mganss%2FMidiMorph/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mganss","download_url":"https://codeload.github.com/mganss/MidiMorph/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223968127,"owners_count":17233445,"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":["ableton","interpolation","maxforlive","maxmsp","midi","morphing"],"created_at":"2024-11-10T15:15:37.609Z","updated_at":"2024-11-10T15:15:38.162Z","avatar_url":"https://github.com/mganss.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# MidiMorph\n\nMidiMorph is a Max for Live device that allows smooth interpolation between two MIDI clips. \nThe output can be played directly from the device, saved to a new clip, or continuously updated to a destination clip.\nSource and destination clips are monitored for changes.\n\nDownload under [releases](https://github.com/mganss/MidiMorph/releases) or at [maxforlive.com](http://www.maxforlive.com/library/device.php?id=5550)\n\n![UI](https://raw.githubusercontent.com/mganss/MidiMorph/master/ui.png)\n![Demo](https://raw.githubusercontent.com/mganss/MidiMorph/master/demo.gif)\n\n## Usage\n\n1. Drag the device into a MIDI track\n2. Select the source clip\n3. Click the \u003ckbd\u003eFrom\u003c/kbd\u003e button\n4. Select the destination clip\n5. Click the \u003ckbd\u003eTo\u003c/kbd\u003e button\n6. Adjust the Morph dial (0 is identical to source, 1 is destination, 0.5 is half-way)\n\nOutput:\n\n- Play directly from the device (if the \u003ckbd\u003ePlay\u003c/kbd\u003e toggle is on)\n- Click the \u003ckbd\u003eClip\u003c/kbd\u003e button to save the current state selected by the Morph dial to a new clip\n- Create a new clip, select it, then click the \u003ckbd\u003eOut\u003c/kbd\u003e button to select permanent output to the newly created clip \n(will be overwritten whenever a new Morph value is selected or parameters changed)\n\n## Algorithm\n\nMidiMorph works by assigning pairs of notes from the source and destination clips, \nthen interpolating between the two notes of each pair to generate the intermediate notes.\nThe pairs are assigned so that the sum of note distances is minimal,\nwhere distance is defined as the euclidean distance in the pitch/time-plane (like in the piano roll).\nFinding the pairs in this way presents the classic [assignment problem](https://en.wikipedia.org/wiki/Assignment_problem) which is\nsolved here using the Jonker-Volgenant algorithm implemented in https://github.com/Fil/lap-jv.\n\nNotes that remain unpaired (because the number of notes differ between the source and destination clips) can be \nhandled in one of two ways:\n\n1. They can be paired\nin additional assignment rounds, such that one note from the clip that has fewer notes then has multiple notes from \nthe other clip assigned to it.\n2. They can remain unpaired and get faded or muted. Technically, they get paired with pseudo notes that are silent versions of themselves.\n\n## Quantization\n\nSelecting any of the values from the Quantize menu will quantize notes to the selected value. \nThis applies to the endpoints as well, i.e. output at 0.0 and 1.0 is quantized, too.\n\n## Unpaired Notes\n\nUsing the \u003ckbd\u003eAssign\u003c/kbd\u003e toggle you can select what happens to notes that remain unpaired after the first assignment \npass as outlined above.\nIf it's on, the remaining notes are assigned in additional assignment rounds using the same algorithm until all notes have been paired.\n\nIf the \u003ckbd\u003eAssign\u003c/kbd\u003e toggle is off, the remaining notes will not be assigned to notes from the other clip. Instead, they will\nget paired with pseudo-notes that are silent versions of themselves. This means they will stay in place and fade out or get muted\n(depending on the Mute/Fade selection described below).\n\nThe image below shows the transition between the same two clips as the demo at the top but with \u003ckbd\u003eAssign\u003c/kbd\u003e enabled.\nThe single note at the top right (F3) is now paired and converges to the note at the bottom right (A2).\n\n![Assign enabled](https://raw.githubusercontent.com/mganss/MidiMorph/master/assign.gif)\n\n## Mute/Fade\n\nNotes that remained unpaired after the first round of assignment will either fade out or get muted. You can choose either behavior from\nthe Mute/Fade menu. In the fade case, the velocity will transition to zero and once it reaches zero, the note\nwill be removed. When mute is selected, the note will stay at its original velocity up to half way, then get removed.\n\n## Skip Mute\n\nIf the Skip Mute toggle is on, notes in either clip that are muted will be ignored. If it's off, muted notes will participate in the\nassignment and interpolation process. If they are paired with non-muted notes, intermediate notes will be unmuted at half-way.\n\n## Overlap\n\nIf intermediate notes overlap and the \u003ckbd\u003eOverlap\u003c/kbd\u003e toggle is on, the overlapping notes are merged into one note which is identical\nto the one that starts earliest.\n\n## Drums\n\nIf the \u003ckbd\u003eDrums\u003c/kbd\u003e toggle is on, all notes that have the same pitch will be handled independently from those that have a different pitch, i.e. notes of one pitch will only be morphed into notes that have the same pitch.\n\n## Steps/Sequences\n\nThe Steps dial selects the number of interpolation steps. The Sequences dial selects the number of \"sequences\" which can be thought of\nas sub-steps. Consider the case where you have 10 notes in both the source and destination clips and the number of steps is 100.\nIf the number of sequences is 100 all notes will be moved 1/100 of the distance at each step. If the number of sequences is 10,\nonly one note will be moved 1/10 of the distance at each step. The idea is to get more subtle changes at a single step in this way.\n\nThe images below show the same transition, both have steps set to 4, the first one has sequences set to 2, the second one has sequences\nset to 4.\n\n![2 Sequences](https://raw.githubusercontent.com/mganss/MidiMorph/master/seqs2.gif)\n![4 Sequences](https://raw.githubusercontent.com/mganss/MidiMorph/master/seqs4.gif)\n\n## Pitch Scale\n\nThe cost function used to assign note pairs calculates a distance in the pitch/time plane. \nThe Scale dial selects the number of semitones that are equal in distance to one beat.\n\n## Technical Notes\n\nWhenever a parameter changes, all steps are precalculated. For immediate playback from the device, all values are saved to a `coll` and playback is triggered by a `metro` with resolution of one tick.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmganss%2Fmidimorph","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmganss%2Fmidimorph","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmganss%2Fmidimorph/lists"}