Ускорьте подсчет ящиков с помощью Python - PullRequest
0 голосов
/ 05 июля 2019

Код ниже является одной из функций аудиофайла.Поскольку я сегментировал один аудиофайл на 4096 сэмплов, я должен вызывать функцию boxcounting 4096 раз, чтобы получить выходные данные для каждого сегментированного файла.Этот код я написал для одного сегментированного файла и вызвал из основного файла Python.Это занимает около 10 секунд / сегментированный файл, если полный звук короткий, и занимает 30 секунд / сегментированный файл, если полный звук составляет 3-4 минуты.Моя проблема в том, что для запуска одного аудиофайла требуется очень много времени.

  1. получить массив аудио и разделить их на 2 монофонических массива (левый канал и правый канал)
  2. нормализуйте значения и умножьте массив на 20 для увеличения
  3. круглых чисел до одного десятичного знака
  4. , соедините их (L, R) с помощью zip ()
  5. удалите дублирующее значение
  6. подсчитать пару координат в каждом маленьком окошке
  7. подсчитать поля, имеющие значение (окончательный вывод) Это мой пример
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) 

Может кто-нибудь помочь мне сделать это быстрее?Большое спасибо.

...