How to emulate a piano key in Python?

I wrote a Python script that sends MIDI data to a another program on my laptop if the a key is pressed on the keyboard which triggers a piano sound.

My problem is the following: On a real piano if I press a key and I keep it pressed, a single note sounds with sustain. But if I press the a key on my keyboard while running the script, instead of behaving as a real acoustic piano, the note sounds a bunch of times while the key is pressed. I suppose this issue could be resolved with some if and loop logic. I just don't know how.

Could anyone suggest me anything?

My script is this:

import time
import rtmidi
import mido
import keyboard

outport = mido.open_output('loopMIDI 1')

while True:
    #Pad A
    if keyboard.is_pressed("a"):
        msg = mido.Message("note_on", note=36, velocity=100, time=10)
        outport.send(msg)
        time.sleep(0.05)
    else:
        msg = mido.Message("note_off", note=36, velocity=100, time=10)
        outport.send(msg)

Upvotes: 0

Views: 2035

Answers (2)

After MaxiMouse's great help, I could accomplish what I wanted. I used the suggestion of MaxiMouse and with a bit of variations I could get the script to work.

I'll leave the working code here.

import time
import rtmidi
import mido
import keyboard

outport = mido.open_output('loopMIDI 1')
a_pressed = False

while True:
    #Pad A
    if keyboard.is_pressed("a") and not a_pressed:
        msg = mido.Message("note_on", note=36, velocity=100, time=10)
        outport.send(msg)
        a_pressed = True
        print("True press")
    elif (keyboard.is_pressed("a") == False):
        msg = mido.Message("note_off", note=36, velocity=100, time=10)
        outport.send(msg)
        a_pressed = False
        print("False press")

Upvotes: 0

Maximouse
Maximouse

Reputation: 4383

You need a variable that remembers if the key is pressed:

import time
import rtmidi
import mido
import keyboard

outport = mido.open_output('loopMIDI 1')
a_pressed = False

while True:
    #Pad A
    if keyboard.is_pressed("a"):
        if a_pressed:
            msg = mido.Message("note_on", note=36, velocity=100, time=10)
            outport.send(msg)
            a_pressed = True
    elif a_pressed:
        msg = mido.Message("note_off", note=36, velocity=100, time=10)
        outport.send(msg)
        a_pressed = False

You could use a dict to save information about more than one key.

Upvotes: 1

Related Questions