клавиатура pynput Слушатель автоповтор - PullRequest
1 голос
/ 09 февраля 2020

Я пытаюсь использовать pynput, чтобы получить ввод с клавиатуры в реальном времени, но функция on_press вызывается при автоповторении.

пример кода:

#!/usr/bin/env python3

import sys

import numpy as np
import sounddevice as sd

from pynput import keyboard

frequency = []

def on_press(key):
    global frequency
    try:
        print(key.vk)
        if key.char == "q":
            frequency.append(440)
        elif key.char == "w":
            frequency.append(880)
    except AttributeError:
        pass

def on_release(key):
    global frequency
    if key == keyboard.Key.esc:
        # Stop listener
        print("Press Enter")
        return False
    elif key.char == "q":
        frequency.remove(440)
    elif key.char == "w":
        frequency.remove(880)

listener = keyboard.Listener(
    on_press=on_press,
    on_release=on_release,
    suppress = True)
listener.start()

start_idx = 0

def callback(outdata, frames, time, status):
    if status:
        print(status, file=sys.stderr)
    print(frames)
    global start_idx
    t = (start_idx + np.arange(frames)) / 48000
    t = t.reshape(-1, 1)
    outdata[:] = 0 * t
    if len(frequency) > 0:
        print("Playing")
    for freq in frequency:
        outdata[:] = outdata[:] + 0.2 * np.sin(2 * np.pi * freq * t)

    start_idx += frames

try:
    with sd.OutputStream(channels=1, callback=callback,
            samplerate=48000):
        input()
        listener.stop()
except Exception as e:
    print("Exception")
    listener.stop()
    exit()

Если вы запустите код и нажмите и удерживайте клавишу Q, автоматически повторяется повтор клавиатуры и портит весь слушатель. Есть ли модуль ввода python, который правильно обрабатывает ввод с клавиатуры?

Во-вторых, код довольно часто обрабатывает sh моего Xorg. Я просто запускаю сценарий несколько раз, и Xorg отключается. И я не могу понять, почему. Linux 5.5.2-zen1-1-zen x86_64 GNU/Linux, X.Org 1.20.7.

В-третьих, синтез звука, похоже, немного отстает. Число кадров для функции обратного вызова, по-видимому, составляет около 400, что при скорости 48000 выборок в секунду составляет менее 10 миллисекунд, но реальная звуковая обратная связь напоминает задержку в сотни миллисекунд.

1 Ответ

1 голос
/ 09 февраля 2020

Pygame имеет хороший кейлист и легко построить окно GUI, которое отображает вывод. Это также хорошо работает в Linux:

import pygame

def main_loop():
    #code
    loopExit = False
    while not loopExit:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                loopExit = True
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_q:
                    #code

            if event.type == pygame.KEYUP:
                if event.key == pygame.K_q:
                    #code

https://www.pygame.org/docs/ref/key.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...