Dưới đây là toàn bộ nội dung tài liệu đặc tả kỹ thuật đã được chuyển đổi sang định dạng Markdown chuẩn, tối ưu hóa các khối mã nguồn (`python`, `text`), căn chỉnh bảng biểu và định dạng các công thức toán học LaTeX: # Đặc Tả Kỹ Thuật: Hành Động Chọn Vùng & Cơ Chế Phát Lặp (Solo vs. Master Loop) Tài liệu này đặc tả cơ chế tương tác chuột và logic phát âm thanh tương ứng đối với hai vùng chọn: Chọn cục bộ trên Track (*Local Selection*) và Chọn toàn cục trên Timeline (*Global Selection*) dựa trên thiết kế chuẩn DAW trong hình `image_dfffa3.png`. Mục tiêu là cung cấp thuật toán xử lý sự kiện chuột (`MouseEvent`) để lập trình viên chuyển đổi (*port*) trực tiếp sang Python (ví dụ sử dụng `QGraphicsView` hoặc `QWidget` tùy biến trong PyQt6/PySide6). --- ## 1. Bản Vẽ Phân Cấp Vùng Tương Tác (Layout Hitboxes) Dựa trên hình `image_dfffa3.png`, khu vực biên tập bên phải được phân chia thành 2 hitbox tương tác chuột chính yếu: ```text +-------------------------------------------------------------------------+ | [VÙNG A] TIMELINE RULER (Thước đo thời gian trên cùng - Mũi tên đỏ chỉ) | +-------------------------------------------------------------------------+ | [VÙNG B] CÁC LÀN TRACK LANE (Xếp chồng dọc) | | - Track 01 Waveform Area (Hitbox cục bộ 1) | | - Track 02 Waveform Area (Hitbox cục bộ 2) | | - Track 03 Waveform Area (Hitbox cục bộ 3) | +-------------------------------------------------------------------------+ ``` --- ## 2. Đặc Tả Tương Tác 1: Chọn Cục Bộ & Phát Lặp Độc Lập (Local Track Selection & Solo Loop) ### 2.1. Hành động người dùng (User Action) * **Click chuột đơn (Mouse Press):** Người dùng nhấp chuột vào một điểm bất kỳ trên dạng sóng của một track (Ví dụ: Track 01). * *Hệ quả:* Track đó lập tức được highlight (*Active State*), các track khác chuyển sang trạng thái chờ. * **Kéo chuột (Mouse Drag):** Click và nhấn giữ chuột, kéo sang trái hoặc phải trên phần hiển thị sóng âm của track đó. * *Hệ quả:* Tạo ra một vùng chọn thời gian giới hạn bởi điểm nhấn đầu và điểm thả chuột cuối. ### 2.2. Cơ chế phát lặp (Loop Playback Logic) * **Chế độ phát:** Khi nhấn nút *Play Loop*, hệ thống chỉ phát lặp duy nhất đoạn nhạc nằm trong vùng chọn của track đang active. * **Xử lý Audio Engine ở Python:** * Tự động kích hoạt cơ chế Mute tạm thời cho tất cả các track khác, hoặc kích hoạt nhanh chế độ Solo cho track đang active trong luồng phát âm thanh. * Giới hạn mốc thời gian phát trong khoảng $T_{\text{start}}$ đến $T_{\text{end}}$. Khi kim phát phát chạm $T_{\text{end}}$, nhảy ngay lập tức về $T_{\text{start}}$ mà không dừng phát các luồng khác (nếu có). ### 2.3. Ánh xạ mã sự kiện Python (PyQt6 / PySide6 Concept) ```python # Giả lập xử lý sự kiện trong lớp TrackWaveformWidget(QWidget) def mousePressEvent(self, event): if event.button() == Qt.MouseButton.LeftButton: # 1. Kích hoạt chọn track hiện hành self.parent_session.set_active_track(self.track_id) # 2. Ghi nhận điểm mốc thời gian bắt đầu self.drag_start_time = self.pixel_to_time(event.position().x()) self.is_dragging = True def mouseMoveEvent(self, event): if self.is_dragging: current_time = self.pixel_to_time(event.position().x()) # Cập nhật vùng chọn cục bộ (Local Selection Range) self.parent_session.update_local_selection( track_id=self.track_id, start=min(self.drag_start_time, current_time), end=max(self.drag_start_time, current_time) ) ``` --- ## 3. Đặc Tả Tương Tác 2: Chọn Toàn Cục & Phát Lặp Đa Kênh (Global Timeline Selection & Master Loop) ### 3.1. Hành động người dùng (User Action) * **Định vị:** Di chuyển con trỏ chuột lên trên cùng, vào thanh chứa Timeline Ruler (Vị trí mũi tên màu đỏ trong hình `image_dfffa3.png`). * **Kéo chuột (Mouse Drag):** Click chuột vào thanh Ruler và kéo sang trái/phải. * *Hệ quả:* Một khung màu cam nhạt (*Selection Overlay*) xuất hiện và kéo dọc toàn bộ chiều cao màn hình xuyên qua tất cả các track từ trên xuống dưới (như hiển thị thực tế trong hình `image_dfffa3.png`). ### 3.2. Cơ chế phát lặp (Loop Playback Logic) * **Chế độ phát:** Khi nhấn nút *Play Loop*, hệ thống sẽ phát đồng thời tất cả các track (*Master Playback*) nhưng giới hạn vòng lặp đồng bộ chỉ nằm trong dải thời gian được bôi màu. * **Xử lý Audio Engine ở Python:** * Giữ nguyên trạng thái Mute/Solo hiện tại của các track (không tự động tắt tiếng các track khác). * Đồng bộ hóa pha của tất cả các luồng phát. Khi Playhead chạm mốc kết thúc vùng chọn $T_{\text{end}}$, toàn bộ các nguồn phát (*Audio Sources*) đang hoạt động đều phải nhảy đồng bộ về vị trí $T_{\text{start}}$. ### 3.3. Ánh xạ mã sự kiện Python (PyQt6 / PySide6 Concept) ```python # Giả lập xử lý sự kiện trong lớp TimelineRulerWidget(QWidget) def mousePressEvent(self, event): if event.button() == Qt.MouseButton.LeftButton: # Ghi nhận mốc thời gian toàn cục ban đầu self.global_drag_start = self.pixel_to_time(event.position().x()) self.is_dragging_global = True # Hủy bỏ các vùng chọn cục bộ (nếu có) để ưu tiên chế độ chọn tổng thể self.parent_session.clear_all_local_selections() def mouseMoveEvent(self, event): if self.is_dragging_global: current_time = self.pixel_to_time(event.position().x()) # Cập nhật vùng chọn toàn cục xuyên suốt tất cả các làn track self.parent_session.set_global_selection( start=min(self.global_drag_start, current_time), end=max(self.global_drag_start, current_time) ) ``` --- ## 4. Tóm Tắt Sự Khác Biệt Giữa 2 Trạng Trạng Thái Để đảm bảo hệ thống không bị xung đột khi xử lý đa luồng âm thanh trên Python Docker, bộ điều phối âm thanh (*Audio Coordinator*) cần tuân thủ bảng logic sau: | Thuộc tính | Tương tác trên Track (Local) | Tương tác trên Ruler (Global) | | --- | --- | --- | | **Phạm vi hiển thị vùng chọn** | Chỉ hiển thị hoặc sáng rõ tại track đang active. | Kéo dài thẳng đứng, phủ qua tất cả các track (như hình `image_dfffa3.png`). | | **Phạm vi phát âm thanh** | **Solo Playback:** Chỉ phát duy nhất âm thanh của track được chọn. | **Master Playback:** Phát tất cả các track cùng lúc (không tự động Solo/Mute). | | **Điểm lặp (Loop Target)** | $T_{\text{start}} \rightarrow T_{\text{end}}$ của riêng track hoạt động. | $T_{\text{start}} \rightarrow T_{\text{end}}$ toàn cục đồng bộ tất cả các track. | | **Phục vụ AI Cut** | Chỉ cắt tệp tin của riêng track được chọn để đưa sang track mới. | Cho phép render/mixdown gộp tất cả các track trong dải chọn thành tệp mới. |