Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better MIDI support #1472

Open
4 of 26 tasks
tresf opened this issue Dec 20, 2014 · 51 comments
Open
4 of 26 tasks

Better MIDI support #1472

tresf opened this issue Dec 20, 2014 · 51 comments

Comments

@tresf
Copy link
Member

tresf commented Dec 20, 2014

This is a placeholder to consolidate MIDI related issues. If a new MIDI enhancement is reported on the tracker, close it out and mark it as a duplicate of this bug (and naturally add to this list as needed) (#1472)

Note: As opposed to our other placeholder bug reports, MIDI is slightly different as it is mostly feature-complete. Version-specific MIDI bugs should remain open and tracked on a per-version basis. Don't close out valid bug reports simply because they use the word "MIDI" in them, first make sure they aren't attributed to a specific build. 👍


Basic Functionality:

Enhanced Functionality:

Bugs:

Related:

  • (none reported yet)
@badosu
Copy link
Contributor

badosu commented Dec 26, 2014

@tresf Perhaps we could make this a checklist where we can tick each task as it is completed.

In my case I don't have a fully capable MIDI controller, but would like to work on the Export to MIDI feature.

Take a look at this reference on markdown checklists if you need.

@diizy
Copy link
Contributor

diizy commented Dec 26, 2014

On 12/26/2014 10:17 PM, Amadeus Folego wrote:

@tresf https://github.com/tresf Perhaps we could make this a
checklist where we can tick each task as it is completed.

In my case I don't have a fully capable MIDI controller, but would
like to work on the Export to MIDI feature.

Take a look at this reference
https://github.com/blog/1375%0A-task-lists-in-gfm-issues-pulls-comments
on markdown checklists if you need.

Export to MIDI should be implemented as an export plugin.

You don't need a MIDI controller for it.

@badosu
Copy link
Contributor

badosu commented Dec 26, 2014

I know, I am talking about the other features, this is an example of a feature that does not need a virtual/real midi controller.

So when this task is completed is is marked and we have a sense on how our MIDI support is evolving.

@tresf
Copy link
Member Author

tresf commented Dec 26, 2014

Perhaps we could make this a checklist where we can tick each task as it is completed.

Sounds good. Planned on using strikeout (~~strikeout~~) to mark as done if that sounds OK.

@Reaper10
Copy link

Reaper10 commented Feb 5, 2015

Working on a keyboard layer plugin and keyboard layer track GUI mockup for #1381.

@rheslip
Copy link

rheslip commented Feb 22, 2015

I'm finding midi import crashes LMMS on about 30% of the files I've tried on V1.10, V1.12, Win64 and Win32 versions. These files seem to play OK in Windows Media Player. Audacity imports them OK. Example: http://en.midimelody.ru/midi.php?str=%2Fb%2FBeck%2C%20Jeff%2FBeck%2C%20Jeff%20-%20Blue%20Wind.mid

@Sti2nd
Copy link
Contributor

Sti2nd commented Feb 22, 2015

Probably because it contains some feature that LMMS doesn't support

@rheslip
Copy link

rheslip commented Feb 23, 2015

I haven't found exactly what causes the crash but it appears to be something with pitch bends. There is a lot of pitch bending in that tune (Jeff Beck's "Blue Wind") and when I filter all the pitch bends out of the midi file it imports correctly. I'll see if I can narrow it down to something more specific.

@badosu
Copy link
Contributor

badosu commented Feb 23, 2015

@tresf Can you tick #699 as it was fixed?

@tresf
Copy link
Member Author

tresf commented Feb 23, 2015

@tresf Can you tick #699 as it was fixed?

👍

@Umcaruje
Copy link
Member

Umcaruje commented Mar 2, 2015

This should be turned into a task list so its easier to mark fixed issues.

@artur-twardowski
Copy link
Contributor

artur-twardowski commented Aug 30, 2019

Some ideas that have come up to my mind so far. If needed, I can open separate tickets for them.

  • A possibility to assign MIDI controllers' buttons to toggle switches. Some controllers, such as Alesis QX49 are highly configurable and their buttons can be assigned a CC, even with defined values on both key-down and key-up. On the other hand, controllers such as AKAI Midimix send Note On and Note Off events, with no way to configure anything. AKAI Midimix has 19 physical buttons, but from the MIDI perspective it exposes 27, so you could do a lot with them.
    • As an extension of the feature above, a group of MIDI controller keys could be assigned to one CC but with different values. This way, for example, I could assign eight buttons on Midimix to choose waveforms of both OpulenZ's oscillators.
  • Back-feeding the actual state of the plugin's control to the MIDI controller. In AKAI Midimix, sending a Note Off message with nonzero velocity will turn on the backlight of the button (the same message with a velocity of 0 will turn the light off). I don't know if there are any MIDI controllers that are capable of moving their sliders or knobs (I have come across such audio mixers only), but if they exist, they might listen for Controller Change messages sent back. Novation Launchpad users will be especially interested in this feature, I guess :)
  • Support for various MIDI Machine Control messages. They are actually SysEx messages but they are defined in the standard, and they include:
    • transport control (Play, Pause, Stop, Rewind, Fast-forward, Record, etc.)
    • master volume control
    • coarse and fine tuning; coarse tuning is typically equivalent to transpose control (Casio CTK-4200 sends them when I transpose the keyboard)
      We could internally re-map these messages into keys and CC using IDs above 128.

Speaking of transport control, the Play/Stop/Record controls could also be made assignable to MIDI events, but this was already mentioned by others.

@benwiley4000
Copy link

What's the main blocker for midi pitch bend recording support? I was recording a solo via midi and was surprised that even though the pitch bends were correct during the recording, they were missing during later playback. If there's something I could contribute to help this make it into a near-term release I'd be happy to look into it!

@michaelgregorius
Copy link
Contributor

Hi @benwiley4000,

I had a quick look at the problem, i.e. I have checked what happens if you play a note while recording and what happens if the pitch wheel is moved. Unfortunately it seems that there is no quick solution to your problem. In my opinion the main blocker is that MIDI is not a first class citizen in LMMS. So you have asked your question in the correct issue. ;)

MIDI and audio streams in other DAWs

Most other DAWs know at least the following two first class citizens:

  • Audio streams
  • MIDI events

If you record something (or import files) these DAWs will create containers which store or reference this data. The containers can be moved or copied around the timeline and tracks to build a song. If you record MIDI with a keyboard the container will still represent this information as a stream of MIDI events. And if you play back with the playhead over the container then the DAW will reproduce this stream of MIDI events and route it wherever it should go, e.g. to an instrument plugin. It's then up to the instrument plugin to interpret what to do with this data which allows for very flexible and different implementations. Because the data is still represented as MIDI events this also means that pitch bends would be played back without problems because they are simply events in that event stream.

What happens in LMMS?

Recording a note

Let's now see what happens in LMMS when you hit record in the piano roll and press a key on your keyboard. I have tested this with an instance of TripleOsc. A note is recorded as follows:

  1. As soon as you press a key on the MIDI keyboard the method InstrumentTrack::processInEvent is triggered. The switch statement in that code will trigger the MidiNoteOn case which in turn will call NotePlayHandleManager::acquire which creates an instance of a NotePlayHandle.
  2. In the constructor of NotePlayHandle the signal midiNoteOn is emitted for the associated instrument track because it is created with the origin being set to OriginMidiInput.
  3. The method PianoRoll::startRecordNote is connected to that signal and adds a new instance of Note to its recorded notes which are stored in m_recordingNotes.

Moving the pitch bend wheel

If you move the pitch wheel this will also trigger InstrumentTrack::processInEvent. In this case the MidiPitchBend case is handled. If you look at the code you will find that it only makes changes to the current state of the instrument track. That's the reason why you can hear the changes during recording. However, it does not trigger any code that will record the pitch bend events. This is because LMMS does not know how to store pitch wheel events and also has no place to store them. It does not make sense to store them in a NotePlayHandle because in that case the NotePlayHandle would now need to be able to store different states of pitch for different times.

A potential solution (how most other DAWs do it)

Put differently: LMMS is very quick to translate the MIDI data into its own representation which is not able to handle all the nuances of a MIDI stream. In my opinion it also does too much interpretation outside of the instruments and plugins (compared to having the interpretation implemented in plugins/clients). The best solution would be to represent all non-audio data as MIDI internally (or at least in a form that encompasses all of MIDI) and to route it accordingly. This would also enable the usage of plugins which transform the MIDI stream (e.g. transpose it, make all notes of equal volume, etc.). With the current implementation I assume that such plugins are not supported.

The fact that most plugin standards (VST2, VST3, LV2, etc.) differentiate between audio and MIDI is another indicator that it's a good idea for a DAW to be able to deal with streams of MIDI data internally.

If MIDI was a first class citizen it would likely make importing MIDI data easier as well. You would "simply" read the MIDI data, perhaps transform it and then put it into the containers. And then play it back to your hearts content.

@benwiley4000
Copy link

@michaelgregorius what do you think some actionable steps could be? The "perfectly correct" way, and also, what would actionable steps be if I'm totally selfish and only want to get my feature implemented? 😜 I'm brand new to the code base but if there's a small task I could start with that would be great.

@michaelgregorius
Copy link
Contributor

Hi @benwiley4000,

I guess even a "selfish" and perhaps even "hacked" implementation that only solves this single problem would be rather complex. The base problem can be described as "MIDI events are generated but only some of them are recorded so only a subset of the input events will be played back". So you'd have to solve the following problems:

  1. Find a way to record the events that are not recorded currently (or at least the pitch bend events). As noted above it likely does not make sense to also store them in the NotePlayHandle instances so you'd have to invent your own data structure and organisation of the structure during recording and playback.
  2. You will also to implement a way to store that new data structure in a saved file so that the recorded events are persisted across sessions.
  3. If you had this data structure then you'd also have to find out in some way how many voices are active for example in a given InstrumentTrack that gets the pitch bends applied. Because if you for example press three keys one after the other on your MIDI keyboard without releasing them and then move the pitch wheel then the pitch bend will have to be applied to all three active notes.

As you can imagine the steps that need to be implemented for the "perfectly correct" way would be even more complex. Things that come to mind are:

  • Implement a data structure that holds the MIDI events and of which several can be associated with an instrument or MIDI track.
  • The note patterns that are saved in old files will have to be converted to MIDI upon loading.
  • The interfaces of LMMS' own plugins will likely need to be changed to now accept MIDI event streams.
  • We would likely need a base class for the existing plugins which provides functionality to convert the incoming MIDI events to a similar behavior as is implemented currently, i.e. this base implementation might make use of the NotePlayHandles because the current "old" code outside of the plugins will not be usable anymore.

Once this infrastructure was available I think many interesting and useful things could be implemented. For example:

  • MIDI containers that point to a file on disk. Whenever that file is changed all instances in the project would be adjusted.
  • MIDI containers which are "instances" or clones of one "internal" MIDI container. One you make changes to the original all clones are adjusted.
  • Same for audio. Once you have something recorded it's one file on disk which might be referenced by several instances at different times or even tracks. This would save tons of memory because as far as I know LMMS currently stores all samples fully in memory.
  • If the containers are implemented intelligently they should stream the data into memory as needed.

By the way, if you want to get your feet wet with regards to coding in LMMS there are some issues which are tagged as "good first issue". Perhaps you can find something interesting there even if it doesn't scratch your current personal itch. 😉

@musikBear
Copy link

Has functional MIDI-export been implemented at any time? Afair : Yes. I believe it has been working.
I can read the Notes in the archive, and the first time MIDI-export is mentioned, is in v1.1.90, under General Improvements as 6. item in that list:

    General Improvements
        Build support for Haiku (BeOS) Operating System
        Better handling of corrupt projects/presets
        Export as loop support for CLI (#2131)
        Added Apple MIDI support (#1153)
        Fix "Dummy" audio selection (#2376)
        MIDI export support

MIDI-export is broken in aspects of

  • Pitch
  • Note-position
  • full length export

in 1.2.1 #5287


Irrelevant:
Yesterday i spend ~20 mins to search for the most relevant thread for (re)-reporting broken MIDI-export in 1.2.1. This thread did not appear in any search involving MIDI+ (fail | broken | lost) -So i made a new Issue. (5287) But it belongs here.
Searching and getting relevant results here, are imo a problem. Some kind of 'header' with most relevant keywords -could that be an idea?

@sebwahl
Copy link

sebwahl commented Jan 3, 2020

Hello !
Firstly, allow me to wish all of you a happy new year !
Secondly, as it is my first post here, I would like to thank really kindly all contributors to this project. I discovered LMMS a few days ago, and I'm very impressed by the quality of this software.

Now to the point : MIDI sound banks !
I also have a nice Yamaha CLP-645 with very high quality piano samples (Yamaha GH2 / Bösendorfer Imperial ...) and I would like to write some parts on LMMS and render them via MIDI.
The problem is : i'm only allowed to select a program (from -1 to 127) that applies to the default bank. But to select the other voices, you need to send a MSB and LSB then a program...
clp685_en_mr_b0.pdf

So, if my opinion is accepted : "MIDI bank-selection (MSB) support #62" item would be really appreciated ;)

Sadly it will be impossible for me to contribute, as my level in programming is too low ... wish I could help...

@LNooteboom
Copy link
Contributor

@tresf
With the merge of pullrequest #5499
"Faster access to MIDI assignment/auto-assignment" can be ticked now I think.

@SeleDreams
Copy link
Contributor

I'm thinking of working on creating a midi out plugin similar to fl that will send midi data to specific channels of vestige instances
i'll look into it

@Spekular
Copy link
Member

I'm thinking of working on creating a midi out plugin similar to fl that will send midi data to specific channels of vestige instances i'll look into it

Why a plugin (where would it go?) and why only to VeSTige? Native effects would benefit from receiving MIDI as well, and ideally you'd be able to send that MIDI from any track (e.g. if you already have an instrument playing the "control" MIDI)

@SeleDreams
Copy link
Contributor

I'm thinking of working on creating a midi out plugin similar to fl that will send midi data to specific channels of vestige instances i'll look into it

Why a plugin (where would it go?) and why only to VeSTige? Native effects would benefit from receiving MIDI as well, and ideally you'd be able to send that MIDI from any track (e.g. if you already have an instrument playing the "control" MIDI)

a plugin because it's the only way i'd imagine being able to send midi data to multiple midi channels of a same plugin at the same time

I said vestige mostly because it's mostly vst that require multi midi input, no lmms instrument uses it since they just use a single channel

@icubex
Copy link

icubex commented May 3, 2023

LMMS on MacOS Ventura 13.3.1 crashes when any virtual MIDI port is created or disposed of. Also, unfortunately LMMS doesn't allow these virtual MIDI ports to be used so it's necessary to use a software like MIDI Pipe to route the messages from the virtual MIDI port to the IAC driver (which can be used in LMMS).
LMMS_crash_report.zip

@PhysSong
Copy link
Member

PhysSong commented May 4, 2023

@icubex Duplicate of #5728, and the fix will be included in future releases.

@sandos
Copy link

sandos commented Apr 3, 2024

This is only slightly tangential, but if this is ever fixed, do have a think around OSC as well. I imagine a "container" or whatever that encompassed MIDI can "easily" handle OSC, too, but who knows. Might anyway be worth thinking about both OSC and extended MIDI variants I guess.

I was about to have a stab at adding OSC myself as an experiment, but Im not sure its worth it after reading this bug.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests