同时录制来自麦克风的音频,并在python中生效播放 [英] Simultaneous record audio from mic and play it back with effect in python

查看:365
本文介绍了同时录制来自麦克风的音频,并在python中生效播放的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的目标是通过便携式麦克风记录我的声音,并同时使用python为其添加效果.我需要的是类似于音乐效果踏板,您可以在其中连接吉他或麦克风,并增加混响或回声或失真等.

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 a guitar or mic and it adds reverb or echo or distortion, etc.

我正在使用"pyaudio"和"wave"来录制和播放音频.使用"scikits.audiolab"将音频导入为数组,并能够使用诸如反转,剪辑,平铺等功能编辑该数组.对音频数组的这种操作使我可以向原始音频添加"效果.

I am using 'pyaudio' and 'wave' to record and play back audio. Using 'scikits.audiolab' to import audio as a array and to be able to edit this array with with functions such as invert, clip, tile, etc. This manipulation of the audio array lets me "add" effects to the original audio.

我遇到了问题,这并不是真正的问题,这不是我想要的效果.假设我记录了"Hello"一词.我的录制功能设置为录制3秒钟.然后,我将这个音频阵列并平铺一次.现在,当我播放此歌曲时,它将打两次招呼,有延迟效果.但是,两个问候之间有一个空白空间"的时间间隔,这是因为在我说完问候之后,音频仍在录制.因此,当重复该单词时,单词之间有太多的空白空间.我想消除此空白空间,以便播放更快地打个招呼.

I am having a problem, which isn't really a problem, it's just not the effect I want. Let's say I record the word "Hello". I have my record function set to record for 3 seconds. I then take this audio array and tile it once. Now, when I play this back, it will say hello twice, a delay effect. BUT, there is a time interval of 'empty space' between both hellos, which happens because the audio is still recording AFTER I finish saying hello. Therefore when it repeats, there's too much empty space between the words. I want to eliminate this empty space so that the playback says hello hello more quickly.

我的老师建议穿线.他说,我应该记录下来,并同时获取前500个样本,然后说一个数字.他建议您取下这500个样本,并在录制时进行回放.我不太确定该如何实现.

My teacher recommends threading. He says I should record, and simultaneously grab the first 500 samples, to say a number. He recommends to take these 500 samples and play them back while you record. I'm not quite sure how to implement this.

我的问题是,如何同时记录,获取前500个样本并创建一个新数组,并在原始记录中添加效果".

My question is, how to simultaneously record, take the first 500 samples, and create a new array with the "effect" added to the original recording.

import scikits.audiolab as audiolab
import pyaudio
import wave

def recordAudio():

    CHUNK = 1024
    FORMAT = pyaudio.paInt16
    CHANNELS = 1
    RATE = 44100
    RECORD_SECONDS = 3
    WAVE_OUTPUT_FILENAME = "audioOriginal.wav"

    p = pyaudio.PyAudio()

    stream = p.open(format=FORMAT,
                channels=CHANNELS,
                rate=RATE,
                input=True,
                frames_per_buffer=CHUNK)

    print("* recording:")

    frames = []

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

    print("* Finished recording.")

    stream.stop_stream()
    stream.close()
    p.terminate()

    wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
    wf.setnchannels(CHANNELS)
    wf.setsampwidth(p.get_sample_size(FORMAT))
    wf.setframerate(RATE)
    wf.writeframes(b''.join(frames))
    wf.close()

    # Duplicate audio and save as Actual
    frames, fs, encoder = audiolab.wavread('audioOriginal.wav')
    audiolab.wavwrite(frames,'audioActual.wav',fs)

def playAudio():

    import pyaudio
    import wave

    CHUNK = 1024

    wf = wave.open('audioActual.wav', 'rb')

    p = pyaudio.PyAudio()

    stream = p.open(format=p.get_format_from_width(wf.getsampwidth()), 
        channels=wf.getnchannels(), 
        rate=wf.getframerate(), 
        output=True)

    data = wf.readframes(CHUNK)

    while data != '':  
        stream.write(data)  
        data = wf.readframes(CHUNK)

    stream.stop_stream()
    stream.close()
    p.terminate()

def reverseAudio():

    frames, fs, encoder = audiolab.wavread('audioActual.wav')

    audiolab.wavwrite(frames[::-1],'audioActual.wav',44100)

def revert():
    frames, fs, encoder = audiolab.wavread('audioOriginal.wav')
    audiolab.wavwrite(frames,'audioActual.wav',fs)

def errorSelection():
    print("\nERROR.") # no option in menu
def showMenu():
    print("""
    1. Record audio
    2. Play audio
    3. Reverse audio
    4. Add delay
    5. Revert to original audio

    T to end program.
    """)

# Menu
def main():
    selecciones = {"1": recordAudio, "2": playAudio, "3": reverseAudio, "5": revert}
    while True:
        showMenu()
        seleccion = raw_input(u'What do you want to do? ')
        if "t" == seleccion:
            return
        elif "T" == seleccion:
            return
        toDo = selecciones.get(seleccion, errorSelection)
        toDo()

if __name__ == "__main__":
    main()

推荐答案

首先,您提出的问题(能够平铺音频样本,同时自动删除它们之间的安静空间)不是可以通过线程解决的问题.您需要分析录制的声音以确定在哪里静音,或者只是让用户指定录制何时结束.您可以通过一个简单的循环来完成后者:

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. 打开音频硬件并开始录制.
  2. 创建一个空列表来存储音频块
  3. 请求一小部分音频数据,追加到列表中
  4. 检查用户已请求结束录制.如果不是,请循环回到3.
  5. 完成后,将块组装到单个数组中以进行播放.

在这个简单的示例中,使用线程没有任何好处.

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. 并非所有的消费类声卡都具有功能同时录音和播放的功能.寻找声称全双工"而不是半双工"的卡.
  2. 对着麦克风说话并在短时间内听到自己的声音极其会分散您的注意力.为了使其正常工作,必须处理录制的音频并在不到20 ms的时间内将其发送回声卡.在44.1 kHz的频率下,这意味着您每个循环周期要读取的帧数少于880帧,并且如果处理不能跟上,则会在输出中留下空白.除非您有专门的软件来帮助,否则这是一个非常困难的问题.如果您确实想这样做,可以看看Jack( http://jackaudio.org/),在大多数平台上提供低延迟音频访问,并且还具有简单的python库( http://sourceforge. net/projects/py-jack/).在这种程序中,线程可能不会有帮助.
  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.

这篇关于同时录制来自麦克风的音频,并在python中生效播放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆