Как настроить высоту тона с помощью модуля python wave

поэтому я изменил скорость воспроизведения моего файла output.wav, используя метод частоты кадров модуля python wave и умножив предыдущую частоту кадров на 2, но я хочу сохранить высоту тона нового output.wav такой же, потому что он звучит высоко. Как сделать? Это фрагмент кода, который у меня есть для чтения и записи в output.wav. Я ищу простое решение, пытаясь избежать загрузки внешних библиотек. Хорошо с волновой библиотекой.

Спасибо.

import wave

wf = wave.open('output.wav', 'rb')
RATE = wf.getframerate()
signal = wf.readframes(-1)
channels = wf.getnchannels()
width = wf.getsampwidth()
wf.close()

spf = wave.open('output.wav', 'wb')
spf.setnchannels(channels)
spf.setsampwidth(width)
spf.setframerate(RATE*2)
spf.writeframes(signal)
spf.close()


person Gjison Giocf    schedule 18.03.2020    source источник
comment
На самом деле нет простого решения без использования других библиотек, если только вы не думаете, что сделать собственную цифровую обработку сигналов просто. Если вы можете, я бы рекомендовал использовать Rubber Band согласно этому ответу.   -  person GordonAitchJay    schedule 20.03.2020


Ответы (1)


У меня есть функция определения высоты тона, написанная здесь, но ей нужно numpy по крайней мере, я думаю, вам следует немного изменить его. Он не сильно зависит от этой библиотеки. Просто для более быстрого результата.

Вот код, эта функция, как видите, не сдвигает окно по размеру, а сдвигает окно с некоторым перекрытием. вы должны настроить эти конкретные коды. есть некоторое использование модуля numpy, который я мог бы легко изменить, но я оставляю это вам.

В обработке сигналов есть много правил, и я реализовал некоторые из них. например, если энергии кадра недостаточно, у него нет высоты тона, и это отображается отправкой -1 вместо высоты тона.

import numpy as np

    
def pitch_detection(self, frame_matrix, frame_number, lag_vector, frequency):
        np.seterr(divide='ignore', invalid='ignore')
        pitch_freq_vector = []
        for frame in range(frame_number):
            ccf = [] 
            frame_expand_1 = frame_matrix[frame-1, :]
            frame_expand_2 = frame_matrix[frame-2, :]
            temp_corr_1 = frame_matrix[frame, :]
            temp_corr_2 = np.append(frame_expand_1[256:], temp_corr_1, axis=0)
            temp_corr_2 = np.append(frame_expand_2[192:256], temp_corr_2, axis=0)
            len_tc2 = len(temp_corr_2)
            for lag in lag_vector: #pitch is the highest correlation in lag vector
                ccf.append(np.sum(temp_corr_1*temp_corr_2[len_tc2-lag-512:len_tc2-lag]))
            max_index, max_value = max(enumerate(ccf), key=operator.itemgetter(1))
            if max(ccf) > 0.3*np.sum(np.power(temp_corr_1, 2)): #if more than 30 detect pitch
                pitch_freq_vector.append(max_index)
            else:
                pitch_freq_vector.append(-1)
        return pitch_freq_vector

person Sadegh    schedule 05.03.2021
comment
Как насчет размещения вашего кода здесь в ответе, а также ссылки на оригинал - person Alan; 06.03.2021
comment
ОК, я думаю, что это хорошо сейчас - person Sadegh; 07.03.2021