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

Improve all documentation about MIDI support #86693

Merged
merged 1 commit into from
Jan 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
43 changes: 24 additions & 19 deletions doc/classes/@GlobalScope.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2522,61 +2522,66 @@
The maximum number of game controller axes: OpenVR supports up to 5 Joysticks making a total of 10 axes.
</constant>
<constant name="MIDI_MESSAGE_NONE" value="0" enum="MIDIMessage">
Enum value which doesn't correspond to any MIDI message. This is used to initialize [enum MIDIMessage] properties with a generic state.
Does not correspond to any MIDI message. This is the default value of [member InputEventMIDI.message].
</constant>
<constant name="MIDI_MESSAGE_NOTE_OFF" value="8" enum="MIDIMessage">
MIDI note OFF message. Not all MIDI devices send this event; some send [constant MIDI_MESSAGE_NOTE_ON] with zero velocity instead. See the documentation of [InputEventMIDI] for information of how to use MIDI inputs.
MIDI message sent when a note is released.
[b]Note:[/b] Not all MIDI devices send this message; some may send [constant MIDI_MESSAGE_NOTE_ON] with [member InputEventMIDI.velocity] set to [code]0[/code].
</constant>
<constant name="MIDI_MESSAGE_NOTE_ON" value="9" enum="MIDIMessage">
MIDI note ON message. Some MIDI devices send this event with velocity zero instead of [constant MIDI_MESSAGE_NOTE_OFF], but implementations vary. See the documentation of [InputEventMIDI] for information of how to use MIDI inputs.
MIDI message sent when a note is pressed.
</constant>
<constant name="MIDI_MESSAGE_AFTERTOUCH" value="10" enum="MIDIMessage">
MIDI aftertouch message. This message is most often sent by pressing down on the key after it "bottoms out".
MIDI message sent to indicate a change in pressure while a note is being pressed down, also called aftertouch.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Unsure between this and
"MIDI message sent when a note's pressure changes while it is being pressed down" or similar

</constant>
<constant name="MIDI_MESSAGE_CONTROL_CHANGE" value="11" enum="MIDIMessage">
MIDI control change message. This message is sent when a controller value changes. Controllers include devices such as pedals and levers.
MIDI message sent when a controller value changes. In a MIDI device, a controller is any input that doesn't play notes. These may include sliders for volume, balance, and panning, as well as switches and pedals. See the [url=https://en.wikipedia.org/wiki/General_MIDI#Controller_events]General MIDI specification[/url] for a small list.
</constant>
<constant name="MIDI_MESSAGE_PROGRAM_CHANGE" value="12" enum="MIDIMessage">
MIDI program change message. This message sent when the program patch number changes.
MIDI message sent when the MIDI device changes its current instrument (also called [i]program[/i] or [i]preset[/i]).
</constant>
<constant name="MIDI_MESSAGE_CHANNEL_PRESSURE" value="13" enum="MIDIMessage">
MIDI channel pressure message. This message is most often sent by pressing down on the key after it "bottoms out". This message is different from polyphonic after-touch as it indicates the highest pressure across all keys.
MIDI message sent to indicate a change in pressure for the whole channel. Some MIDI devices may send this instead of [constant MIDI_MESSAGE_AFTERTOUCH].
Copy link
Contributor Author

@Mickeon Mickeon Jan 2, 2024

Choose a reason for hiding this comment

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

Unsure between this and
"MIDI message sent when the channel's pressure value changes" or similar

</constant>
<constant name="MIDI_MESSAGE_PITCH_BEND" value="14" enum="MIDIMessage">
MIDI pitch bend message. This message is sent to indicate a change in the pitch bender (wheel or lever, typically).
MIDI message sent when the value of the pitch bender changes, usually a wheel on the MIDI device.
</constant>
<constant name="MIDI_MESSAGE_SYSTEM_EXCLUSIVE" value="240" enum="MIDIMessage">
MIDI system exclusive message. This has behavior exclusive to the device you're receiving input from. Getting this data is not implemented in Godot.
MIDI system exclusive (SysEx) message. This type of message is not standardized and it's highly dependent on the MIDI device sending it.
[b]Note:[/b] Getting this message's data from [InputEventMIDI] is not implemented.
</constant>
<constant name="MIDI_MESSAGE_QUARTER_FRAME" value="241" enum="MIDIMessage">
MIDI quarter frame message. Contains timing information that is used to synchronize MIDI devices. Getting this data is not implemented in Godot.
MIDI message sent every quarter frame to keep connected MIDI devices synchronized. Related to [constant MIDI_MESSAGE_TIMING_CLOCK].
[b]Note:[/b] Getting this message's data from [InputEventMIDI] is not implemented.
</constant>
<constant name="MIDI_MESSAGE_SONG_POSITION_POINTER" value="242" enum="MIDIMessage">
MIDI song position pointer message. Gives the number of 16th notes since the start of the song. Getting this data is not implemented in Godot.
MIDI message sent to jump onto a new position in the current sequence or song.
[b]Note:[/b] Getting this message's data from [InputEventMIDI] is not implemented.
</constant>
<constant name="MIDI_MESSAGE_SONG_SELECT" value="243" enum="MIDIMessage">
MIDI song select message. Specifies which sequence or song is to be played. Getting this data is not implemented in Godot.
MIDI message sent to select a sequence or song to play.
[b]Note:[/b] Getting this message's data from [InputEventMIDI] is not implemented.
</constant>
<constant name="MIDI_MESSAGE_TUNE_REQUEST" value="246" enum="MIDIMessage">
MIDI tune request message. Upon receiving a tune request, all analog synthesizers should tune their oscillators.
MIDI message sent to request a tuning calibration. Used on analog synthesizers. Most modern MIDI devices do not need this message.
</constant>
<constant name="MIDI_MESSAGE_TIMING_CLOCK" value="248" enum="MIDIMessage">
MIDI timing clock message. Sent 24 times per quarter note when synchronization is required.
MIDI message sent 24 times after [constant MIDI_MESSAGE_QUARTER_FRAME], to keep connected MIDI devices synchronized.
</constant>
<constant name="MIDI_MESSAGE_START" value="250" enum="MIDIMessage">
MIDI start message. Start the current sequence playing. This message will be followed with Timing Clocks.
MIDI message sent to start the current sequence or song from the beginning.
</constant>
<constant name="MIDI_MESSAGE_CONTINUE" value="251" enum="MIDIMessage">
MIDI continue message. Continue at the point the sequence was stopped.
MIDI message sent to resume from the point the current sequence or song was paused.
</constant>
<constant name="MIDI_MESSAGE_STOP" value="252" enum="MIDIMessage">
MIDI stop message. Stop the current sequence.
MIDI message sent to pause the current sequence or song.
</constant>
<constant name="MIDI_MESSAGE_ACTIVE_SENSING" value="254" enum="MIDIMessage">
MIDI active sensing message. This message is intended to be sent repeatedly to tell the receiver that a connection is alive.
MIDI message sent repeatedly while the MIDI device is idle, to tell the receiver that the connection is alive. Most MIDI devices do not send this message.
</constant>
<constant name="MIDI_MESSAGE_SYSTEM_RESET" value="255" enum="MIDIMessage">
MIDI system reset message. Reset all receivers in the system to power-up status. It should not be sent on power-up itself.
MIDI message sent to reset a MIDI device to its default state, as if it was just turned on. It should not be sent when the MIDI device is being turned on.
</constant>
<constant name="OK" value="0" enum="Error">
Methods that return [enum Error] return [constant OK] when no error occurred.
Expand Down
64 changes: 35 additions & 29 deletions doc/classes/InputEventMIDI.xml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="InputEventMIDI" inherits="InputEvent" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
Represents an input event from a MIDI device, such as a piano.
Represents a MIDI message from a MIDI device, such as a musical keyboard.
</brief_description>
<description>
InputEventMIDI allows receiving input events from MIDI (Musical Instrument Digital Interface) devices such as a piano.
MIDI signals can be sent over a 5-pin MIDI connector or over USB, if your device supports both be sure to check the settings in the device to see which output it's using.
To receive input events from MIDI devices, you need to call [method OS.open_midi_inputs]. You can check which devices are detected using [method OS.get_connected_midi_inputs].
InputEventMIDI stores information about messages from [url=https://en.wikipedia.org/wiki/MIDI]MIDI[/url] (Musical Instrument Digital Interface) devices. These may include musical keyboards, synthesizers, and drum machines.
MIDI messages can be received over a 5-pin MIDI connector or over USB. If your device supports both be sure to check the settings in the device to see which output it is using.
By default, Godot does not detect MIDI devices. You need to call [method OS.open_midi_inputs], first. You can check which devices are detected with [method OS.get_connected_midi_inputs], and close the connection with [method OS.close_midi_inputs].
[codeblocks]
[gdscript]
func _ready():
Expand All @@ -17,16 +17,16 @@
if input_event is InputEventMIDI:
_print_midi_info(input_event)

func _print_midi_info(midi_event: InputEventMIDI):
func _print_midi_info(midi_event):
print(midi_event)
print("Channel " + str(midi_event.channel))
print("Message " + str(midi_event.message))
print("Pitch " + str(midi_event.pitch))
print("Velocity " + str(midi_event.velocity))
print("Instrument " + str(midi_event.instrument))
print("Pressure " + str(midi_event.pressure))
print("Controller number: " + str(midi_event.controller_number))
print("Controller value: " + str(midi_event.controller_value))
print("Channel ", midi_event.channel)
print("Message ", midi_event.message)
print("Pitch ", midi_event.pitch)
print("Velocity ", midi_event.velocity)
print("Instrument ", midi_event.instrument)
print("Pressure ", midi_event.pressure)
print("Controller number: ", midi_event.controller_number)
print("Controller value: ", midi_event.controller_value)
[/gdscript]
[csharp]
public override void _Ready()
Expand All @@ -35,9 +35,9 @@
GD.Print(OS.GetConnectedMidiInputs());
}

public override void _Input(InputEvent @event)
public override void _Input(InputEvent inputEvent)
{
if (@event is InputEventMIDI midiEvent)
if (inputEvent is InputEventMIDI midiEvent)
{
PrintMIDIInfo(midiEvent);
}
Expand All @@ -57,7 +57,7 @@
}
[/csharp]
[/codeblocks]
Note that Godot does not currently support MIDI output, so there is no way to emit MIDI signals from Godot. Only MIDI input works.
[b]Note:[/b] Godot does not support MIDI output, so there is no way to emit MIDI messages from Godot. Only MIDI input is supported.
</description>
<tutorials>
<link title="MIDI Message Status Byte List">https://www.midi.org/specifications-old/item/table-2-expanded-messages-list-status-bytes</link>
Expand All @@ -66,33 +66,39 @@
</tutorials>
<members>
<member name="channel" type="int" setter="set_channel" getter="get_channel" default="0">
The MIDI channel of this input event. There are 16 channels, so this value ranges from 0 to 15. MIDI channel 9 is reserved for the use with percussion instruments, the rest of the channels are for non-percussion instruments.
The MIDI channel of this message, ranging from [code]0[/code] to [code]15[/code]. MIDI channel [code]9[/code] is reserved for percussion instruments.
</member>
<member name="controller_number" type="int" setter="set_controller_number" getter="get_controller_number" default="0">
If the message is [constant MIDI_MESSAGE_CONTROL_CHANGE], this indicates the controller number, otherwise this is zero. Controllers include devices such as pedals and levers.
The unique number of the controller, if [member message] is [constant MIDI_MESSAGE_CONTROL_CHANGE], otherwise this is [code]0[/code]. This value can be used to identify sliders for volume, balance, and panning, as well as switches and pedals on the MIDI device. See the [url=https://en.wikipedia.org/wiki/General_MIDI#Controller_events]General MIDI specification[/url] for a small list.
</member>
<member name="controller_value" type="int" setter="set_controller_value" getter="get_controller_value" default="0">
If the message is [constant MIDI_MESSAGE_CONTROL_CHANGE], this indicates the controller value, otherwise this is zero. Controllers include devices such as pedals and levers.
The value applied to the controller. If [member message] is [constant MIDI_MESSAGE_CONTROL_CHANGE], this value ranges from [code]0[/code] to [code]127[/code], otherwise it is [code]0[/code]. See also [member controller_value].
</member>
<member name="instrument" type="int" setter="set_instrument" getter="get_instrument" default="0">
The instrument of this input event. This value ranges from 0 to 127. Refer to the instrument list for [url=https://en.wikipedia.org/wiki/General_MIDI#Program_change_events]General MIDI[/url] to see a list of instruments, except that this value is 0-index, so subtract one from every number on that chart. A standard piano will have an instrument number of 0.
The instrument (also called [i]program[/i] or [i]preset[/i]) used on this MIDI message. This value ranges from [code]0[/code] to [code]127[/code].
To see what each value means, refer to the [url=https://en.wikipedia.org/wiki/General_MIDI#Program_change_events]General MIDI's instrument list[/url]. Keep in mind that the list is off by 1 because it does not begin from 0. A value of [code]0[/code] corresponds to the acoustic grand piano.
</member>
<member name="message" type="int" setter="set_message" getter="get_message" enum="MIDIMessage" default="0">
Returns a value indicating the type of message for this MIDI signal. This is a member of the [enum MIDIMessage] enum.
For MIDI messages between 0x80 and 0xEF, only the left half of the bits are returned as this value, as the other part is the channel (ex: 0x94 becomes 0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.
Notes will return [constant MIDI_MESSAGE_NOTE_ON] when activated, but they might not always return [constant MIDI_MESSAGE_NOTE_OFF] when deactivated, therefore your code should treat the input as stopped if some period of time has passed.
Some MIDI devices may send [constant MIDI_MESSAGE_NOTE_ON] with zero velocity instead of [constant MIDI_MESSAGE_NOTE_OFF].
For more information, see the note in [member velocity] and the MIDI message status byte list chart linked above.
Represents the type of MIDI message (see the [enum MIDIMessage] enum).
For more information, see the [url=https://www.midi.org/specifications-old/item/table-2-expanded-messages-list-status-bytes]MIDI message status byte list chart[/url].
</member>
<member name="pitch" type="int" setter="set_pitch" getter="get_pitch" default="0">
The pitch index number of this MIDI signal. This value ranges from 0 to 127. On a piano, middle C is 60, and A440 is 69, see the "MIDI note" column of the piano key frequency chart on Wikipedia for more information.
The pitch index number of this MIDI message. This value ranges from [code]0[/code] to [code]127[/code].
On a piano, the [b]middle C[/b] is [code]60[/code], followed by a [b]C-sharp[/b] ([code]61[/code]), then a [b]D[/b] ([code]62[/code]), and so on. Each octave is split in offsets of 12. See the "MIDI note number" column of the [url=https://en.wikipedia.org/wiki/Piano_key_frequencies]piano key frequency chart[/url] a full list.
</member>
<member name="pressure" type="int" setter="set_pressure" getter="get_pressure" default="0">
The pressure of the MIDI signal. This value ranges from 0 to 127. For many devices, this value is always zero.
The strength of the key being pressed. This value ranges from [code]0[/code] to [code]127[/code].
[b]Note:[/b] For many devices, this value is always [code]0[/code]. Other devices such as musical keyboards may simulate pressure by changing the [member velocity], instead.
</member>
<member name="velocity" type="int" setter="set_velocity" getter="get_velocity" default="0">
The velocity of the MIDI signal. This value ranges from 0 to 127. For a piano, this corresponds to how quickly the key was pressed, and is rarely above about 110 in practice.
[b]Note:[/b] Some MIDI devices may send a [constant MIDI_MESSAGE_NOTE_ON] message with zero velocity and expect this to be treated the same as a [constant MIDI_MESSAGE_NOTE_OFF] message, but device implementations vary so Godot reports event data exactly as received. Depending on the hardware and the needs of the game/app, this MIDI quirk can be handled robustly with a couple lines of script (check for [constant MIDI_MESSAGE_NOTE_ON] with velocity zero).
The velocity of the MIDI message. This value ranges from [code]0[/code] to [code]127[/code]. For a musical keyboard, this corresponds to how quickly the key was pressed, and is rarely above [code]110[/code] in practice.
[b]Note:[/b] Some MIDI devices may send a [constant MIDI_MESSAGE_NOTE_ON] message with [code]0[/code] velocity and expect it to be treated the same as a [constant MIDI_MESSAGE_NOTE_OFF] message. If necessary, this can be handled with a few lines of code:
[codeblock]
func _input(event):
if event is InputEventMIDI:
if event.message == MIDI_MESSAGE_NOTE_ON and event.velocity &gt; 0:
print("Note pressed!")
[/codeblock]
</member>
</members>
</class>
Loading