PyGame Sound шумы при воспроизведении фрагментов звука, в чем проблема?
Пишу приложение для создания анимации, есть необходимость нарезки звука на фрагменты соответствующие кадрам анимации. Для этих целей использую PyGame mixer Sound. При воспроизведении этих фрагментов возникают шумы. При сборке фрагментов в новый звук происходит следующее:
- если собирать от первого до последнего, то звук получается чистый
- если НЕ от первого до последнего, получается грязный или один шум
- если от первого НЕ до последнего, получается чистый звук
Причем такое происходит не со всеми WAV файлами, с одними вообще нет проблем, а с другими всё вышеописанное. В чем причина и как с ней бороться?
Дополнение: заметил, что на шумы влияет изменение переменной SPF
(количество семплов на кадр), вероятно имеет влияние длина оглавления файла или длина семплов.
Ссылка на звук с которым НЕТ ПРОБЛЕМ.
Пример воспроизводимого кода:
import os.path
import sys
from PyQt5.QtCore import QTimer
from PyQt5.QtWidgets import QMainWindow, QLabel,QFileDialog, QApplication
from pygame import mixer
from pygame.mixer import Sound
class Window(QMainWindow):
def __init__(self):
super().__init__()
mixer.init()
self.label = QLabel('Click me!', self)
self.label.setStyleSheet('font-size: 20px')
self.label.setGeometry(10,10,480,280)
self.setFixedWidth(500)
self.setFixedHeight(300)
# необходимые переменные
self.FPS = 12 # предустановленная скорость кадров в секунду
self.Frame_Count = 25 # предустановленное количество кадров
self.Current_Frame = 0 # текущий кадр
self.Frame_List = [] # список для нарезанных звуков в кадры
self.collect_arr = None # переменная для сборки фрагментов звука
self.interval = [0,24] # значения диапазона для сборки фрагментов звука от 0 до 24
self.show()
def mousePressEvent(self, event):
self.Frame_List = [] # очищаем список
self.collect_arr = None # очищаем сборку
PathTuple = QFileDialog.getOpenFileName(None, 'Open file', '', "wav file (*.wav)")
if PathTuple[0] != '':
txt_lbl = os.path.basename(PathTuple[0] + '\n')
snd = Sound(PathTuple[0]) # объект звук из файла
snd_arr = snd.get_raw() # получаем битовый массив звука
samples = len(snd_arr) # длина - количество семплов
txt_lbl += str(samples) + ' семплов\n'
duration = snd.get_length() # продолжительнось звука
txt_lbl += str(duration) + ' длительность\n'
SPF = int((samples / duration) / self.FPS) # семплов в одном кадре
txt_lbl += str(SPF) + ' семплов в кадре\n'
for i in range(self.Frame_Count): # цикл от 0 до количества кадров
if i == 0: # добавляем первый фрагмент звука
self.Frame_List.append(snd_arr[ :SPF]) # добавляем в список срез массива для каждого кадра
self.Frame_List.append(snd_arr[i*SPF : (i+1)*SPF]) # далее ОТ значения i ПО i+1
if i >= self.interval[0] and i <= self.interval[1]: # делаем сборку из фрагментов в заданном диапазоне
if self.collect_arr == None:
self.collect_arr = snd_arr[i*SPF : (i+1)*SPF]
else:
self.collect_arr = self.collect_arr + snd_arr[i*SPF : (i+1)*SPF]
self.timer = QTimer() # создаем таймер
self.timer.start(84) # запускаем с интервалом соответствующим 12 кадрам в секунду
self.timer.timeout.connect(self.play_animation_sound) # отправляем сигнал в слот
txt_lbl += 'ВОСПРОИЗВЕДЕНИЕ\n'
self.label.setText(str(txt_lbl)) # выводим информацию в лейбл
def play_animation_sound(self):
Sound(self.Frame_List[self.Current_Frame]).play() # воспроизводим фрагмент текущего кадра
self.Current_Frame += 1 # переходим в следующий кадр
if self.Current_Frame >= 25: # по достижении последнего кадра
self.timer.stop() # останавливаем таймер
self.Current_Frame = 0 # возвращаемся в нулевой кадр
self.label.setText(self.label.text() + '\nВоспроизведение сборки') # выводим информацию в лейбл
Sound(self.collect_arr).play() # воспроизводим сборку диапазона
app = QApplication(sys.argv)
app.setApplicationName("Window")
window = Window()
app.exec_()