Simultaneous record audio from mic and play it back with effect in python

后端 未结 2 1102
你的背包
你的背包 2020-12-30 18:40

My goal is to record my voice through the laptop mic and simultaneously adding an effect to it, in python. What I need is similar to a music effects pedal where you connect

相关标签:
2条回答
  • 2020-12-30 18:53

    First, the problem you posed (being able to tile audio samples while automatically removing the quiet space between them) is not one that can be solved with threading. You need to analyze the recorded sound to determine where there is or is not silence, or simply allow the user to specify when recording should end. You can accomplish the latter with a simple loop:

    1. Open audio hardware and start recording.
    2. Create an empty list to store chunks of audio
    3. Request a small chunk of audio data, append to the list
    4. Check user has requested the recording to end. If not, loop back to 3.
    5. When finished, assemble the chunks into a single array for playback.

    In this simple example, there is no benefit to using threading.

    The method suggested, to record and simultaneously play back, seems like a solution to a different problem, one that is much more complex. In this case, there are two major difficulties:

    1. Not all consumer sound cards are capable of recording and playing simultaneously. Look for cards that claim "full duplex" instead of "half duplex".
    2. Speaking into a microphone and hearing yourself with a short delay is extremely distracting. To make this work properly, the recorded audio must be processed and sent back to the sound card in less than about 20 ms. At 44.1 kHz, this means you should be reading fewer than 880 frames per loop-cycle, and if the processing can't keep up, you will have gaps in the output. This is a surprisingly difficult problem unless you have specialized software to help. If you really want to go this way, you might look at Jack (http://jackaudio.org/), which provides low-latency audio access on most platforms and has an easy python library as well (http://sourceforge.net/projects/py-jack/). Threading will probably not be helpful in this type of program.
    0 讨论(0)
  • 2020-12-30 18:56

    To expand on Luke's answer:

    for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
        data = stream.read(CHUNK)
        frames.append(data)
    

    In your code is where you commit to a certain time of recording. If you wrote a function "isSilent" that can determine if a chunk is silent, your code might change to:

    while len(frames) <= 0 or not isSilent(frames[-1]):
        data = stream.read(CHUNK)
        frames.append(data)
    

    If "isSilent" is to hard to write or if it is to computationally slow you can wait for user input. KeyboardInterrupt is a first hack to play with this method:

    try:
        while true:
            data = stream.read(CHUNK)
            frames.append(data)
    except KeyboardInterrupt:
        pass
    

    This is a hack, and not the right way to look for user input in production, but it will let you start experimenting with this. you will want to find or make a stopButtonHasBeenPressed function.

    while not stopButtonHasBeenPressed():
        data = stream.read(CHUNK)
        frames.append(data)
    
    0 讨论(0)
提交回复
热议问题