-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathplay_marker.py
More file actions
82 lines (66 loc) · 3.92 KB
/
Copy pathplay_marker.py
File metadata and controls
82 lines (66 loc) · 3.92 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
import numpy
from numpy._typing import NDArray
from PyQt6.QtCore import QThread
from PyQt6.QtGui import QColor, QPen
from PyQt6.QtWidgets import QGraphicsLineItem
from wave_audio import WaveAudio
class PlayMarker(QThread):
"""Класс для визуализации маркера текущей позиции воспроизведения аудио.
Наследуется от QThread для работы в отдельном потоке.
Отображает синюю вертикальную линию, перемещающуюся по волне во время воспроизведения.
Атрибуты:
pen (QPen): Объект пера для отрисовки маркера (синий цвет, толщина 2px)
wave (WaveAudio): Виджет для отображения аудиоволны
scene (QGraphicsScene): Графическая сцена для отрисовки
play_marker (Optional[QGraphicsLineItem]): Графический объект маркера воспроизведения
current_position (float): Текущая позиция маркера в пикселях
data_length (int): Длина аудиоданных в семплах
step (float): Шаг перемещения маркера (пикселей на семпл)
"""
def __init__(self, wave: WaveAudio, data: NDArray[numpy.float32]):
"""Инициализирует маркер воспроизведения.
Аргументы:
wave (WaveAudio): Виджет волны, на котором будет отображаться маркер
data (NDArray[numpy.float32]): Аудиоданные для расчета позиции маркера
"""
super().__init__()
self.pen = QPen(QColor(0, 0, 255), 2)
self.wave = wave
self.scene = wave._scene
self.play_marker: QGraphicsLineItem | None = None
self.current_position = 0.0
self.data_length = len(data)
self.step = self.wave._width / self.data_length
def create_play_marker(self) -> None:
"""Создает маркер воспроизведения в начальной позиции (0).
Если маркер уже существует, ничего не делает.
"""
if self.play_marker is None:
self.play_marker = self.scene.addLine(
self.current_position, 0.0, self.current_position, self.wave._height, self.pen
)
def update_position(self, sample_index: int) -> None:
"""Обновляет позицию маркера в соответствии с текущим семплом воспроизведения.
Аргументы:
sample_index (int): Индекс текущего семпла в аудиоданных
"""
if self.play_marker is not None:
self.scene.removeItem(self.play_marker)
self.current_position = sample_index * self.step
self.play_marker = self.scene.addLine(
self.current_position, 0, self.current_position, self.wave._height, self.pen
)
def pause_marker(self) -> None:
"""Приостанавливает обновление позиции маркера (заглушка)."""
pass
def reset_marker(self) -> None:
"""Сбрасывает позицию маркера в начало (позиция 0)."""
if self.play_marker is not None:
self.scene.removeItem(self.play_marker)
self.current_position = 0
self.play_marker = self.scene.addLine(
self.current_position, 0, self.current_position, self.wave._height, self.pen
)
def remove(self) -> None:
"""Полностью удаляет маркер воспроизведения со сцены."""
self.scene.removeItem(self.play_marker)