Cómo convertir un teclado en un piano con Python

De alguna manera me interesé por la teoría musical. Pero, lamentablemente, no tengo piano, así que fui en busca de un programa con la siguiente funcionalidad: después de presionar un botón, suena una nota determinada. Al principio miré programas altamente profesionales, pero también tienen demasiadas funciones. Y esto es muy bueno, pero en el momento actual de mi vida simplemente es innecesario para mí. Esto solo interferirá y distraerá. En programas con menos funcionalidad, la interfaz más inconveniente. Así que decidí escribir ese programa yo mismo. Detalles debajo del corte.






Un poco sobre MIDI

MIDI -     . , . :





  1. midi , .





  2. . , noteon – ; noteoff – ; change_program – , control_change – , , , . .





  3. : – , , , .; , ; ( 16), , . , .





MIDI- Mido

Mido – python, MIDI- . .





:





from mido import MidiFile
 
mid = MidiFile('song.mid')
for i, track in enumerate(mid.tracks):
    print('Track {}: {}'.format(i, track.name))
    for msg in track:
        print(msg)
      
      



:





from mido import Message, MidiFile, MidiTrack, second2tick
 
 
mid = MidiFile()
 
track = MidiTrack()
mid.tracks.append(track)
time = int(second2tick(0.1, 480, 500000))
for i in range(100):
    track.append(Message('program_change', program=12, time=0))
    track.append(Message('note_on', note=64, velocity=64, time=time))
    track.append(Message('note_off', note=64, velocity=64, time=time))
 
mid.save('new_song.mid')
      
      



«time». .





c keyboard.





:





import keyboard
 
 
def hook(key):
    if key.event_type == "down":
        print("{} press".format(key.name))
    if key.event_type == "up":
        print("{} release".format(key.name))
 
keyboard.hook(hook)
keyboard.wait("esc")
      
      



{key: note} ( ):





import keyboard
 
 
keys = {}
note = 48
def hook(key):
    global note

    if key.event_type == "down":
        if key.name != "esc":
            keys.update({key.name: note})
            note += 1

    if key.event_type == "up":
        if key.name == "esc":
            print(keys)
 
keyboard.hook(hook)
keyboard.wait()
      
      



e mido

python-rtmidi.





( ):





>>> mido.get_output_names()
['Microsoft GS Wavetable Synth 0']
      
      



:





import keyboard
import mido
 
 
port = mido.open_output('Microsoft GS Wavetable Synth 0')
keys = keys = {'1': 48, '2': 49, '3': 50, '4': 51, '5': 52, '6': 53, '7': 54, '8': 55, '9': 56, '0': 57, '-': 58, '=': 59, 'q': 60, 'w': 61, 'e': 62, 'r': 63, 't': 64, 'y': 65, 'u': 66, 'i': 67, 'o': 68, 'p': 69, '[': 70, ']': 71, 'a': 72, 's': 73, 'd': 74, 'f': 75, 'g': 76, 'h': 77, 'j': 78, 'k': 79, 'l': 80, ';': 81, "'": 82, 'enter': 83}
pressed_keys = {key: False for key in keys.keys()}
 
 
def hook(key):
    if key.event_type == "down":
        if key.name in keys:
            if not pressed_keys[key.name]:
                port.send(mido.Message('note_on', note=keys[key.name]))
                pressed_keys[key.name] = True
 
    if key.event_type == "up":
        if key.name in keys:
            port.send(mido.Message('note_off', note=keys[key.name]))
            pressed_keys[key.name] = False
 
keyboard.hook(hook)
keyboard.wait()
      
      



– . midi wav .





e fluidsynth

Fluidsynth – .





fluidsynth ( Windows):





  1. fluidsynth Windows .





  2. «fluidsynth\bin» path. « », ; « », «Path», «», «» «fluidsynth\bin».





  3. .





  4. fluidsynth. midi «fluidsynth FluidR3_GM.sf2 file_name.mid». .





pyfluidsynth.





  1. pyfluidsynth ( github) .





  2. 1.5 ( , , ). «fluidsynth\bin» «libfluidsynth-3.dll» ( , ). «fluidsynth.py» «pyfluidsynth», «lib = find_library('fluidsynth') or…» ( ) «fluidsynth» «libfluidsynth-3.dll» ( ).





  3. «pyfluidsynth» «py setup.py install». .





numpy.





:





import time
import fluidsynth
 
fs = fluidsynth.Synth()
fs.start()
 
sfid = fs.sfload("FluidR3_GM.sf2")
fs.program_select(0, sfid, 0, 0)
 
 
for i in range(10):
    fs.noteon(0, 60, 30)
    fs.noteon(0, 67, 30)
    fs.noteon(0, 76, 30)
 
    time.sleep(1.0)
 
    fs.noteoff(0, 60)
    fs.noteoff(0, 67)
    fs.noteoff(0, 76)
 
time.sleep(1.0)
 
fs.delete()
      
      



keyboard:





import keyboard
import mido
import fluidsynth
 
 
fs = fluidsynth.Synth()
fs.start()
sfid = fs.sfload("FluidR3_GM.sf2")
fs.program_select(0, sfid, 0, 41)
 
 
keys = {'1': 48, '2': 49, '3': 50, '4': 51, '5': 52, '6': 53, '7': 54, '8': 55, '9': 56, '0': 57, '-': 58, '=': 59, 'q': 60, 'w': 61, 'e': 62, 'r': 63, 't': 64, 'y': 65, 'u': 66, 'i': 67, 'o': 68, 'p': 69, '[': 70, ']': 71, 'a': 72, 's': 73, 'd': 74, 'f': 75, 'g': 76, 'h': 77, 'j': 78, 'k': 79, 'l': 80, ';': 81, "'": 82, 'enter': 83}
pressed_keys = {key: False for key in keys.keys()}
 
 
def hook(key):
    if key.event_type == "down":
        if key.name in keys:
            if not pressed_keys[key.name]:
                fs.noteon(0, keys[key.name], 127)
                pressed_keys[key.name] = True
 
    if key.event_type == "up":
        if key.name in keys:
            fs.noteoff(0, keys[key.name])
            pressed_keys[key.name] = False
 
keyboard.hook(hook)
keyboard.wait()
      
      



midi wav

:





fluidsynth -F melody.wav FluidR3_GM.sf2 melody.mid
      
      



. !








All Articles