Y
Unfortunately, I have no idea what you've written,
But I've got an example that might be useful to you.Source: https://gist.github.com/tam17aki/44e544d8d6d07e31de764bbd28fdee40 # ...возможность изменить высоту и формат с помощью ползунка PyQt5.
import sys
from PyQt5.QtWidgets import (QWidget, QSlider, QLabel, QApplication)
from PyQt5.QtCore import Qt, QTimer
import pyaudio
import numpy as np
import pyworld as pw # pip install pyworld
sample_rate = 16000
input_buffer_size = 1024 * 8
output_buffer_size = 1024 * 2
f0_rate = 1.0 # Регулировка высоты голоса: удвоение на одну октаву вверх на 0,5 вверх на одну октаву вниз
sp_rate = 1.0 # Регулировка цвета голоса (> 0,0): для женских голосов меньше 1,0, для мужчин верно обратное
class Analysis_Synthesis(QWidget):
def __init__(self):
super().__init__()
self.CHUNK = input_buffer_size # Ширина данных голосового чтения за один раз
self.RATE = sample_rate # Частота дискретизации
self.audio = pyaudio.PyAudio()
self.stream_in = self.audio.open(format=pyaudio.paInt16,
channels=1,
rate=self.RATE,
input=True,
output=True,
frames_per_buffer=self.CHUNK)
self.stream_out = self.audio.open(format=pyaudio.paInt16,
channels=1,
rate=self.RATE,
output=True,
frames_per_buffer=output_buffer_size)
self.timer = QTimer()
self.timer.timeout.connect(self.update)
self.timer.start(5)
self.f0_rate = f0_rate
self.sp_rate = sp_rate
# Место хранения голосовых данных (данные графика)
self.data = np.zeros(self.CHUNK)
self.initUI()
def analysis_resynthesis(self, signal):
f0, t = pw.dio(signal, sample_rate) # Извлечение основной частоты
f0 = pw.stonemask(signal, f0, t, sample_rate) # утонченность
sp = pw.cheaptrick(signal, f0, t, sample_rate) # Извлечение спектральной огибающей
ap = pw.d4c(signal, f0, t, sample_rate) # Извлечение индекса апериодичности
# Сдвиг высоты тона
modified_f0 = self.f0_rate * f0
# Сдвиг форманты (равномерное расширение и сжатие оси частот)
modified_sp = np.zeros_like(sp)
sp_range = int(modified_sp.shape[1] * self.sp_rate)
for f in range(modified_sp.shape[1]):
if (f < sp_range):
if self.sp_rate >= 1.0:
modified_sp[:, f] = sp[:, int(f / self.sp_rate)]
else:
modified_sp[:, f] = sp[:, int(self.sp_rate * f)]
else:
modified_sp[:, f] = sp[:, f]
synth = pw.synthesize(modified_f0, modified_sp, ap, sample_rate)
return synth.astype(np.int16).tobytes()
def update(self):
try:
audio_input = self.stream_in.read(
self.CHUNK, exception_on_overflow=False)
signal = np.frombuffer(
audio_input, dtype='int16').astype(np.float64)
output = self.analysis_resynthesis(signal)
self.stream_out.write(output)
except KeyboardInterrupt:
print("\nInterrupt.")
self.stream_in.stop_stream()
self.stream_in.close()
self.stream_out.stop_stream()
self.stream_out.close()
self.audio.terminate()
print("Stop Streaming.")
def initUI(self):
# Создать вертикальный слайдер
sld_f0 = QSlider(Qt.Vertical, self)
# Предотвратить слайдер от фокусировки
sld_f0.setFocusPolicy(Qt.NoFocus)
sld_f0.setGeometry(30, 40, 30, 200)
# Функция ChangeValue вызывается при перемещении ползунка
sld_f0.valueChanged[int].connect(self.changeValue_f0)
# Создать вертикальный слайдер
sld_sp = QSlider(Qt.Vertical, self)
# Предотвратить слайдер от фокусировки
sld_sp.setFocusPolicy(Qt.NoFocus)
sld_sp.setGeometry(130, 40, 30, 200)
# Функция ChangeValue вызывается при перемещении ползунка
sld_sp.valueChanged[int].connect(self.changeValue_sp)
# Создание метки (класс для отображения символов)
self.label_f0 = QLabel(self)
# Положение метки (x, y, ширина, высота)
self.label_f0.setGeometry(30, 0, 100, 40)
self.label_f0.setText(
'Pitch\n' + str(int(self.f0_rate * 100)) + '%')
# Создание метки (класс для отображения символов)
self.label_sp = QLabel(self)
# Положение метки (x, y, ширина, высота)
self.label_sp.setGeometry(120, 0, 100, 40)
self.label_sp.setText('Formant\n' + str(int(self.sp_rate * 100)) + '%')
sld_f0.setValue(25)
sld_sp.setValue(20)
# Размер окна
self.setGeometry(300, 300, 200, 250)
self.setWindowTitle('Voice Changer')
self.show()
def changeValue_f0(self, value):
self.f0_rate = (50 + 2.0 * value) / 100
self.label_f0.setText('Pitch\n' + str(int(self.f0_rate * 100)) + '%')
def changeValue_sp(self, value):
self.sp_rate = (75 + 1.25 * value) / 100
self.label_sp.setText('Formant\n' + str(int(self.sp_rate * 100)) + '%')
if name == 'main':
app = QApplication(sys.argv)
ex = Analysis_Synthesis()
sys.exit(app.exec_())