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

Implement MIDI input support #2804

Merged
merged 26 commits into from
May 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
748dd68
Implement MIDI input
holly-hacker Aug 28, 2019
8f4ff56
Don't throw if MIDI input cannot be initialized (eg. missing asound)
holly-hacker Aug 28, 2019
d1d88ff
Enable MidiInputHandler for Android and iOS
holly-hacker Aug 28, 2019
b67a97b
Handle Running Status messages
holly-hacker Aug 29, 2019
5e7cab0
Handle midi event edge cases
holly-hacker Aug 29, 2019
0c43156
Include velocity in Midi events
holly-hacker Aug 29, 2019
14d2d11
Move MidiInputHandler to correct namespace
holly-hacker Aug 29, 2019
0a16a99
Manually (and properly) parse MIDI messages
holly-hacker Aug 29, 2019
068b07f
Fix code style issues
holly-hacker Aug 29, 2019
a22e62e
Remove remaining TODO comment
holly-hacker Aug 29, 2019
21d6ada
Fix missing imports in Android and iOS projects
holly-hacker Aug 29, 2019
c11b145
Add Midi keys to InputKey
holly-hacker Aug 29, 2019
78b1c63
Remove accidental using statement
holly-hacker Aug 29, 2019
c669b13
Track Midi events in FrameStatistics
holly-hacker Aug 29, 2019
6f588aa
Update managed-midi to 1.9.6
holly-hacker Sep 5, 2019
0a408fd
Merge remote-tracking branch 'origin/master' into midi-input
smoogipoo Sep 10, 2019
feeda0a
Update managed-midi
smoogipoo Sep 10, 2019
dd1ad39
Merge branch 'master' into midi-input
smoogipoo Apr 27, 2020
3c154a8
Remove unnecessary clone
smoogipoo Apr 27, 2020
c633835
Update managed-midi
holly-hacker May 2, 2020
fc54002
Fix return parameter of OnMidiUp, add doc comments
holly-hacker May 2, 2020
aac4366
Use ButtonEventManager instead of manually calling handleMidiKey*
holly-hacker May 2, 2020
cc44d6c
Improve error handling in case of invalid MIDI messages
holly-hacker May 2, 2020
6769cd1
Fix up debug logging
holly-hacker May 2, 2020
b7fcba7
Merge branch 'master' into midi-input
smoogipoo May 3, 2020
89ad557
Make velocities public
smoogipoo May 3, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion osu.Framework.Android/AndroidGameHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
using osu.Framework.Graphics.Video;
using osu.Framework.Input;
using osu.Framework.Input.Handlers;
using osu.Framework.Input.Handlers.Midi;
using osu.Framework.IO.Stores;
using osu.Framework.Platform;
using osu.Framework.Threading;
Expand Down Expand Up @@ -56,7 +57,7 @@ public override ITextInputSource GetTextInput()
=> new AndroidTextInput(gameView);

protected override IEnumerable<InputHandler> CreateAvailableInputHandlers()
=> new InputHandler[] { new AndroidKeyboardHandler(gameView), new AndroidTouchHandler(gameView) };
=> new InputHandler[] { new AndroidKeyboardHandler(gameView), new AndroidTouchHandler(gameView), new MidiInputHandler() };

protected override Storage GetStorage(string baseName)
=> new AndroidStorage(baseName, this);
Expand Down
103 changes: 103 additions & 0 deletions osu.Framework.Tests/Visual/Input/TestSceneMidi.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using System;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Input;
using osu.Framework.Input.Events;
using osuTK;
using osuTK.Graphics;

namespace osu.Framework.Tests.Visual.Input
{
public class TestSceneMidi : FrameworkTestScene
{
public TestSceneMidi()
{
var keyFlow = new FillFlowContainer
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
};

for (MidiKey k = MidiKey.A0; k < MidiKey.C8; k++)
keyFlow.Add(new MidiKeyHandler(k));

Child = keyFlow;
}

protected override bool OnMidiDown(MidiDownEvent e)
{
Console.WriteLine(e);
return base.OnMidiDown(e);
}

protected override void OnMidiUp(MidiUpEvent e)
{
Console.WriteLine(e);
base.OnMidiUp(e);
}

protected override bool Handle(UIEvent e)
{
if (!(e is MouseEvent))
Console.WriteLine("Event: " + e);
return base.Handle(e);
}

private class MidiKeyHandler : CompositeDrawable
{
private readonly Drawable background;

public override bool HandleNonPositionalInput => true;

private readonly MidiKey key;

public MidiKeyHandler(MidiKey key)
{
this.key = key;

Size = new Vector2(50);

InternalChildren = new[]
{
background = new Container
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.DarkGreen,
Alpha = 0,
Child = new Box { RelativeSizeAxes = Axes.Both }
},
new SpriteText
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Text = key.ToString().Replace("Sharp", "#")
}
};
}

protected override bool OnMidiDown(MidiDownEvent e)
{
if (e.Key != key)
return base.OnMidiDown(e);

const float base_opacity = 0.25f; // to make a velocity of 1 not completely invisible

background.FadeTo(base_opacity + e.Velocity / 128f * (1 - base_opacity), 100, Easing.OutQuint);
return true;
}

protected override void OnMidiUp(MidiUpEvent e)
{
if (e.Key != key)
base.OnMidiUp(e);
else
background.FadeOut(100);
}
}
}
}
5 changes: 3 additions & 2 deletions osu.Framework.iOS/IOSGameHost.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using System;
Expand All @@ -13,6 +13,7 @@
using osu.Framework.Input;
using osu.Framework.Input.Bindings;
using osu.Framework.Input.Handlers;
using osu.Framework.Input.Handlers.Midi;
using osu.Framework.IO.Stores;
using osu.Framework.iOS.Graphics.Textures;
using osu.Framework.iOS.Graphics.Video;
Expand Down Expand Up @@ -97,7 +98,7 @@ protected override void PerformExit(bool immediately)
public override ITextInputSource GetTextInput() => new IOSTextInput(gameView);

protected override IEnumerable<InputHandler> CreateAvailableInputHandlers() =>
new InputHandler[] { new IOSTouchHandler(gameView), keyboardHandler = new IOSKeyboardHandler(gameView), rawKeyboardHandler = new IOSRawKeyboardHandler() };
new InputHandler[] { new IOSTouchHandler(gameView), keyboardHandler = new IOSKeyboardHandler(gameView), rawKeyboardHandler = new IOSRawKeyboardHandler(), new MidiInputHandler() };

protected override Storage GetStorage(string baseName) => new IOSStorage(baseName, this);

Expand Down
23 changes: 23 additions & 0 deletions osu.Framework/Graphics/Drawable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2034,6 +2034,13 @@ public bool TriggerEvent(UIEvent e)
OnJoystickRelease(joystickRelease);
return false;

case MidiDownEvent midiDown:
return OnMidiDown(midiDown);

case MidiUpEvent midiUp:
OnMidiUp(midiUp);
return false;

default:
return Handle(e);
}
Expand Down Expand Up @@ -2194,6 +2201,22 @@ public bool TriggerEvent(UIEvent e)
/// <param name="e">The <see cref="JoystickReleaseEvent"/> containing information about the input event.</param>
protected virtual void OnJoystickRelease(JoystickReleaseEvent e) => Handle(e);

/// <summary>
/// An event that occurs when a <see cref="MidiKey"/> is pressed.
/// </summary>
/// <param name="e">The <see cref="MidiDownEvent"/> containing information about the input event.</param>
/// <returns>Whether to block the event from propagating to other <see cref="Drawable"/>s in the hierarchy.</returns>
protected virtual bool OnMidiDown(MidiDownEvent e) => Handle(e);

/// <summary>
/// An event that occurs when a <see cref="MidiKey"/> is released.
/// </summary>
/// <remarks>
/// This is guaranteed to be invoked if <see cref="MidiDownEvent"/> was invoked.
/// </remarks>
/// <param name="e">The <see cref="MidiUpEvent"/> containing information about the input event.</param>
protected virtual void OnMidiUp(MidiUpEvent e) => Handle(e);

#endregion

/// <summary>
Expand Down
Loading