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

how can I specify a different MIDI channel for identical MIDI notes on a layer? #9456

Closed
ralfkaa opened this issue Jun 17, 2020 · 39 comments
Closed
Labels
help wanted question stale Issues or pull requests that have become inactive without resolution.

Comments

@ralfkaa
Copy link

ralfkaa commented Jun 17, 2020

Background: I'm implementing MIDI on a hand-wired keyboard. Several notes repeat by design to make for more convenient fingering (I'm using isomorphic note layouts). But if the repeated notes send the same MIDI note keycodes on the same MIDI channel (i.e., if there are notes on the keyboard which are absolutely identical), I run into trouble depending on what DAW and/or OS I'm using.

Question: Can I configure a layout (in the keymap, I assume) so that each switch sends not only a MIDI note, but also a MIDI channel specification?

An example using quantum keycodes: on a layer I need to have, say, the note MI_G_2 playing on channel MI_CH1 on one switch, and the same MI_G_2 playing on channel MI_CH2 on another switch (on the same layer).

Is that possible, and if so, is there any written documentation on this or example that could show me how to implement this?

Thank you in advance for any help!

@AlexOConnorHub
Copy link
Contributor

I've looked into QMK's MIDI abilities a bit for my keyboard, and sadly, I've not seen this as an option. I may have missed seeing this in my searching though.

@ralfkaa
Copy link
Author

ralfkaa commented Jun 20, 2020

thanks, Alex. i realize MIDI is still experimental in QMK, but i was hoping someone might have had the same need and found a solution.
i'm going to experiment with macros, if i find a workaround to achieve this i will share it here.

@AlexOConnorHub
Copy link
Contributor

If you check out my fork, I made Keyboard handwired/ortho5x12. I made a custom midi keyboard layer where I store the octave, and make a 'custom' key that sends its notes at the octave specified. I didn't know that sending the same note at the same octave caused an error, so I need to make some keys send octave +1. You can check out out and see if anything there could help you out.

@ralfkaa
Copy link
Author

ralfkaa commented Jun 20, 2020

it doesn't cause an error, per se, but different DAWs treat a repeated note differently across platforms (i'm using Linux and Mac mainly). on a Mac running GarageBand the notes will both play simultaneously, but it activates a sustain effect that stays until you unplug the keyboard. on LMMS on Linux the second not simply won't play.
what is the name of your keyboard?

@AlexOConnorHub
Copy link
Contributor

https://github.com/AlexOConnorHub/qmk_firmware is my fork. (in the master branch) my files are in keyboards/handwired/ortho5x12

@ralfkaa
Copy link
Author

ralfkaa commented Jun 20, 2020

that's quite interesting.
you didn't use the quantum keycodes at all, you just defined your MIDI notes in the funcs.c file, then did an "include" in your keymap, is that correct?
i'm very much a dabbler when it comes to coding, so it's a bit difficult to understand how that works, but i presume you could have assigned different MIDI channels in your funcs.c file, couldn't you?
do you have speakers on your keyboard, or do you just play through a DAW (on or offline)?

@AlexOConnorHub
Copy link
Contributor

You understand that perfectly! I don't use quantum because of the constant channel and velocity. I made channel +/- and velocity +/- buttons. I checked the quantum buttons, and they call a midi send function. So I just call that function, but use what ever velocity /channel is selected currently. I don't have a keyboard yet, waiting on parts, so I keep adding to my keymap, hehe. I don't plan on having a speaker on my board, I'll just use a DAW.

@ralfkaa
Copy link
Author

ralfkaa commented Jun 20, 2020

would you mind my experimenting with a similar solution (provided i can wrap my head around your code)?
for the sake of clarification, i'm implementing an isomorphic (Wicki-Hayden) layout.

@AlexOConnorHub
Copy link
Contributor

Enjoy! I put it on git for that reason.

@ralfkaa
Copy link
Author

ralfkaa commented Jun 21, 2020

thanks! i will let you know how it goes and share the code (if it works...).

@AlexOConnorHub
Copy link
Contributor

Hey, I just split up that one file func.c into 3, because the one file was getting long, and I was really making 3 different new functions. now custom_midi.c has what I was doing with midi.

@AlexOConnorHub
Copy link
Contributor

*My keyboard is now in a branch called "custom-keyboard" on my fork.

@ralfkaa
Copy link
Author

ralfkaa commented Jun 26, 2020

hi Alex, your solution doesn't seem to work for me (perhaps because i understand it conceptually, but not in terms of actually developing the code). i need to set different channels for repeated notes by default.
i've experimented with ways of including two Quantum MIDI keycodes for a single key, and that didn't work.
now i'm looking at defining macros, which seems like a really convoluted way of going about this, but since i'm not a coder, that seems to be the only option open to me right now :-/

@ralfkaa
Copy link
Author

ralfkaa commented Jun 26, 2020

*My keyboard is now in a branch called "custom-keyboard" on my fork.

hi Alex, i have a technical question for you: there's a way to use a single keystroke to send a KC with a modifier, as in LCTL(kc).

could i just define LCTL(noteX) as "noteX on MIDI channel 2"? something like "if midi is on, define LCTL(noteX) as noteX played on midi channel 2".

any thoughts on this?

@AlexOConnorHub
Copy link
Contributor

Sorry I just got around to thinking about this...

So to respond to your first question, with my implementation, repeated notes are not sent on different channels. I just thought my project might provide a base for you to modify. While there might be a more efficient way to do this, one idea I can think of is making a boolean for each note, and if it is true, you could send on channel 2, if not, send on channel 1. I think you understand what my code does rather well, but I may have misrepresented what I made it do.

To reply to your second question, you can check if the left control modifier key is being pressed with (get_mods() & (MOD_BIT(KC_LCTL))) != 0. You then just need to add this as an if statement to your code.

@ralfkaa
Copy link
Author

ralfkaa commented Jul 9, 2020

Alex, thank you for your comments, and sorry for the delayed response!
I don't think a boolean for each note is a solution, because we're talking about 128 notes on 16 channels (to accommodate the full range of midi). If you then want to add, say, the possibility of quarter-tone notes, you have another 128 notes (in quarter-tone intervals) across the same 16 channels.
If I understand your last paragraph, in "common language" it would be: "if MIDI is active, define LCTL as MIDI channel 2". That would work for a few channels, but I would soon run out of modifier combinations.
So I really have to create a MIDI-specific set of commands with which I can define any note as "MIDIchannel(MIDInote)" in a keymap file. I suppose that means I'd have to fiddle with the process_midi files, which (not being a coder) puts me at risk of breaking things :-/
I will take a stab at it, and let you know how/if it creates something useful.
Thanks for engaging with me on this challenge!

@3araht
Copy link
Contributor

3araht commented Aug 29, 2020

on a Mac running GarageBand the notes will both play simultaneously, but it activates a sustain effect that stays until you unplug the keyboard.

It's a bit off from the main topic here but this happens on my setup, too.
I referred here to assign a chord to each key. It seems to happen when multiple chords are played and when the chords share the same note(s). I'm looking for a solution to avoid it.
When you are using GarageBand, the symptom can be fixed by clicking "Revert" button on the bottom left corner on the GarageBand window. But want to avoid it from the first place...

I raised this topic here.

@ralfkaa
Copy link
Author

ralfkaa commented Sep 5, 2020

on a Mac running GarageBand the notes will both play simultaneously, but it activates a sustain effect that stays until you unplug the keyboard.

It's a bit off from the main topic here but this happens on my setup, too.
I referred here to assign a chord to each key. It seems to happen when multiple chords are played and when the chords share the same note(s). I'm looking for a solution to avoid it.
When you are using GarageBand, the symptom can be fixed by clicking "Revert" button on the bottom left corner on the GarageBand window. But want to avoid it from the first place...

I raised this topic here.

the solution is to have the possibility to assign identical notes to different MIDI channels, but qmk doesn't support that functionality (yet). it only supports keyboard-wide channel up/down functions.
that said, if we bypass the higher-level definitions in quantum keycodes and address the underlying midi function, we should be able to add a table for repeat notes across different channels.
if i find a way to do that, i will post it here.

@3araht
Copy link
Contributor

3araht commented Sep 18, 2020

It seems I found a solution.
Can you take a look at this?
#10199 (comment)

@ralfkaa
Copy link
Author

ralfkaa commented Sep 18, 2020

It seems I found a solution.
Can you take a look at this?
#10199 (comment)

hi @3araht 3araht, i don't understand what your code does. can you explain the logic of what you did in plain language?

@3araht
Copy link
Contributor

3araht commented Sep 18, 2020

To be honest, I'm not 100% sure why this modification fixed the issue. I should say it just happened.
I guess something irregular happens when the same key is pressed before the first one being released.
Usually, normal keyboards don't have duplicate keys. The number keys on the upper row and num-pads are individual keys.
Probably handling duplicate keys are not well-developed because of such reason.

What I intended to do was to suppress the second or further midi_send_noteon() if the note is already turned on.
Does this make sense?

@ralfkaa
Copy link
Author

ralfkaa commented Sep 18, 2020

"suppress the second or further midi_send_noteon" makes sense, yes. but that wouldn't even be an issue if we found a way to send the same note on different MIDI channels. that's what i'm still shooting for ;-)

@ralfkaa
Copy link
Author

ralfkaa commented Nov 10, 2020

ok, i'm stuck.
hoping someone like @jackhumbert or @brandenbyers might indicate whether what i am trying to do is even possible with @qmk.
or whether one of them can point me to someone who might be able to help with this MIDI requirement.

@brandenbyers
Copy link
Contributor

I’m new to the concept of isomorphic midi keyboards but did a quick search and have a basic understanding now. My main question is: what is the benefit of having the same note on multiple channels playing at the same time as opposed to suppressing a duplicate note?

If multiple channels for the same midi key code is a requirement, does every key/note need to play on channel 1 unless it is a duplicate at which point it must play on the next unused channel for that note? Or could different switches that duplicate the same notes be hard coded to separate channels and always play on their respective channels?

How many repeats of the same notes are there on an isomorphic keyboard?

@ralfkaa
Copy link
Author

ralfkaa commented Nov 14, 2020

hi @brandenbyers , thanks for pitching in! and thanks for all the previous refinements you've contributed to the MIDI component!

the benefit is what is called "immutable fingering", meaning: you can move your hand around on a key array when transposing a piece (melody or chord) without having to find a new fingering because the piece doesn't "fit" within the keys you have left.

what you propose in the second paragraph would be an option, but it doesn't meet the expectation of the isomorphic musicians i've been in contact with. they expect the duplicates to be mapped across different channels: i will try to upload the suggested mapping one of them provided to illustrate (i'm not proficient with github, i may fail to do so).

as to your last question: the number of repeats would depend on the extent of the key array. the biggest arrays i've built for testing would require no more than 5 MIDI channels.

shot

@ralfkaa
Copy link
Author

ralfkaa commented Nov 14, 2020

as to why have repeat notes, and why not have a "rule" to silence repetitions: if you use two hands on a single keyboards, you may repeat a note, and you might want that to just go without issues.

i've played a bit and have found that different DAWs respond differently to a repeated not on the same MIDI channel: GarageBand will introduce a sustain, and the note will remain weird until you unplug and reconnect the keyboard. LMMS does something different, i cannot recall right now exactly what.

by the way, the above is a wicki-hayden layout. but repetition is a common event on the most common isomorphic layouts.

in hindsight, there's one isomorphic keyboard that would benefit from cancelling: the Jankó. the notes repeat every two rows, so you can finger consistently and comfortably. but you would NOT want the notes to repeat, you would want them to cancel as you suggest!

image

@brandenbyers
Copy link
Contributor

Ok, I think I now understand the scenario where silencing repeats wouldn’t work. Let me know if I’m understanding this correctly:

If a user presses a note on the right hand, and then presses the same note on the left hand, if the user lets up on the right hand, the left note should still be playing, right?

If the left note (the repeat of the right note) had been silenced, when lifting up on the right note, the left note would not be playing as expected.

If this scenario is correct, then I understand the need for a different solution.

@brandenbyers
Copy link
Contributor

brandenbyers commented Nov 14, 2020

Instead of channels and firmware, why not solve this problem in hardware? Wire all switches together that are the same midi key code. That way, the firmware will see each of those keys being pressed as the same key in code. So even if one of them lets up, the other(s) would still make the code think the same switch is still pressed.

Would that work? Or am I still missing something about why isomorphic users expect and/or need multiple channels?

@3araht
Copy link
Contributor

3araht commented Nov 14, 2020

Instead of channels and firmware, why not solve this problem in hardware? Wire all switches together that are the same midi key code. That way, the firmware will see each of those keys being pressed as the same key in code. So even if one of them lets up, the other(s) would still make the code think the same switch is still pressed.

Would that work? Or am I still missing something about why isomorphic users expect and/or need multiple channels?

Hi @brandenbyers, allow me to jump in.
Hardwiring is the simplest solution. However, it will kill the ability to change the keyboard layouts.
This is a keyboard I made. It is a MIDI keyboard of chromatic button accordion with no bellows. You can find an English description at the bottom.
After I released this keyboard kit, there were several layout requests to add to the new keymap layers.
This layout list is what I have at the moment.
One of the beauties of using QMK Firmware is flexibility so hardwiring is the last choice in my opinion.

I can tell this because actually, there are hardwired keys on the right side of my keyboard already, which limited the layout flexibility...
Well, I had to, to fit other features in Pro Micro but that is an irrelevant story here.

@3araht
Copy link
Contributor

3araht commented Nov 14, 2020

i've played a bit and have found that different DAWs respond differently to a repeated not on the same MIDI channel: GarageBand will introduce a sustain, and the note will remain weird until you unplug and reconnect the keyboard. LMMS does something different, i cannot recall right now exactly what.

Hi @ralfkaa, do you still have the sustain effect? It should be solved in the latest QMK firmware.
See here for the details of the temporary fix.

@3araht
Copy link
Contributor

3araht commented Nov 14, 2020

There are many amazing isomorphic layouts!!! Here are some.

Isomorphic keyboard

Chromatic Button Accordion

Chromatone

Wicki–Hayden note layout
Check here for s-ol's work, too.

Balanced keyboard

Jankó keyboard

The strategy which throws 2nd of further duplicate notes to other channels might work with some conditions.
But might not with others.
Ideally, just simply keep the notes ON if it is pressed, would be the versatile solution.

@ralfkaa
Copy link
Author

ralfkaa commented Nov 15, 2020

Ok, I think I now understand the scenario where silencing repeats wouldn’t work. Let me know if I’m understanding this correctly:

If a user presses a note on the right hand, and then presses the same note on the left hand, if the user lets up on the right hand, the left note should still be playing, right?

If the left note (the repeat of the right note) had been silenced, when lifting up on the right note, the left note would not be playing as expected.

If this scenario is correct, then I understand the need for a different solution.

hi @brandenbyers , this is correct for 2 of the 3 layouts i've been using: the Wicki-Hayden (first image above) and the Harmonic Table (see below). that's why these two layouts should permit activation of the same note on different keys.

but as i mentioned in my second message, this is not the case for the Jankó: for the Jankó you would want a repeat note (say, Y and B in "Mann's Virtual Jankó") to be simply ignored.

this is a complication i had honestly not thought about, nor run into yet, because the Jankó is a more linear (ascending left-to-right, like a regular piano keyboard) layout, and i am less likely to hit repeat notes by accident. it makes me think that perhaps the Jankó would have to be addressed on a different keyboard altogether (see below my answer to your other comments).

harmonictable

@ralfkaa
Copy link
Author

ralfkaa commented Nov 15, 2020

Instead of channels and firmware, why not solve this problem in hardware? Wire all switches together that are the same midi key code. That way, the firmware will see each of those keys being pressed as the same key in code. So even if one of them lets up, the other(s) would still make the code think the same switch is still pressed.

Would that work? Or am I still missing something about why isomorphic users expect and/or need multiple channels?

@3araht is aware of the issue: the keyboard in question has multiple layers. in @3araht 's case it's the different accordion layouts (and, i assume, an alphanumeric layout as well).

in my case it's at least 3 layers: alphanumeric, Wicki-Hayden, and Harmonic Table (i'm seriously considering dropping the Jankó for now, because it adds a different kind of complexity, and the two MIDI layouts are sufficient for my purpose: using the keyboard as a tool to teach theory and harmony).

@ralfkaa
Copy link
Author

ralfkaa commented Nov 15, 2020

so i'm looking at three possibilities (2 suggested by Dean Camera, two i've though of, but don't know whether they are feasible):

  1. a modifier that allows me to use "play the note X on channel Y" on a given layout, such as "channel3(note 62)" (per Dean Camera's first suggestion); i've tried variations such as (MI_CH1 | MI_C4) in layouts, but it doesn't work

  2. a table that maps the layout in coordinates, to which i can assign MIDI channel AND midi note (also from Dean Camera's comment);

  3. a way to assign different MIDI channels to different layers, using transparency so that a "top" layer includes notes in, say, channel 1, channel 2, and channel 3 by means of combining notes on three different layers (this is one way i imagine this could be done, but i still wouldn't know how to assign different midi channels to each layer...);

  4. defining the midi notes in quantum keycodes in channel-specific terms (say, there's a C4CH1 and a C4CH2); still, i don't know if/how that can be done, because there's a midi channel set to 0 elsewhere in a "process midi" file.

there may be other/better solutions. but something along these lines would make the MIDI functionality in QMK much more robust (for Wicki-Hayden, Harmonic Table, and the C-system and B-system chromatic accordions, in particular).

@ralfkaa
Copy link
Author

ralfkaa commented Nov 15, 2020

i've played a bit and have found that different DAWs respond differently to a repeated not on the same MIDI channel: GarageBand will introduce a sustain, and the note will remain weird until you unplug and reconnect the keyboard. LMMS does something different, i cannot recall right now exactly what.

Hi @ralfkaa, do you still have the sustain effect? It should be solved in the latest QMK firmware.
See here for the details of the temporary fix.

hi @3araht i haven't flashed new layouts recently, and my old mac got converted to a Fedora machine, so i'd have to give that a try. thanks for sharing.

but i still have to see what the effect is in, say, an open source DAW such as LMMS, or in online DAWs i've tested over time.

@ralfkaa
Copy link
Author

ralfkaa commented Nov 15, 2020

There are many amazing isomorphic layouts!!! Here are some.

Isomorphic keyboard

Chromatic Button Accordion

* [C-System](https://en.wikipedia.org/wiki/Chromatic_button_accordion#/media/File:C-Griff.svg)

* [B-System](https://en.wikipedia.org/wiki/Chromatic_button_accordion#/media/File:B-Griff.svg)

Chromatone

Wicki–Hayden note layout
Check here for s-ol's work, too.

Balanced keyboard

Jankó keyboard

The strategy which throws 2nd of further duplicate notes to other channels might work with some conditions.
But might not with others.
Ideally, just simply keep the notes ON if it is pressed, would be the versatile solution.

i hope this isn't creating more confusion, @3araht .

you are correct in that, as i stated previously, the Jankó needs a different solution. but the PRINCIPLE of MIDI is the ability to assign notes to up to 16 channels, so that should, IMHO, be the go-to solution for the issue of replicated notes across note arrays in isomorphic layouts.

more importantly, i researched this with professional musicians and music instructors who use isomorphic layouts extensively (except for Jankó, now that i think about it), and this is the solution they expect: throw duplicates onto different channels, and all is good.

@ralfkaa
Copy link
Author

ralfkaa commented Dec 4, 2020

hi @brandenbyers , just checking in: did you have any insights on how QMK might address this need?

@stale
Copy link

stale bot commented Mar 5, 2021

This issue has been automatically marked as stale because it has not had activity in the last 90 days. It will be closed in the next 30 days unless it is tagged properly or other activity occurs.
For maintainers: Please label with bug, in progress, on hold, discussion or to do to prevent the issue from being re-flagged.

@stale stale bot added the stale Issues or pull requests that have become inactive without resolution. label Mar 5, 2021
@ralfkaa
Copy link
Author

ralfkaa commented Mar 5, 2021

closing this though this is unresolved, and a clear requirement for any more serious use of MIDI on QMK mechanical keyboards...

@ralfkaa ralfkaa closed this as completed Mar 5, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted question stale Issues or pull requests that have become inactive without resolution.
Projects
None yet
Development

No branches or pull requests

4 participants