Извлечение частот из wav файла python

Я знаком с python, но плохо знаком с numpy, поэтому, пожалуйста, извините меня, если я ошибаюсь.

Я пытаюсь прочитать файл .wav с несколькими частотами (разделенными тишиной). До сих пор мне удавалось читать значения и находить в файле различные части, в которых есть звук. Затем я пытаюсь найти дискретное косинусное преобразование и вычислить из него частоты (ссылка: как извлечь частоту, связанную со значениями fft в python)

Однако я получаю сообщение об ошибке:

индекс 46392 выходит за пределы оси 0 с размером 25

Вот мой код:

import wave
import struct
import numpy as np

def isSilence(windowPosition):
    sumVal = sum( [ x*x for x in sound[windowPosition:windowPosition+windowSize+1] ] )
    avg = sumVal/(windowSize)
    if avg <= 0.0001:
        return True
    else:
        return False

#read from wav file
sound_file = wave.open('test.wav', 'r')
file_length = sound_file.getnframes()
data = sound_file.readframes(file_length)
sound_file.close()
#data = struct.unpack("<h", data)
data = struct.unpack('{n}h'.format(n=file_length), data)
sound = np.array(data)
#sound is now a list of values

#detect silence and notes
i=0
windowSize = 2205
windowPosition = 0
listOfLists = []
listOfLists.append([])
maxVal = len(sound) - windowSize
while True:
    if windowPosition >= maxVal:
        break
    if not isSilence(windowPosition):
        while not isSilence(windowPosition):
            listOfLists[i].append(sound[windowPosition:windowPosition+ windowSize+1])
            windowPosition += windowSize
        listOfLists.append([]) #empty list
        i += 1
    windowPosition += windowSize

frequencies = []
#Calculating the frequency of each detected note by using DFT
for signal in listOfLists:
    if not signal:
        break
    w = np.fft.fft(signal)
    freqs = np.fft.fftfreq(len(w))
    l = len(signal)

    #imax = index of first peak in w
    imax = np.argmax(np.abs(w))
    fs = freqs[imax]

    freq = imax*fs/l
    frequencies.append(freq)

print frequencies

Изменить: вот трассировка:

Traceback (most recent call last):
  File "final.py", line 61, in <module>
    fs = freqs[imax]
IndexError: index 46392 is out of bounds for axis 0 with size 21

person Nikhil Sardana    schedule 06.12.2016    source источник
comment
Я получаю сообщение об ошибке:... Всегда включайте в свой вопрос сообщение об ошибке complete (т. е. полную трассировку). Трассировка показывает, какая строка вызвала ошибку.   -  person Warren Weckesser    schedule 06.12.2016
comment
@WarrenWeckesser хорошо. Строка fs = freqs[imax] вызывала ошибку. В приведенной выше ссылке преобразование Фурье было одномерным. Но мой тестовый файл дал многомерный список.   -  person Nikhil Sardana    schedule 06.12.2016
comment
Наверное многоканальный (стерео)? Если это так, уменьшите до моно, взяв среднее значение двух каналов.   -  person Ahmed Fasih    schedule 06.12.2016


Ответы (1)


Проблема заключалась в том, что я предполагал, что listOfLists на самом деле был списком списков, но на самом деле это был список списков списков. Линия:

        listOfLists[i].append(sound[windowPosition:windowPosition+ windowSize+1])

каждый раз добавлял список, но я предположил, что он добавлял элементы в существующий список.

Например, если listOfLists был:

[ [1,2,3] ]

Затем listOfLists[0].append([4,5,6]) даст:

[ [ [1,2,3],[4,5,6] ] ]

Но я ожидал:

[ [1,2,3,4,5,6] ]

Замена проблемной строки кодом ниже сработала для меня:

for v in sound[windowPosition:windowPosition+windowSize+1]:
            listOfLists[i].append(v)
person Nikhil Sardana    schedule 07.12.2016