
# Tài Liệu Đặc Tả Giao Diện (UI Blueprint): SonicForge Studio Pro DAW

Tài liệu này đặc tả chi tiết cấu trúc, bố cục, thông số thiết kế và cơ chế tương tác của giao diện SonicForge Studio (trong tệp `index.html`). Tài liệu được biên soạn nhằm mục đích hướng dẫn lập trình viên dựng lại (port) giao diện này sang các ứng dụng Python một cách chính xác bằng các thư viện như PyQt6 / PySide6 (`QGraphicsView`), Flet (Flutter for Python), hoặc Reflex / NiceGUI.

---

## 1. Thông Số Thiết Kế Hệ Thống (Design Tokens)

Giao diện SonicForge Studio sử dụng phong cách *Dark Charcoal Studio* tối giản, chuyên nghiệp và có độ tương phản cao nhằm giảm mỏi mắt khi làm việc trong thời gian dài.

| Thuộc tính | Giá trị màu HEX | Ánh xạ mã màu Tailwind | Mô tả ứng dụng |
| --- | --- | --- | --- |
| **Trần nền chính** | `#111111` | `bg-zinc-950` / `bg-[#111111]` | Nền của lưới dòng thời gian (Timeline grid) |
| **Nền ứng dụng** | `#1e1e1e` | `bg-zinc-900` / `bg-[#1e1e1e]` | Nền tổng thể của toàn bộ cửa sổ phần mềm |
| **Nền bảng điều khiển** | `#262626` | `bg-zinc-800` / `bg-[#262626]` | Nền của TCP (bên trái) và Footer (bên dưới) |
| **Nền thanh công cụ** | `#2e2e2e` | `bg-[#2e2e2e]` | Nền của thanh Header và thước đo thời gian (Ruler) |
| **Màu nhấn chính** | `#ef4444` | `text-red-500` / `bg-red-500` | Con trỏ phát nhạc (Playhead), núm âm lượng chủ |
| **Màu nhấn phụ** | `#06b6d4` | `text-cyan-500` / `bg-cyan-500` | Trạng thái chọn track hoạt động (Active select border) |
| **Màu vùng chọn** | `#f59e0b` (Alpha: 0.1) | `bg-amber-500/10` / `border-amber-500` | Khung phủ vùng chọn thời gian (Selection Overlay) |
| **Kiểu chữ (Font)** | `Inter, sans-serif` | - | Sử dụng font Sans-serif không chân, thanh mẫu |

---

## 2. Bản Vẽ Bố Cục Không Gian (Layout Architecture)

Cửa sổ làm việc được chia làm 3 khu vực chính theo chiều dọc màn hình (*Vertical Stack Layout*):

```text
+-----------------------------------------------------------------------+
|  [1] HEADER & AI CONFIG DRAWER (Chiều cao cố định: 44px)              |
+-----------------------------------------------------------------------+
|  [2] WORKSPACE (Chiều cao linh hoạt - Fill Remaining Space)           |
|  +---------------------------+-------------------------------------+  |
|  | [2.A] TRACK CONTROL PANEL | [2.B] TIMELINE LANES & RULER        |  |
|  |       (Width: 300px)      |       (Horizontal & Vertical Scroll)|  |
|  |                           |                                     |  |
|  | - Track ID & Name         | - Sticky Time Ruler (top-0)         |  |
|  | - Solo (S) & Mute (M)     | - Stacked Waveform Canvases         |  |
|  | - Volume Rotary Knob      | - Interactive Selection Overlay    |  |
|  | - Upload Local/Synth      | - Global Playhead Line (Vertical)   |  |
|  |                           |                                     |  |
|  +---------------------------+-------------------------------------+  |
+-----------------------------------------------------------------------+
|  [3] FOOTER PANEL & TRANSPORT (Chiều cao cố định: 176px)              |
+-----------------------------------------------------------------------+
|  [4] UTILITY STATUS BAR (Chiều cao cố định: 24px)                     |
+-----------------------------------------------------------------------+

```

---

## 3. Đặc Tả Chi Tiết Thành Phần (Widget Specification)

### 2.A. Bảng Điều Khiển Kênh (Track Control Panel - TCP)

* **Chiều rộng:** Cố định 300px.
* **Cấu trúc:** Chứa danh sách các Track được xếp dọc.
* **Mỗi hàng (Track Header):** Chiều cao 96px (Đồng bộ tuyệt đối với chiều cao Waveform Lane bên phải).
* **Chỉ số (Index):** Số thứ tự track dạng Monospace (ví dụ: `01`, `02`).
* **Trạng thái màu:** Đèn LED tròn hiển thị màu đặc trưng của track (ví dụ: lục, lam, tím).
* **Tên tệp tin:** Nhãn chữ có tính năng thu gọn tự động (`truncate`).
* **Nút Mute (M):** Khi bật sẽ hiển thị nền đỏ (`bg-red-950` / `text-red-400`).
* **Nút Solo (S):** Khi bật sẽ hiển thị nền hổ phách (`bg-amber-950` / `text-amber-400`).
* **Volume Rotary Knob:** Thiết kế dạng núm vặn xoay tròn 2D.
* *Cơ chế hoạt động:* Nhấp và giữ chuột trên núm, kéo chuột lên trên để tăng Volume (vặn cùng chiều kim đồng hồ, giới hạn quay $+135^\circ$), kéo chuột xuống dưới để giảm Volume (vặn ngược chiều kim đồng hồ, giới hạn quay $-135^\circ$).


* **Nút Upload:** Nút bấm cục bộ mở hộp thoại chọn tệp âm thanh trên máy.

### 2.B. Khu Vực Dòng Thời Gian (Timeline & Waveform Lanes)

* **Chiều rộng:** Trải rộng chiếm toàn bộ phần màn hình còn lại.
* **Thước Đo Thời Gian (Ruler):**
* Chiều cao 32px (`sticky top-0`), luôn hiển thị ở trên cùng kể cả khi cuộn dọc.
* Hiển thị vạch chia độ theo từng giây dựa trên mức độ thu phóng (zoom). Định dạng thời gian: `M:SS.mmm`.


* **Các Làn Sóng Âm (Waveform Lanes):**
* Chiều cao mỗi làn: Cố định 96px (tươngương với chiều cao của Track Header bên trái).
* Sử dụng một đối tượng Canvas để vẽ đồ thị sóng âm thời gian thực. Sóng âm vẽ đối xứng qua trục nằm ngang chính giữa.


* **Vùng Chọn Phủ (Selection Overlay):**
* Một phân vùng bán trong suốt màu hổ phách (`bg-amber-500/10`) bao quanh khoảng thời gian được chọn.
* Ranh giới phía trên bắt đầu từ mép dưới thước Ruler (`top-8` hay 32px), kéo dài xuống tận đáy của toàn bộ các track để không đè và che khuất dải sóng âm phía trên.
* Hai đầu biên có thanh nắm (Handles) màu cam (`w-3`) để co dãn vùng chọn bằng cách kéo chuột (`EW-resize`).


* **Đường Chỉ Con Trỏ (Global Playhead Line):**
* Một đường kẻ đứng màu đỏ (`w-[2px] bg-red-500`) chạy dọc từ trên xuống dưới, ghim một tam giác đỏ nhỏ ở đỉnh thước Ruler.



---

## 4. Đặc Tả Cơ Chế Tương Tác & Lập Trình (Interactivity Specs)

Để chuyển giao chính xác sang Python (ví dụ sử dụng PyQt6 hoặc Soundfile/Numpy), cần lập trình chính xác các cơ chế điều khiển sau:

### A. Thuật Toán Phóng To/Thu Nhỏ Theo Vị Trí Chuột (Mouse-Anchored Zoom)

* **Sự kiện kích hoạt:** Cuộn chuột (`wheel`) trên vùng Timeline.
* **Cơ chế:**
1. Ghi nhận vị trí hoành độ `mouseX` của con trỏ chuột đối với khung chứa.
2. Xác định mốc thời gian tuyệt đối tại điểm chuột đang chỉ:

$$\text{anchorTime} = \frac{\text{mouseX} + \text{scrollLeft}}{\text{currentZoom}}$$


3. Cập nhật tỷ lệ zoom mới:

$$\text{newZoom} = \text{currentZoom} \times \text{zoomFactor}$$



*(Ràng buộc: $\text{minZoom} \le \text{newZoom} \le 2000\text{ px/s}$)*
4. Sau khi vẽ lại đồ thị, tính toán và gán lại vị trí thanh cuộn ngang để khóa điểm âm thanh dưới chuột đứng im:

$$\text{newScrollLeft} = (\text{anchorTime} \times \text{newZoom}) - \text{mouseX}$$





### B. Cơ Chế Di Chuyển Đầu/Cuối Vùng Chọn (Selection Resize & Move)

* **Kéo giãn (Resize):**
* Khi nhấp giữ chuột vào Handle trái: Cập nhật `selectionStart` tương ứng với vị trí chuột nhưng khống chế không được vượt quá `selectionEnd`.
* Khi nhấp giữ chuột vào Handle phải: Cập nhật `selectionEnd` nhưng không được nhỏ hơn `selectionStart`.


* **Dịch chuyển (Move):**
* Khi nhấp vào vùng lòng trong của dải chọn (màu cam nhạt), ghi nhận khoảng cách thời gian giữa hai đầu ($\Delta t = \text{end} - \text{start}$).
* Khi di chuột sang trái/phải, tịnh tiến đồng thời cả `start` và `end` một lượng tương đương mà vẫn giữ nguyên độ rộng $\Delta t$.



### C. Logic Lặp Không Độ Trễ (Seamless Looping Logic)

* Khi playhead chạy đến mốc `selectionEnd`, hệ thống phát nhạc phải kích hoạt nhảy ngay lập tức về mốc phát `selectionStart` ở tầng Audio Thread để tránh hiện tượng vấp hoặc trễ nhịp âm thanh.

---

## 5. Bản Đồ Ánh Xạ Sang Thư Viện Python (Python GUI Mapping)

Nếu bạn lựa chọn phát triển ứng dụng máy để bàn (Desktop Application) bằng Python, dưới đây là bảng tham chiếu các lớp Widget tương đương trong thư viện PyQt6 / PySide6:

| Thành phần giao diện (React/HTML) | Thành phần tương đương trong PyQt6 / PySide6 | Phương thức xử lý / Ghi chú |
| --- | --- | --- |
| **Workspace Scroll Container** | `QScrollArea` | Cho phép cuộn đứng đồng bộ cả TCP và Waveforms. |
| **Track Control Panel (TCP)** | `QVBoxLayout` chứa các `QWidget` | Layout xếp dọc, cố định chiều rộng bằng `.setFixedWidth(300)`. |
| **Ruler & Waveform Lanes** | `QGraphicsView` & `QGraphicsScene` | Thích hợp nhất để vẽ đồ thị vectơ sóng âm, playhead line và selection block nhờ khả năng vẽ hai tầng bộ đệm (*Double-buffering*) tốc độ cao. |
| **Waveform Canvas Painter** | `QPainter.drawPath()` / `QPainterPath` | Chuyển đổi dữ liệu mẫu thô (`numpy.ndarray`) thành một tập hợp các đường thẳng đứng biểu diễn biên độ đỉnh âm học (*Peak Waveform*). |
| **Volume Knob Control** | `QDial` hoặc Custom `QWidget` | Tùy biến sự kiện `mouseMoveEvent` để tính toán góc xoay núm âm lượng. |
| **Time Formatter** | Hàm định dạng chuỗi Python | `f"{minutes:02d}:{seconds:02d}.{milliseconds:03d}"` |

---

## 6. Sơ Đồ Cấu Trúc JSON Phục Vụ Port API

Khi Frontend tương tác và nhấn nút **AI Cut & New Track**, cấu hình dải chọn sẽ được đóng gói và gửi thẳng về Dockerized Python API theo định dạng chuẩn sau:

```json
{
  "session_id": "pro_session_active",
  "source_track_id": "1",
  "selection": {
    "start_seconds": 2.458,
    "end_seconds": 7.892
  },
  "dsp_actions": {
    "zero_crossing_align": true,
    "apply_fades_ms": 50,
    "volume_db_change": 0.0
  },
  "export_format": "wav"
}

```

