So verwandeln Sie eine Tastatur mit Python in ein Klavier

Irgendwie interessierte ich mich für Musiktheorie. Aber leider habe ich kein Klavier, also habe ich mich auf die Suche nach einem Programm mit folgenden Funktionen gemacht: Nach dem Drücken einer Taste ertönt eine bestimmte Note. Zuerst habe ich mir hochprofessionelle Programme angesehen, aber sie haben auch zu viele Funktionen. Und das ist sehr gut, aber im gegenwärtigen Moment meines Lebens ist es für mich einfach unnötig. Dies wird nur stören und ablenken. In Programmen mit weniger Funktionalität die unbequemste Schnittstelle. Also habe ich beschlossen, ein solches Programm einfach selbst zu schreiben. Details unter dem Schnitt.






Ein bisschen über 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