mirror of
https://github.com/Relintai/pandemonium_demo_projects.git
synced 2024-12-21 13:56:50 +01:00
98 lines
3.0 KiB
GDScript
98 lines
3.0 KiB
GDScript
extends Control
|
|
|
|
# A standard piano with 88 keys has keys from 21 to 108.
|
|
# To get a different set of keys, modify these numbers.
|
|
# A maximally extended 108-key piano goes from 12 to 119.
|
|
# A 76-key piano goes from 23 to 98, 61-key from 36 to 96,
|
|
# 49-key from 36 to 84, 37-key from 41 to 77, and 25-key
|
|
# from 48 to 72. Middle C is pitch number 60, A440 is 69.
|
|
const START_KEY = 21
|
|
const END_KEY = 108
|
|
|
|
const WhiteKeyScene = preload("res://piano_keys/white_piano_key.tscn")
|
|
const BlackKeyScene = preload("res://piano_keys/black_piano_key.tscn")
|
|
|
|
var piano_key_dict := Dictionary()
|
|
|
|
onready var white_keys = $WhiteKeys
|
|
onready var black_keys = $BlackKeys
|
|
|
|
func _ready():
|
|
# Sanity checks.
|
|
if _is_note_index_sharp(_pitch_index_to_note_index(START_KEY)):
|
|
printerr("The start key can't be a sharp note (limitation of this piano-generating algorithm). Try 21.")
|
|
return
|
|
|
|
for i in range(START_KEY, END_KEY + 1):
|
|
piano_key_dict[i] = _create_piano_key(i)
|
|
|
|
if white_keys.get_child_count() != black_keys.get_child_count():
|
|
_add_placeholder_key(black_keys)
|
|
OS.open_midi_inputs()
|
|
print(OS.get_connected_midi_inputs())
|
|
|
|
|
|
func _input(input_event):
|
|
if not (input_event is InputEventMIDI):
|
|
return
|
|
var midi_event: InputEventMIDI = input_event
|
|
if midi_event.pitch < START_KEY or midi_event.pitch > END_KEY:
|
|
# The given pitch isn't on the on-screen keyboard, so return.
|
|
return
|
|
_print_midi_info(midi_event)
|
|
var key: PianoKey = piano_key_dict[midi_event.pitch]
|
|
if midi_event.message == MIDI_MESSAGE_NOTE_ON:
|
|
key.activate()
|
|
else:
|
|
key.deactivate()
|
|
|
|
|
|
func _add_placeholder_key(container):
|
|
var placeholder = Control.new()
|
|
placeholder.size_flags_horizontal = SIZE_EXPAND_FILL
|
|
placeholder.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|
placeholder.name = "Placeholder"
|
|
container.add_child(placeholder)
|
|
|
|
|
|
func _create_piano_key(pitch_index):
|
|
var note_index = _pitch_index_to_note_index(pitch_index)
|
|
var piano_key: PianoKey
|
|
if _is_note_index_sharp(note_index):
|
|
piano_key = BlackKeyScene.instance()
|
|
black_keys.add_child(piano_key)
|
|
else:
|
|
piano_key = WhiteKeyScene.instance()
|
|
white_keys.add_child(piano_key)
|
|
if _is_note_index_lacking_sharp(note_index):
|
|
_add_placeholder_key(black_keys)
|
|
piano_key.setup(pitch_index)
|
|
return piano_key
|
|
|
|
|
|
func _is_note_index_lacking_sharp(note_index: int):
|
|
# B and E, because no B# or E#
|
|
return note_index in [2, 7]
|
|
|
|
|
|
func _is_note_index_sharp(note_index: int):
|
|
# A#, C#, D#, F#, and G#
|
|
return note_index in [1, 4, 6, 9, 11]
|
|
|
|
|
|
func _pitch_index_to_note_index(pitch: int):
|
|
pitch += 3
|
|
return pitch % 12
|
|
|
|
|
|
func _print_midi_info(midi_event: InputEventMIDI):
|
|
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))
|