0

I am currently trying to make a simple python script for creating speech data.

The idea with the script is that is starts recording using pyaudio, when a key is pressed and hold down, and stops recording when the key is released.

I am currently a bit confused on how i should implement the while key hold / stop at release mechanism.

i found this library keyboard , but can't make sense whether it incorporates this form of mechanism?

open_ey
  • 1
  • 3
  • 1
    See comment of [this](https://stackoverflow.com/questions/40649634/determine-length-of-keypress-in-python) question. That might help you. – P. Siehr Jul 03 '17 at 11:41
  • Just seem like a bit too much for this simple task @P.Siehr – open_ey Jul 03 '17 at 12:05

2 Answers2

2

According to this code in library "keyboard"'s source, it do provide such mechanism to detect if a key is currently pressed. so you can just do a while loop to check whether user has released that key.

#/usr/bin/python
# file: __init__.py
# ...
def is_pressed(key):
    """
    Returns True if the key is pressed.
        is_pressed(57) -> True
        is_pressed('space') -> True
        is_pressed('ctrl+space') -> True
    """
    _listener.start_if_necessary()
    if is_number(key):
        return key in _pressed_events
    elif len(key) > 1 and ('+' in key or ',' in key):
        parts = canonicalize(key)
        if len(parts) > 1:
            raise ValueError('Cannot check status of multi-step combination ({}).'.format(key))
        return all(is_pressed(part) for part in parts[0])
    else:
        for event in _pressed_events.values():
            if matches(event, key):
                return True
        return False
Sajuuk
  • 2,667
  • 3
  • 22
  • 34
  • `while keyboard.is_pressed('space'):` gives me error message: `raise ImportError('You must be root to use this library on linux.') ImportError: You must be root to use this library on linux.` And running it as sudo gives me error message: `IOError: [Errno 1] Operation not permitted: '/dev/uinput'` – open_ey Jul 03 '17 at 12:10
  • `keyboard` seems only to work with windows and linux. Anything that both works on linux an windows. – open_ey Jul 03 '17 at 15:11
  • @open_ey, Are you using MacOS? – Sajuuk Jul 04 '17 at 07:47
  • Is there anything for Mac? – tonix Dec 25 '17 at 23:45
0

I faced a similar issue while working on a project. Here is my simplified approach using just keyboard module.

We can divide the problem in 3 parts:

  1. Waiting for Key Press
  2. Record while Key is pressed (held)
  3. Stop recording upon Key release

The first part is tricky, there are multiple solutions using listeners, while True loops, input and raw_input implementations. I was struggling with configuring these implementations and went ahead with keyboard.wait(<your key choice>). This blocks the program till the key of choice is pressed. If you do not pass in any argument, it waits for any key press.

The second part is resolved by a while loop which executes till the key is pressed. After the first two are resolved, the third part falls in place as the is_pressed has a mechanism which detects if the key is held down/pressed. This is what is pointed out by @Sajuuk in his solution.

Here is an implementation of the code:

import pyaudio
import keyboard

def audioRecord(object):
    chunk = 1024  # Record in chunks of 1024 samples
    sample_format = pyaudio.paInt16  # 16 bits per sample
    channels = 2
    fs = 44100  # Record at 44100 samples per second

    p = pyaudio.PyAudio()  # Create an interface to PortAudio

    # Open the stream
    stream = p.open(format=sample_format,
                                channels=channels,
                                rate=fs,
                                frames_per_buffer=chunk,
                                input=True)
    
    frames = []  # Initialize array to store frames

    # ----- Solution starts here -----
    print('Hold Space to record')
    keyboard.wait('space') # Waits for key press
    if keyboard.is_pressed('space'):
        print('Recording...')

        while keyboard.is_pressed('space'): # Records till key is pressed/held down
            data = stream.read(chunk)
            frames.append(data)

    # Stop and close the stream 
    stream.stop_stream()
    stream.close()
    # Terminate the PortAudio interface
    p.terminate()

    print('Finished recording')

You can now process these frames as per your requirement. Save it in a file or process the frames directly. Just couple of recommendations, add a timeout for the keyboard.wait() to avoid the program to be blocked indefinitely.

Hope this answer helps, cheers :)

Elysian Storm
  • 788
  • 6
  • 18