简体   繁体   English

Python:消除录制音频片段之间的间隙

[英]Python: Eliminating gaps between segments of recorded audio

I am using Python sounddevice library to record audio, but I can't seem to eliminate ~0.25 to ~0.5 second gaps between what should be consecutive audio files.我正在使用 Python sounddevice 库来录制音频,但我似乎无法消除应该是连续音频文件之间的 ~0.25 到 ~0.5 秒的间隔。 I think this is because the file writing takes up time, so I learned to use Multiprocessing and Queues to separate out the file writing but it hasn't helped.我认为这是因为文件写入占用时间,所以我学会了使用 Multiprocessing 和 Queues 来分离文件写入但它并没有帮助。 The most confusing thing is that the logs suggest that the iterations in Main()'s loop are near gapless (only 1-5 milliseconds) but mysteriously the audio_capture function is taking longer than expected even tho nothing else significant is being done.最令人困惑的是,日志表明 Main() 循环中的迭代几乎没有间隙(只有 1-5 毫秒),但神秘的是 audio_capture function 花费的时间比预期的要长,即使没有做任何其他重要的事情。 I tried to reduce the script as much as possible for this post.我试图为这篇文章尽可能地减少脚本。 My research has all pointed to this threading/multiprocessing approach, so I am flummoxed.我的研究都指向这种线程/多处理方法,所以我很困惑。

Background: 3.7 on Raspbian Buster I am dividing the data into segments so that the files are not too big and I imagine programming tasks must deal with this challenge.背景:Raspbian Buster 上的 3.7 我将数据分成几段,这样文件就不会太大,我想编程任务必须应对这一挑战。 I also have 4 other subprocesses doing various things after.之后我还有 4 个其他子流程在做各种事情。

Log: The audio_capture part should only take 10:00日志:audio_capture 部分只需要 10:00

08:26:29.991 --- Start of segment #0
08:36:30.627 --- End of segment #0     <<<<< This is >0.6 later than it should be
08:36:30.629 --- Start of segment #1   <<<<< This is near gapless with the prior event

Script:脚本:

import logging
import sounddevice
from scipy.io.wavfile import write
import time
import os
from multiprocessing import Queue, Process

# this process is a near endless loop
def main():
    fileQueue = Queue()
    writerProcess = Process(target=writer, args=(fileQueue,))
    writerProcess.start()
    for i in range(9000):
        fileQueue.put(audio_capture(i)) 
    writerProcess.join()

# This func makes an audio data object from a sound source
def audio_capture(i): 
    cycleNumber = str(i)
    logging.debug('Start of segment #' + cycleNumber)
    # each cycle is 10 minutes at 32000Hz sample rate
    audio = sounddevice.rec(frames=600 * 32000, samplerate=32000, channels=2) 
    name = time.strftime("%H-%M-%S") + '.wav' 
    path = os.path.join('/audio', name)
    sounddevice.wait()
    logging.debug('End of segment #' + cycleNumber)
    return [audio, path]
    
# This function writes the files.
def writer(input_queue):
    while True:
        try:
            parameters = input_queue.get()
            audio = parameters[0]
            path = parameters[1]
            write(filename=path, rate=32000, data=audio)
            logging.debug('File is written')
        except:
            pass

if __name__ == "__main__":
    logging.basicConfig(level=logging.DEBUG, format='%(asctime)s.%(msecs)03d --- %(message)s', datefmt='%H:%M:%S',handlers=[logging.FileHandler('/audio/log.txt'), logging.StreamHandler()])
    main()  

The documentation tells us that sounddevice.rec() is not meant for gapless recording: 文档告诉我们sounddevice.rec()不适用于无缝录音:

If you need more control (eg block-wise gapless recording, overlapping recordings, …), you should explicitly create an InputStream yourself.如果您需要更多控制(例如,块式无缝记录、重叠记录……),您应该自己明确创建一个InputStream If NumPy is not available, you can use a RawInputStream .如果 NumPy 不可用,您可以使用RawInputStream

There are multiple examples for gapless recording in the example programs . 示例程序中有多个无缝录制示例。

Use Pyaudio, open a non-blocking audio-stream.使用 Pyaudio,打开非阻塞音频流。 you can find a very good basic example on the Pyaudio documentation frontpage.您可以在 Pyaudio 文档首页上找到一个非常好的基本示例。 Choose a buffer size, I recommend 512 or 1024. Now just append the incoming data to a numpy array.选择缓冲区大小,我推荐512或1024。现在只需将append传入数据到一个numpy数组。 I sometimes store up to 30 seconds of audio in one numpy array.我有时会在一个 numpy 数组中存储长达 30 秒的音频。 When reaching the end of a segment, create another empty numpy array and start over.当到达一个段的末尾时,创建另一个空的 numpy 数组并重新开始。 Create a thread and save the first segment somewhere.创建一个线程并将第一段保存在某处。 The recording will continue and not one sample will be dropped;)录音将继续,不会丢弃任何样本;)

Edit: if you want to write 10 mins in one file, I would suggest just create 10 arrays á 1 minute and then append and save them.编辑:如果你想在一个文件中写 10 分钟,我建议只创建 10 arrays á 1 分钟然后 append 并保存它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM