python3音频静音去除+分割; concurrent.futures 多处理速度较慢

问题描述

我正在尝试对某些音频文件运行一些批处理音频。

  1. 读取 wav 文件
  2. 消除沉
  3. 将音频分割成固定长度
  4. 运行特征提取
  5. 保存功能

我的 multiprocessing.cpu_count56,如果我不使用任何多处理,下面的多处理版本仍然需要 113 秒,而脚本在 96 秒内完成。

如何利用我的大部分 cpu 内核通过多处理来加速我的代码

# author: github.com/zabir-nabil

import librosa
from pydub import AudioSegment
import pydub
import os
from spafe.features.mfcc import mfcc
from spafe.features.gfcc import gfcc
from spafe.features.lfcc import lfcc
import cv2
import numpy as np

def segment_aud_eq(audio_segment,k):
    # k denotes,seconds * 1000
    a_segs = [audio_segment[i*k:min((i+1)*k,len(audio_segment)-1)] for i in range(len(audio_segment)//k)]
    return a_segs

def silence_remove_segment(filename,silence_thresh=-60.,segment_size = 5.0,save = False,save_path = "",ret = True):
    # takes an wav/sph file/anything that librosa supports
    # removes the silence with a threshold
    # makes a list of segment of size >= segment_size (in sec.) 
    # saves the wav file or returns a numpy array 16 bit PCM
    y,sr = librosa.load(filename)
    # convert from float to uint16
    y = np.array(y * (1<<15),dtype=np.int16)
    audio_segment = pydub.AudioSegment(
        y.tobytes(),frame_rate=sr,sample_width=y.dtype.itemsize,channels=1
    )
    aud_segs = pydub.silence.split_on_silence(audio_segment,silence_thresh=silence_thresh)
    # join all
    all_seg = sum(aud_segs)
    eq_segs = segment_aud_eq(all_seg,int(segment_size * 1000)) # 1000 because,in AudioSegment 1s is 1000 points

    if save:
        # save as wav
        bn = os.path.basename(filename)
        for i,s in enumerate(eq_segs):
            s.export(f"{os.path.join(save_path,bn.split('.')[0])}_{i}.wav",format="wav")

    if ret:
        return [np.array(s.get_array_of_samples(),dtype = np.int16) for s in eq_segs]

def mgl_fcc(y_s,t_dim = None,f_dim = 20,file_root = "temp",save = True):
    # calculate mfcc,gfcc,lfcc features
    # make a (t_dim,f_dim,3) image (resizing with cv2)
    # save as numpy array

    for i,y in enumerate(y_s):
        mfcc_ = mfcc(sig = y,num_ceps= f_dim)
        if t_dim == None:
            t_dim = mfcc_.shape[0]
        lfcc_ = lfcc(sig = y,num_ceps= f_dim)
        gfcc_ = gfcc(sig = y,num_ceps= f_dim)
        fcc = np.stack( [mfcc_,lfcc_,gfcc_],axis = -1 )
        fcc = cv2.resize(fcc,(f_dim,t_dim)) # dimensions swap cv2
        np.save(f"{file_root}_{i}.npy",fcc)
# code without multiprocessing 
import time
t1 = time.time()
sph_files = [("test.wav",True)]*10

for sf in sph_files:
    sigs = silence_remove_segment(sf[0],save=True)
    mgl_fcc(sigs)

print(time.time() - t1)
# 96.82

import concurrent.futures
import time
import multiprocessing as mp
# multiprocessing trial
t1 = time.time()

def silence_remove_segment_helper(arg_s):
    sigs = silence_remove_segment(arg_s[0],save = arg_s[1])
    return sigs


with concurrent.futures.ProcesspoolExecutor(mp.cpu_count()) as executor:
    for sf in sph_files:
        f = executor.submit(silence_remove_segment_helper,sf)
        executor.submit(mgl_fcc,f.result())

print(time.time() - t1)
# 113.82

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)