使用Python加快boxcounting代码的速度

2024-09-21 01:13:53 发布

您现在位置:Python中文网/ 问答频道 /正文

下面的代码是音频文件的功能之一。因为我将一个音频文件分割成4096个样本,所以我必须调用4096次boxcounting函数来获得每个分割文件的输出。我为一个分段文件编写的代码,从主python文件调用。如果完整音频较短,则需要大约10秒/分段文件;如果完整音频约为3-4分钟,则需要30秒/分段文件。我的问题是运行一个音频文件需要很长时间。你知道吗

  1. 从音频获取一个数组,并将它们分离为2个单声道数组(左声道和右声道)
  2. 标准化值并将数组乘以20以放大
  3. 将数字舍入到小数点后一位
  4. 使用zip()将它们(L,R)配对
  5. 删除重复值
  6. 计算每个小盒子中的坐标对
  7. 有值的计数框(最终输出) This is my example
import numpy as np
from pydub import AudioSegment
from collections import OrderedDict 

def difference(a, b):
    if (a > 0) and (b > 0):
        return (abs(a - b))
    elif (a > 0) and (b < 0):
        return abs(a + abs(b))
    elif (a < 0) and (b < 0):
        return (abs(a) - abs(b))

def boxcounting(left_channel, right_channel, scale):
    ratioX = difference(max(left_channel), min(left_channel))/scale
    ratioY = difference(max(right_channel), min(right_channel))/scale
    startX = min(left_channel)
    count_per_scale = []
    countbox = 0
    pair = list(OrderedDict.fromkeys(list(zip(left_channel, right_channel)))) 

    for x in range(scale):
        print('startX',startX)
        startY = min(right_channel)
        endX = startX + ratioX
        if x == (scale-1):
            endX = max(left_channel)
        print('endX',endX)
        for y in range(scale):
            print('-----------------------')
            print('startY',startY)
            endY = startY + ratioY
            if y == (scale-1):
                endY = max(right_channel)
            print('endY',endY)
            count = 0 # reset
            for l,r in pair:
                if (startX < l <= endX):
                    if (startY < r <= endY):
                        count+=1
                        print('0',l,r)
                        print('count',count)
                    elif (min(right_channel) == r and r == startY):
                        count+=1
                        print('1',l,r)
                        print('count',count)
                elif (min(left_channel) == l and l == startX):
                    if (startY < r <= endY):
                        count+=1
                        print('2',l,r)
                        print('count',count)
                    elif (min(right_channel) == r and r == startY):
                        count+=1
                        print('3',l,r)
                        print('count',count)
            count_per_scale.append(count)
            if count != 0:
                countbox += 1
            startY = endY
        startX = endX
        print('===============================')

    print(count_per_scale)
    countbox = 0
    for i in count_per_scale:
        if(i > 0):
            countbox += 1
    countbox = np.count_nonzero(count_per_scale)
    print('No. of box that has value =', countbox)
    return countbox

sound = AudioSegment.from_file('Alpharock - Pump This Party.mp3') 
split_sound = sound.split_to_mono()
left_channel = np.array(split_sound[0].get_array_of_samples())
right_channel = np.array(split_sound[1].get_array_of_samples())
scale = 10 #norm and scale up
scaleupL = np.round((left_channel/np.abs(left_channel).max())* scale,1) 
scaleupR = np.round((right_channel/np.abs(right_channel).max())* scale,1) 

有人能帮我快点吗?非常感谢你。你知道吗


Tags: andrightifcountnpchannelabsmin

热门问题