Giter VIP home page Giter VIP logo

minis's Introduction

Minis: MIDI Input for New Input System

gif gif

Minis (MIDI Input for New Input System) is a Unity plugin that adds MIDI input device support to Unity's new Input System.

System Requirements

  • Unity 2019.3 or later
  • 64-bit desktop platforms (Windows, macOS, Linux)

On Linux, ALSA (libasound2) must be installed on the system.

How To Install

This package uses the scoped registry feature to resolve package dependencies. Please add the following sections to the manifest file (Packages/manifest.json).

To the scopedRegistries section:

{
  "name": "Keijiro",
  "url": "https://registry.npmjs.com",
  "scopes": [ "jp.keijiro" ]
}

To the dependencies section:

"jp.keijiro.minis": "1.0.10"

After changes, the manifest file should look like below:

{
  "scopedRegistries": [
    {
      "name": "Keijiro",
      "url": "https://registry.npmjs.com",
      "scopes": [ "jp.keijiro" ]
    }
  ],
  "dependencies": {
    "jp.keijiro.minis": "1.0.10",
    ...

How To Use

Input Controls

When Minis is installed to a project, MIDI control elements appear under "Other" > "MIDI Device". You can also use the "Listen" button to select a control.

gif

TIPS - There is a small known issue where the listener only reacts to notes with high velocity (higher than 63). You may have to press a key strongly.

The MIDI Notes are shown as button controls with names like "Note C4". These controls work as pressure-sensitive buttons. These button values are normalized as values between 0.0 to 1.0.

The MIDI Controls (CC) are shown as axis controls with names like "Control 10". These axis values are normalized as values between 0.0 to 1.0.

For further usage of the new Input System, please see the Input System manual.

MIDI Channels

Minis treats each MIDI channel as an individual device. MIDI devices are dynamically added to the Input System when it detects a MIDI message from a new channel.

TIPS - It means that the Input System can't detect a MIDI device until it sends a message. You may have to prompt the user to press a key to activate the device.

When multiple MIDI interfaces are connected to the system, channels under these interfaces are also treated as individual devices. For instance, if you have connected two MIDI interfaces to a computer, you can use up to 32 input devices at the same time (as each interface can handle up to 16 channels).

MIDI Device Assigner

inspector

MIDI Device Assigner is a small utility that assigns a MIDI device to PlayerInput. You can specify a MIDI channel and a product name as a search condition. It assigns a found device to a PlayerInput instance that exists in the same GameObject.

Scripting Examples

This repository contains some examples showing how to use Minis from C# scripts.

DeviceCallback.cs - This script shows how to define a callback to get notified on MIDI device additions and removals.

DeviceQuery.cs - This script shows how to search MIDI devices by a pattern matching with a product name and a channel number.

NoteCallback.cs - This script shows how to define a callback to get notified on MIDI note-on/off events.

Frequently Asked Questions

Does it support MIDI out?

No, but the backend (RtMidi) supports MIDI out. You can use the output functionality by directly accessing it. Please check the RtMidi for Unity repository that contains a MIDI out sample script.

minis's People

Contributors

keijiro avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

minis's Issues

Free?

I want to use this Assets for my application.
Using this Assets is free?

Can't receive Midi Clock messages

I wanted to add the receival of Midi Clock messages, so in my fork I've added a check for status == 0xF8 in MidiPort#ProcessMessageQueue and also added 'RtMidiDll.InIgnoreTypes(_rtmidi, false, false, false);' after RtMidiDll.Openport in the same class (apparently timing messages are ignored by default by RtMidi). However I'm still not receiving midi clock messages and I don't really see what else could be the problem, do you have an idea by any chance?

The input debugger doesn't detect my device based on the clock messages, only when I send notes/ccs on the same device.

Note number delayed

Is it just me or does a note change come 3 note changes too late?
the noteNumber seems to get updated later than the note on call.

Cannot get Midi input to call function through Actions and C#

I'm currently testing the ability to use a midi controller as input using minis, and I am running into a major issue. I have an Action set named jump setup in Unity with both my spacebar on my keyboard, and a pad on my midi controller mapped to it. As for the action "Jump", I have its input set to any so that both inputs should work. However, only the spacebar calls my "OnJump" function, while the midi pad does not. Is this a bug?
actions
playercs

Human readable device name specification

As suggested in #14 (comment) I tried to use this with a nanoKONTROL2. In the input debugger it shows up like this:

image

So I tried #(nanoKONTROL2 SLIDER/KNOB*Channel 0)/control001 but unfortunately, that doesn't work. The control changes are not coming through.

This method does work for me with a different controller though: #(XONE:K2 Channel 14)/control04

Thanks in advance.

Instantaneous Inputs Don't Change `wasPressedThisFrame`

Hello,

While adding drum support to my game, I noticed that the wasPressedThisFrame value was not changing when hitting the drums pads or cymbals. My assumption is that any “instantaneous inputs” (as in, inputs that can't be held down) update too fast for it to be detected by wasPressedThisFrame, which is evident as my piano inputs are detected, and the onWillNoteOn event is also called.

For now, I can just use the onWillNoteOn events, but I thought I'd let you know that this issue exists anyway.

Thanks.

Retrigger animation without waiting the end of it

Hello everyone, I'm using the Minis package to trigger an animation with a midi controller but i have to wait until the end of the animation to trigger it again. How can I retrigger an animation without waiting the end of it ? Thank you.

UWP and x86?

I'm attempting to develop a Unity app that targets Hololens 1st gen and was wondering if Minis supports that.

Specifically, HoloLens 1 requires applications to be an x86 UWP as well as Midi Over Bluetooth connection.

Issue finding a way of "unpairing" or deallocating midi device

Hello,

I am currently having an issue figuring out how to deallocate the usage of a midi device, as I want the process to be a little bit dynamic if possible. Basically, if I connect the device and my game detects it, no other device will be able to use the midi device until the game is closed. I don't want to always be using the midi device in the game, so when I close the part that is meant to use my midi keyboard I want the device usage to be freed as well.

I tried to do different things, mainly trying to remove the device from unity usage using the InputSystem class, but that does not free up the device. Is this possible to do in any way, and also possible to attempt to access the device once it is needed again? I am able to elaborate this question more if needed.

Thank you in advance.

P.S. Amazing plugin, thank you so much for making it!

Control of two midi controllers

I tried to use Minis to control two midi controllers.
It behaves like a conflict.
The problem: After operating the CC of the midi controller with the Action registered, operating any CC of the other unregistered midi contoroller will cause the CC of the midi controller with the Action registered to stop responding.

The event occurs when the following steps are taken.

  1. Attach ScaleByInputValue.cs(Sample Script) to an arbitrary 3D object.
  2. Go to Inspector>ScaleByInputValue>Action and attach to any CC(at midi controller No.1).
  3. Press the Play button and operate the CC registered in step 2 (at this point, it is confirmed to work properly).
  4. Operate any CC of the midi Controller(at midi controller No.2) that is not registered in 2.
  5. The 3D Object does not respond when manipulating the CC of the midi Controller(at midi controller No.1) registered in 5.2.

The above event did not occur with midiJack.
Is there something wrong with my settings?

Not an issue, but a question on android/quest

Hi, firstly thanks for making these, they are really useful! I have integrated minis into a unity project and all works well, however I am building out to a Quest 2 and want it to recognise the midi, preferably from a direct cable connection. Someone told me minis does not support android, is there a workaround for this or the same question if using midijack? Any help would be greatly appreciated!

How to bind or access Sustain Pedal state

Hi, I would like to know if it's possible to bind a Sustain pedal press or access its current state using this plugin. Using the Notecallback example I don't get any response when pressing or releasing it. Considering that DAWs have a way to access this state I was wondering if this could be achieved with this plugin.

(For reference I am using a KAWAI KDP120 Keyboard connected with a UM-ONE USB MIDI Interface)

Simultaneous midi pad presses causes a .5 second input delay, or no input at all - In build but not editor

Hi,

I am using Akai MPD218 usb midi controller on MacOS (tested on intel 64 bit and apple silicon with the same result). When I press or hold 1-2 midi pads, the note on message is received and processed quickly. When 3 or more simultaneous pad presses occur, there is a massive input buffer, lasting up to >1 second, sometimes to the point that the input is discarded entirely. I have a suspicion that the input queue for rtmidi is being exhausted by "note hold" messages, because on the unity side, every works great in the input debugger. The other strange thing is that this issue does not appear when running play mode within the editor, however I noticed that there was a second "editor loop" that is instantiated under this instance. The rtmidi documentation mentions that a callback function ought to be assigned to prevent messages being lost in the queue and I did not see that happen while looking through the scripts.

thanks!

Parsing different channels (virtual MIDI ports)

I am using virtual midi ports ( loopMIDI app). I have midi coming out of a DAW from different channels. I a PlayerInput for each object I want to animate via midi. I attached a Midi Device Assigner to each object
image

Then I have a simple script to get the player Input data and change the transform

public class ObjectController : MonoBehaviour
{
    private PlayerInput playerInput;
    private InputAction getCC5;
    private InputAction getCC9;
    public Vector3 displace; 

    private void Awake()
    {
        playerInput = GetComponent<PlayerInput>();
        getCC5 = playerInput.actions["GetCC5"];
        getCC9 = playerInput.actions["GetCC9"];

    }
    void Update()
    {
        float cc5 = getCC5.ReadValue<float>();
        float cc9 = getCC5.ReadValue<float>();
        Vector3 pos = new Vector3(0, cc9, cc5);
        transform.position = pos + displace;
    }
}

The different channels assigned in the Midi Device Assigner don't seem to affect the object though.
What am I missing?

[noob] basic implementation unclear from the documentation

Keijiro san, sorry for a question that is likely trivial. I am trying to setup a template for a keyboard, both from a new 2D project and referencing your "minis-master." Minis appears to be set up the same in both. I am failing to understand how to assign the midi input to a sprite (key), nor can I find the menu GUI you show in the beginning of your documentation (https://unitylist.com/p/sds/Minis).

For a keyboard of any size, do I assign the scripts under Minis--runtime to each key, to the group that contains all keys, or somewhere else? My first goal would be to assign a trigger to one octave of piano keys, accepting any octave from the input keyboard source.

I would be grateful for any hep you can give, and would be happy to share my additional documentation and basic keyboard template with you in return.
Thank you.

How to get value of MIDI keyboard key

Hi Keijiro,

Awesome work as always, I was wondering if it was possible to get the current state of a MIDI key (raw or normalized). I'm trying to replicate in the game-world how 'deeply pressed' the key currently is and both MidiNoteControl and MidiValueControl don't seem to hold this value.

I understand that some MIDI devices don't have range/axis like a MIDI piano does, so I'm not sure if the information is even available. Regardless, I would love to know for sure.

Can't trigger midi keyboard on Scale By Input Value

In the sample scene I get to trigger Note E2 using PlayByInputAction.cs using my midi keyboard.
However in the same sample scene I get nothing logged in the console from ScaleByInputValue.cs. I know I've seen this script printing to the console just fine before but it is so random and unpredictable.

Any ideas about how to make it 100% reliable? I truly don't know what's going on. Why does PlayByInputAction work just fine all the time an ScaleByInputValue doesn't?

Any ideas?

Thanks
ps: I am on windows 10 Unity 2020.3.25

Add events for controls like there are for notes

MidiDevice has two lovely c# events -- onWillNoteOn and onWillNoteOff. However, the only way to watch for changes in midi controls is to manually loop through the values in GetControl(int controlNumber). It would be very nice if controls had an event like notes do.

Crash in MidiDevice.FinishSetup due to null product

        // MIDI channel number determination
        // Here is a dirty trick: Parse the last two characters in the product
        // name and use it as a channel number.
        var product = description.product;
        channel = int.Parse(product.Substring(product.Length - 2));

The product for my MIDI device is null, so this code crashes.

Adding

Debug.Log($"{description}|||{description.product}");

under the var product line results in:

<Empty Device Description>|||

The device is an Arturia KeyStep: https://www.arturia.com/keystep/overview

No license

This repository does not have a license.

Mobile Support ? (Android / IOS)

Hello ! firstly, very nice work you do here !

I'm working on a music application that will use MIDI keyboard input (via USB). I'm wondering if the library you're making available for Unity is compatible with mobile platforms, especially Android and IOS in a second step?

best regards.

Control (CC) input not showing up

So im trying to map my nanoKontrol2 inputs to unity input system.
The "listen" function of input system does not work, however if i manually input the correct notes, unity does recognize the inputs from my nanoKontrol2.
However, the sliders cannot be mapped to notes, and i cannot manually put it in the control (CC) inputs.
How can i fix this?

Demo available?

The README shows a fireworks demo, is that available in this package?

Thanks!

Performance issues on Android

I'm using your plugin, thanks by the way, to help with the level editor of a rhythm game. However, when I build into Quest, the performance is noticeable cause it goes into build. ¿Can you make a check to select platform? I don't even know if android can handle MIDI.

Changing control values / infinite twisting

I've got a wee problem with a specific implementation.

I'm trying to use one of the knobs to change the forward direction of a character in unity. The idea being that you twist the knob, and the character will rotate in that direction. I was thinking I would do a little bit of logic where if the new value is greater than the previous, turn one direction, or if the new value is less than the previous, turn the other direction.

midiDevice.onWillControlChange += RotateCharacter;

However I have an issue where, let's say, I keep twisting right (I don't know how other midi controllers work, but I can infinitely twist the knobs in any direction on mine) the control value will reach 1 and will be stuck at that value. If the player twists to that point, and wants to keep twisting to further spin the character they won't be able to, RotateCharacter is not run when the min/max value is reached.

Is there some other way I can get the direction the knob is twisting? One idea I had would be to reset the knobs value to something like 0.5, but is it possible to do that?

Cheers

Guitar Strings

I wanted to know if or how i can find out on what string on the guitar a note has been played. Thanks for the answer :)

Event handler can't unbind itself

Pretty straightforward, in MidiDevice.cs the event handler callbacks are iterated over, which means that if an event handler removes itself from the handler list, an exception will be thrown. Simple example:

public class MidiTester : MonoBehavior {
    public MidiDevice device;

    private void Awake()
    {
        var match = new InputDeviceMatcher().WithInterface("Minis");
        foreach (InputDevice dev in InputSystem.devices){
            if (match.MatchPercentage(device.description) > 0)
                device = dev as MidiDevice;
        }

        device.onWillNoteOn += FirstAction
    }

    private void FirstAction(MidiNoteControl note, float value)
    {
        Debug.Log("First press");
        device.onWillNoteOn -= FirstAction;
        device.onWillNoteOn += SecondAction;
    }

    private void SecondAction(MidiNoteControl note, float value)
    {
       Debug.Log("Later presses");
    }
}

CollectionIterationError

possible to support InputDevice.canRunInBackground when Application.runInBackground = true?

The way I'm using Mini requires the Unity process to run in the background (without window focus). I'm noticing that no midi input is detected when this occurs.

I traced it to InputDevice canRunInBackground being false for MidiDevice. It isn't clear to me how a custom InputDevice should be setup for QueryCanRunInBackground with the InputSystem (was first trying to modify Mini's to support it).

I ended up making the Input system a local package and forcing it to always accept background input (line 2424 of InputManager.cs ) as a workaround, but this isn't ideal.

Although that works, it behaves like there are 2 separate states for background and focused. For example, a knob in the background state updates the value, and then if Unity regains focus, the value jumps to what it was when Unity last had focus, and then the reverse for going back to unfocused.

Curious if you have any insight into this, if it could be supported in Minis or if it is a shortcoming of the new InputSystem.

About Android

Are there any plans for Minis to support Android?
I've seen the issue #3 for iOS, but I'd like to ask about Android.

Multiple MIDI devices all register as the same device and multiple channels don't fix it

I have two MIDI devices that I'm using at the same time and they both register as one device (so any notes mapped to both will trigger from either device). I saw a possible fix for this issue here #14 but one thing I noticed in the readme is that "Minis treats each MIDI channel as an individual device" so I tried changing the channel on both of them but still have the same issue. It seems like channel isn't taken into account when reading from either device. I know pressing the "T" and manually changing the name should work (maybe even adding in the channel manually?) but I'm mapping a ton of buttons and it feels like a slightly frail and tedious way to do it. Am I missing something with how channels work?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.