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

Add limited support for midi drums w/ rockband 3 #15054

Merged
merged 16 commits into from Feb 13, 2024

Conversation

nswarm
Copy link
Contributor

@nswarm nswarm commented Jan 16, 2024

This is an implementation for playing midi drums directly in rpcs3 with Rock Band 3 without the midi pro adapter. I've been playing on this version for a couple weeks and it's working great.

Caveats

  • This code is provided AS IS to help anyone looking for something similar, it's maybe not "production ready" and I'm not really interested in making it so atm.
  • This is based on my Alesis Nitro Max kit, the specific midi signals may vary across kits.
  • I have only tested on my kit on windows.

Configuration

Midi drums pulse width ms - how long each drum hit is "held" for. (default 30ms, which works great for me).

Combos

I added "combos" for some buttons that exist on the actual controller but not midi drums. Hitting these within 2 seconds without any other input will "click" the button.

START: hihat pedal x3 + snare rim
BACK: hihat pedal x3 + kick

I didn't do select/system button cause idk what you use them for.

I also haven't yet added hold pedal to bring up the category selector in the song list, but may eventually.

Hihat pedal

I opted to make use of the hihat:

  • hit while pedal down = yellow cymbal
  • hit while pedal up = blue cymbal

This seems to match many songs that chart the blue cymbal as either hihat open or ride cymbal. This way you can decide per song how to play it.

Cymbal/Drum flag issues

Rock band drums use the same bits for drum and cymbal colors, e.g. whether you hit green drum or cymbal, the same bit marker is sent. There are separate flag bits that get set to indicate if the hit is a cymbal vs drum.

The problem is if you hit both at the same time, a naive implementation will set both but the game will interpret both hits as either drum OR cymbal, not one of each.

My solution is just to buffer hits when they will collide with each other, which staggers one or the other 30ms (configurable pulse ms) behind the first. This seems to work fine. The timescale is too fast for humans to notice and rock band picks it up fine.

Changing to fit your drum kit

The constants in RB3MidiDrums.cpp midi namespace define the hex ids of the midi hits.

You can run this program to find out what your specific kit uses. It will connect to your midi device and print out the hex codes as you're hitting the drums:
https://github.com/nswarm/midichkr/releases/tag/1.0.0

Credits

@Megamouse Megamouse self-assigned this Jan 16, 2024
Copy link
Contributor

@Megamouse Megamouse left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good work, I haven't seen any major issues. Only needs some cleanup.

rpcs3/Emu/Io/RB3MidiDrums.cpp Outdated Show resolved Hide resolved
rpcs3/Emu/Io/RB3MidiDrums.cpp Outdated Show resolved Hide resolved
rpcs3/Emu/Io/RB3MidiDrums.cpp Outdated Show resolved Hide resolved
rpcs3/Emu/Io/RB3MidiDrums.cpp Outdated Show resolved Hide resolved
rpcs3/Emu/Io/RB3MidiDrums.cpp Outdated Show resolved Hide resolved
rpcs3/Emu/Io/RB3MidiDrums.cpp Outdated Show resolved Hide resolved
rpcs3/Emu/Io/RB3MidiDrums.cpp Outdated Show resolved Hide resolved
rpcs3/Emu/Io/RB3MidiDrums.cpp Outdated Show resolved Hide resolved
rpcs3/Emu/Io/RB3MidiDrums.cpp Outdated Show resolved Hide resolved
rpcs3/Emu/Io/RB3MidiDrums.cpp Outdated Show resolved Hide resolved
@DarkRTA
Copy link
Contributor

DarkRTA commented Jan 24, 2024

Rock band drums use the same bits for drum and cymbal colors, e.g. whether you hit green drum or cymbal, the same bit marker is sent. There are separate flag bits that get set to indicate if the hit is a cymbal vs drum.

The problem is if you hit both at the same time, a naive implementation will set both but the game will interpret both hits as either drum OR cymbal, not one of each.

The real kit sends a d-pad input when hitting the yellow cymbal and blue cymbal to avoid this issue. And the game will never chart a same colored cymbal and tom at the same time.

See: https://github.com/TheNathannator/PlasticBand/blob/main/Docs/Instruments/4-Lane%20Drums/PS3%20and%20Wii.md#input-info

@carlmylo
Copy link

carlmylo commented Jan 24, 2024

Amazing idea. I've brought this up to a few people that will hopefully be testing soon. I noticed the notes adhere to General MIDI spec, which is great as that has been standardized for quite some time. That being said, would it be possible to use the same mappings the official MIDI Pro Adapter uses? I think Harmonix did this specifically to help kits that had slightly off mapping and kits that use CC 4 for Hi-Hat pedal level.
image

@nswarm
Copy link
Contributor Author

nswarm commented Jan 24, 2024

The real kit sends a d-pad input when hitting the yellow cymbal and blue cymbal to avoid this issue. And the game will never chart a same colored cymbal and tom at the same time.

See: https://github.com/TheNathannator/PlasticBand/blob/main/Docs/Instruments/4-Lane%20Drums/PS3%20and%20Wii.md#input-info

huh neat, I sure wish I had found this earlier, thank you. I will likely get around to this in the next week or two.

That being said, would it be possible to use the same mappings the official MIDI Pro Adapter uses?

Sure.

@carlmylo
Copy link

carlmylo commented Jan 30, 2024

Regarding Start and Select. Would it be possible to have:

  • Hi-Hat CTRL (CC#4) Half: Select
  • Hi-Hat CTRL (CC#4) Fully Closed: Start?

To my knowledge, freestyle fills are the only place where the CC#4 pedal actually has an effect, which would help make Start and Select a bit more accessible. Understandable if this isn't possible.

Also, regarding testing, we've had three testers so far on Milohax with the following e-kits: Donner DED-20, and two Alesis Nitro Mesh kits.
The DED-20 was obviously an interesting case but, with MIDI-OX to change the notes, it worked.
Both Nitro Mesh users are noticing MUCH better performance compared to the previous method of connecting, which was using VJoy and MIDIDrumHero in conjunction, which led to dropped notes during rolls and other faster patterns. This build, on the other hand, is working flawlessly as far as they can tell.

@JReaper4590
Copy link

JReaper4590 commented Feb 2, 2024

I'm playing on an Alesis Turbo mesh kit and everything works great except for my hi-hat cymbal. Both my hi-hat and crash cymbal are playing blue cymbal notes while my irl ride cymbal is playing crash. My hi-hat pedal is also acting as another kick drum. Is there a way to fix or change this? Thanks

@nswarm
Copy link
Contributor Author

nswarm commented Feb 2, 2024

I'm playing on an Alesis Turbo mesh kit and everything works great except for my hi-hat cymbal. Both my hi-hat and crash cymbal are playing blue cymbal notes while my irl ride cymbal is playing crash. My hi-hat pedal is also acting as another kick drum. Is there a way to fix or change this? Thanks

iirc there's an "Enable hi-hat pedal" option in rb3 that changes it from kick to hihat. If that works then hit w/ hihat down = yellow, hit w/hihat up = blue cymbal

@JReaper4590
Copy link

I'm playing on an Alesis Turbo mesh kit and everything works great except for my hi-hat cymbal. Both my hi-hat and crash cymbal are playing blue cymbal notes while my irl ride cymbal is playing crash. My hi-hat pedal is also acting as another kick drum. Is there a way to fix or change this? Thanks

iirc there's an "Enable hi-hat pedal" option in rb3 that changes it from kick to hihat. If that works then hit w/ hihat down = yellow, hit w/hihat up = blue cymbal

This helps a ton, thanks so much. Is there by any chance a way to have it so I don't have to hold the pedal down to hit the hi-hat? If not, its alright. Thanks again!

@nswarm
Copy link
Contributor Author

nswarm commented Feb 5, 2024

With this update I added a number of things:

  • Removed my hacky drum/cymbal stagger thing, replaced with the correct dpad inputs to disambiguate cymbal/drum hits (thank you @DarkRTA )
  • Default midi mapping is now equivalent to the pro adapter mappings (thank you @carlmylo )
    • Note that my previous mapping had crash/ride swapped since my kit's crash is in the middle, but rockband calls that green (right).
  • Added a "hold kick" combo, which will mimic the kick pedal being held down until the combo is entered again, or the drum accept/cancel notes are hit.
    • This is for bringing up the category quick navigation in the song list
  • Added config for minimum velocity
  • Added config for combo maximum duration
  • Combos are now configurable with a comma-separated list of note inputs
    • See list of possible note names below.
    • e.g. "HihatPedal,HihatPedal,HihatPedal,Snare"
    • You can disable any combo by setting it to an empty string i.e. ""
  • All notes are now overridable in config
    • "Midi id to note override" is a comma-separated list of <midi_id>=<note_name>
    • Midi IDs are whatever your device outputs in decimal
    • Possible note names are below.
      • e.g. I have my crash and ride cymbals swapped (crash (green) is center for me)
      • my config looks like: "Midi id to note override": "49=Ride,51=Crash"
    • You can use a program like midichkr to see what midi ids your device outputs (you'll need to convert hex to decimal for config though)
  • Note that HihatWithPedalUp (midi id 46 on my kit) defaults to Ride
    • If you don't want to use the hihat pedal for this you can use this config:

Note names for use configuration

(combos or note overrides)

  • Kick
  • HihatPedal
  • Snare (red drum)
  • SnareRim
  • HiTom (yellow drum)
  • LowTom (blue drum)
  • FloorTom (green drum)
  • HihatWithPedalUp
  • Hihat (yellow cymbal)
  • Ride (blue cymbal)
  • Crash (green cymbal)

Example Configuration

Input/Output:
  Rockband 3 Midi Drums:
    Pulse width ms: 30
    Minimum velocity: 10
    Combo window in milliseconds: 2000
    Midi id to note override: "49=Ride,51=Crash"
    Combo Start: HihatPedal,HihatPedal,HihatPedal,Snare
    Combo Select: HihatPedal,HihatPedal,HihatPedal,SnareRim
    Combo Toggle Hold Kick: HihatPedal,HihatPedal,HihatPedal,Kick

Midi CC#4

@carlmylo I don't have a device that outputs this midi signal, so I'm unable to test it. I could theorize from the midi spec, but If you could give an example of the bytes output by pressing the CC#4 fully down and (separately) halfway down (using midichkr or equivalent) I could probably add some sort of support for it.

The main thing I'm unsure of is how the 'continuous control' factor looks in bytes and if it's constantly sending data or only when it changes or something. Right now I listen for single midi messages for each note so I might need some sort of threshold + state tracking.

@TheNathannator
Copy link

Caught wind of this just a moment ago and thought I'd share info lol

The main thing I'm unsure of is how the 'continuous control' factor looks in bytes and if it's constantly sending data or only when it changes or something. Right now I listen for single midi messages for each note so I might need some sort of threshold + state tracking.

The values are an axis ranging from 0 to 127; controls 0-31 and 32-63 can be combined into high/low bytes respectively to create a 14-bit axis (0-16383), but for the purposes here that can probably be ignored.

CC messages are only sent on value change, some state tracking will be necessary. MIDI in general does not send data continuously, the only messages that do this are active sense (optionally sent at least every 300 ms to indicate device presence) and MIDI Time Code messages.

While I don't have an e-kit to verify/demonstrate with, I have a RB3 keyboard which is capable of sending CC messages with its touchbar and pedal port:

image

@DarkRTA
Copy link
Contributor

DarkRTA commented Feb 5, 2024

Removed my hacky drum/cymbal stagger thing, replaced with the correct dpad inputs to disambiguate cymbal/drum hits (thank you @DarkRTA)

I still recommend automatically staggering double cymbal hits. The game has been known to drop inputs this scenario and it is a problem that has consistently annoyed top level drummers.

@nswarm
Copy link
Contributor Author

nswarm commented Feb 5, 2024

@TheNathannator thank you!

@DarkRTA you mean hitting two different cymbals at the same time? or one cymbal hit registering twice?

@DarkRTA
Copy link
Contributor

DarkRTA commented Feb 6, 2024

@DarkRTA you mean hitting two different cymbals at the same time? or one cymbal hit registering twice?

Hitting two different cymbals at the same time.

@JReaper4590
Copy link

How do I download the new update? Sorry I'm new to github

rpcs3/Emu/Io/RB3MidiDrums.cpp Outdated Show resolved Hide resolved
rpcs3/Emu/Io/RB3MidiDrums.cpp Outdated Show resolved Hide resolved
rpcs3/Emu/Io/RB3MidiDrums.cpp Outdated Show resolved Hide resolved
rpcs3/Emu/system_config.h Outdated Show resolved Hide resolved
@nswarm
Copy link
Contributor Author

nswarm commented Feb 11, 2024

  • Added back staggering for double cymbal hits. There's a new config to turn this off.
  • Moved drums config to its own file rb3drums.yml
  • Added support for midi CC triggering a note

Midi CC I can't really test, but this should support most use cases. New config to control:

  • midi_cc_status defines the status byte, defaults to 0xB0.
  • midi_cc_number defines the control number, defaults to 4 which is usually used for a foot pedal.
  • midi_cc_threshold defines the minimum value the control must pass to be considered 'triggered'. It will not be triggered again until after the value drops below this threshold again.
  • midi_cc_invert_threshold inverts the threshold requirement, i.e. if your pedal is at 127 when up and 0 when pressed down, this will cause it to trigger when the value becomes lower than the threshold.
  • The Midi CC defaults to the Kick pedal at a threshold of 64 (halfway). It can be overridden in config with the note value 255, e.g. "Midi id to note override": "255=HihatPedal"

@LinosM
Copy link

LinosM commented Feb 11, 2024

I would like to make the suggestion to have open hi-hats back on Yellow by default, since that's what the MPA does and most casual users are not going to be using the hi-hat pedal at all for gameplay. Just about everyone on the MiloHax Discord testing this build wanted to change it so I figured for a better "plug and play" experience it would be best to revert that.

rpcs3/Emu/Cell/lv2/sys_usbd.cpp Outdated Show resolved Hide resolved
rpcs3/Emu/Io/RB3MidiDrums.cpp Outdated Show resolved Hide resolved
@nswarm
Copy link
Contributor Author

nswarm commented Feb 11, 2024

@JReaper4590 you can probably dig into the automated builds on this PR to find built artifacts.

@LinosM agree, changed.

@Megamouse thanks for all the feedback.

@Megamouse
Copy link
Contributor

Needs a rebase

@Megamouse
Copy link
Contributor

you have conflicts. that's why I said you have to rebase.

@nswarm
Copy link
Contributor Author

nswarm commented Feb 11, 2024

sorry didn't see comment before. rebased now

@Megamouse Megamouse merged commit 8533f96 into RPCS3:master Feb 13, 2024
6 checks passed
@hrzhu
Copy link

hrzhu commented Feb 14, 2024

I don't why the CI builds succeed but I have to add #include <optional> to /rpcs3/Emu/Io/RB3MidiDrums.h to make rpcs3 to compile on my local machine.

@carlmylo
Copy link

I know this is merged and it has been amazing so far! There was something I forgot to bring up. There currently is no way to handle D-Pad Left or D-Pad Right, which makes trainers hard to navigate. Slowing tracks down in practice mode is also impossible.

Would it be possible to implement another set of combos? Perhaps HihatPedal, HihatPedal, HihatPedal, HiTom for D-Pad Left and HihatPedal,HihatPedal,HihatPedal,LoTom for D-Pad Right? This would obviously not be an issue on an actual MIDI Pro Adapter since it had dedicated D-Pad buttons.

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

Successfully merging this pull request may close these issues.

None yet

8 participants