-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwave_audio.py
More file actions
91 lines (74 loc) · 3.91 KB
/
wave_audio.py
File metadata and controls
91 lines (74 loc) · 3.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import numpy
from PyQt6.QtGui import QColor, QPen
from PyQt6.QtWidgets import QGraphicsScene, QGraphicsView
class WaveAudio(QGraphicsView):
"""Класс для визуализации аудиоволны и управления маркерами.
Наследуется от QGraphicsView для отображения графической сцены с аудиоволной.
Атрибуты:
_scene (QGraphicsScene): Графическая сцена для отображения волны.
wave (numpy.ndarray | None): Массив данных аудиоволны.
_height (int): Высота виджета.
_width (int): Ширина виджета.
start_marker (float): Позиция стартового маркера (0.0-1.0).
end_marker (float): Позиция конечного маркера (0.0-1.0).
duration (float): Длительность аудио в секундах.
play_line (None): Линия текущего положения воспроизведения.
"""
def __init__(self, height: int, width: int) -> None:
"""Инициализирует виджет для отображения аудиоволны.
Аргументы:
height (int): Высота виджета.
width (int): Ширина виджета.
"""
super().__init__()
self._scene = QGraphicsScene()
self.setScene(self._scene)
self.wave: numpy.ndarray[tuple[int], numpy.dtype[numpy.float64]] | None = None
self._height = height
self._width = width
self.start_marker = 0.0
self.end_marker = 1.0
self.duration = 1.0
self.play_line = None
def set_wave(self, data: numpy.ndarray[tuple[int], numpy.dtype[numpy.float64]] | None, duration: float) -> None:
"""Устанавливает данные аудиоволны для отображения.
Аргументы:
data (numpy.ndarray | None): Массив данных аудиоволны.
duration (float): Длительность аудио в секундах.
"""
self._scene.clear()
self.wave = data
self.duration = duration
if data is not None:
pen = QPen(QColor(128, 128, 128), 1)
step = max(1, len(data) // self._width)
points = [(i, self._height // 2 - data[i] * self._height // 2) for i in range(0, len(data), step)]
for i in range(1, len(points)):
self._scene.addLine(i - 1, points[i - 1][1], i, points[i][1], pen)
pen = QPen(QColor(255, 0, 0), 2)
start_line = self._scene.addLine(0.0, 0, 0.0, self._height, pen)
if start_line:
start_line.setData(0, "marker")
pen = QPen(QColor(0, 255, 0), 2)
end_line = self._scene.addLine(1.0, 0, 1.0, self._height, pen)
if end_line:
end_line.setData(0, "marker")
def draw_markers(self) -> None:
"""Отрисовывает маркеры начала и конца на аудиоволне.
Удаляет старые маркеры и рисует новые в соответствии с текущими позициями.
"""
for item in self._scene.items():
if item.data(0) == "marker":
self._scene.removeItem(item)
if self.duration <= 0:
return
start_x = self.start_marker / self.duration * self._width
end_x = self.end_marker / self.duration * self._width
pen = QPen(QColor(255, 0, 0), 2)
start_line = self._scene.addLine(start_x, 0, start_x, self._height, pen)
if start_line:
start_line.setData(0, "marker")
pen = QPen(QColor(0, 255, 0), 2)
end_line = self._scene.addLine(end_x, 0, end_x, self._height, pen)
if end_line:
end_line.setData(0, "marker")