fix&feat: 11_REFACTOR_UI.md sửa lỗi UI và thêm các tính năng của track timeline
This commit is contained in:
@@ -0,0 +1,164 @@
|
|||||||
|
# Technical Specification: Advanced UI Refactoring & Clip Editing Mechanics
|
||||||
|
|
||||||
|
This document defines the improved user interface design and advanced audio interaction algorithms to standardize frontend development and porting workflows into a containerized Python DAW application running on Docker.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. UI Refactoring Specification
|
||||||
|
|
||||||
|
### 1.1. Resolving TCP Horizontal Scroll Overflows (Horizontal Scroll Isolation)
|
||||||
|
|
||||||
|
* **Symptom:** When scrolling horizontally across the Timeline, waveform or grid canvas elements incorrectly render on top of the left Track Control Panel (TCP) region.
|
||||||
|
* **Refactoring Solution:** Enforce strict visual separation using Flexbox constraints. The master arrangement window (Workspace) is divided into two physically adjacent columns with completely isolated presentation variables:
|
||||||
|
|
||||||
|
```css
|
||||||
|
.tcp-column {
|
||||||
|
width: 300px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
position: relative;
|
||||||
|
z-index: 30; /* Ensures columns stay stacked on top */
|
||||||
|
background-color: #262626; /* Solid, opaque color mask */
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.timeline-viewport {
|
||||||
|
flex: 1 1 0%;
|
||||||
|
position: relative;
|
||||||
|
z-index: 10;
|
||||||
|
overflow-x: auto;
|
||||||
|
overflow-y: hidden; /* Restricts column to independent horizontal scrolling */
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.2. Prominent Shortcut Labels
|
||||||
|
|
||||||
|
* **Graphical Standard:** Scale up text components displaying key combination hints within system dropdown menus and right-click Context Menus.
|
||||||
|
* **Layout Mapping Properties:**
|
||||||
|
* Keyboard shortcut font sizing: Scaled up from 10px to 12px (`text-[12px]`).
|
||||||
|
* Weight property: Configured to `font-semibold`.
|
||||||
|
* High-contrast color palette: Replace low-contrast gray strings with vivid purple (`text-purple-400` / `#c084fc`) or neon amber (`text-amber-400` / `#fbbf24`) that pop cleanly over the dark `#1e1e1e` canvas backdrop.
|
||||||
|
* Structural alignment: Push shortcut labels directly to the right edge of the context window (`ml-auto pl-8`).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### 1.3. Enlarged & Centered Toolbar
|
||||||
|
|
||||||
|
* **Layout Adjustment:** Primary editing triggers (Cut, Copy, Paste, Snap) are scaled up to $1.5\times$ their legacy sizing boundaries (button height locked at 40px).
|
||||||
|
* **Viewport Placement:** Move the button group into the center cluster on the same horizontal row plane as the ruler axis (positioned immediately to the left of the Time Ruler). This ensures the sound engineer's focus safely encapsulates macro controls alongside timeline visuals.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Timeline Mechanics & Advanced Clip Editing
|
||||||
|
|
||||||
|
### 2.1. Clip Delete vs. Track Delete Logic
|
||||||
|
|
||||||
|
The environment explicitly segregates asset deletions from track configurations to protect project layout structures:
|
||||||
|
|
||||||
|
* **Clip Erasure (`Delete` Key):** When a user triggers `Delete` or `Backspace` keys while an active Audio Clip segment is selected, the application drops the graphical boundary and unloads its corresponding sample sequence from the timeline. The containing track channel remains safely intact.
|
||||||
|
* **Track Disassembly (TCP Delete Button):** Add a compact red trash bin icon (`w-4 h-4 text-red-500 hover:text-red-400`) into the right edge profile of every TCP block. Engaging this trigger purges the entire track lane along with all embedded clip blocks out of the project.
|
||||||
|
|
||||||
|
### 2.2. Preserve Selection Border Resize
|
||||||
|
|
||||||
|
* **Legacy Behavior:** Clicking or interacting directly with selection handles accidentally flags a focus reset, clearing the bôi màu canvas overlay.
|
||||||
|
* **Preserve & Scale System:**
|
||||||
|
* When hovering the mouse near the explicit left or right edge boundaries of an active selection zone (within a $\pm 5\text{ px}$ tolerance window), the cursor style changes to `ew-resize`.
|
||||||
|
* Triggering a mouse drag updates, expands, or shrinks selection markers continuously without clearing the overlay mask.
|
||||||
|
|
||||||
|
|
||||||
|
* **Escape Loop Hook (Clear Focus):** The colored selection range is unmapped if and only if the user executes a `Ctrl + Click` shortcut interaction over an empty, unpopulated quadrant outside the selection bounds.
|
||||||
|
|
||||||
|
### 2.3. Sub-tab Sandboxing
|
||||||
|
|
||||||
|
When a user highlights a clip portion and triggers "Edit in Sub-tab" or double-clicks a targeted audio asset clip:
|
||||||
|
|
||||||
|
1. **Buffer Extraction:** The system maps a non-destructive copy of the target sub-region's audio slice into memory buffers.
|
||||||
|
2. **Tab Instantiation:** Appends a temporary document window onto the global Tab container bar (e.g., `Tab: Sample_Edit_1`).
|
||||||
|
3. **Automated Insertion:** Instantiates a single empty track channel workspace inside the tab context and drops the cloned audio segment at the absolute root milestone ($t = 0.0\text{ s}$). Editors evaluate local actions here before clicking *Apply* to pass the updated data payload back to the main session track.
|
||||||
|
|
||||||
|
### 2.4. Zero-Crossing Filter Tool & AI Cut
|
||||||
|
|
||||||
|
Automated crossfade calculation mechanics to eliminate popping anomalies during clip slicing:
|
||||||
|
|
||||||
|
1. A user selects a timeline region and hits the *AI Analysis* utility.
|
||||||
|
2. The server processes the audio block using NumPy arrays to locate phase inversion milestones (where amplitude values cross from negative to positive indices or vice versa) closest to the selection boundary vectors:
|
||||||
|
|
||||||
|
$$x[i] \cdot x[i+1] \le 0$$
|
||||||
|
|
||||||
|
|
||||||
|
3. The engine moves the actual slice boundaries to match these optimized zero-crossing sample addresses ($t'_{\text{start}}$ and $t'_{\text{end}}$).
|
||||||
|
4. Upon clicking *AI Cut*, the underlying engine runs the physical audio slice at the perfect sample indices, duplicates the segment, and appends it to a freshly populated track lane added right below the source track.
|
||||||
|
|
||||||
|
### 2.5. Track Height Resizing
|
||||||
|
|
||||||
|
* **Interaction:** Users can hover over the dividing line between two track lanes on either the left TCP column or the right Waveform viewport (the cursor scales to `ns-resize`).
|
||||||
|
* **Drag-and-Drop Mapping:** Dragging downward expands the specific track lane vertical ceiling (up to an upper bound of $200\text{ px}$), magnifying waveform amplitude layouts for precision edits. Dragging upward reduces the height dimension (down to a lower ceiling of $48\text{ px}$) for macro project navigation.
|
||||||
|
|
||||||
|
### 2.6. Time-Stretching & Speed Math
|
||||||
|
|
||||||
|
Alters the playback rate (*Speed*) of audio clips directly from the interactive timeline view:
|
||||||
|
|
||||||
|
```text
|
||||||
|
[ Right Boundary Drag Interaction ]
|
||||||
|
Alt + Left-Click & Drag the right border outwards (Expand)
|
||||||
|
|<────────────────── Original Clip ──────────────────>|
|
||||||
|
+─────────────────+─────────────────────────────────────────────────────+──────────+
|
||||||
|
| Track Waveform | ███████████████████████████████████████████████████ | |
|
||||||
|
+─────────────────+─────────────────────────────────────────────────────+──────────+
|
||||||
|
▲ ▲
|
||||||
|
│ │
|
||||||
|
│ ▼ [ Expand Rightward ]
|
||||||
|
+─────────────────+────────────────────────────────────────────────────────────────+
|
||||||
|
| Track Waveform | █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ |
|
||||||
|
+─────────────────+────────────────────────────────────────────────────────────────+
|
||||||
|
│ │
|
||||||
|
│ Visual Speed Tag: "Speed: 50%" │
|
||||||
|
|<────────────────────────── D' ─────────────────────────────>|
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
* **Modifier Binding:** Hold down the `Alt` key, left-click the rightmost bounding handle of a clip, and drag the boundary left or right.
|
||||||
|
* **Speed Ratio Formula ($S$):** Let $D$ represent the native unscaled duration value of the clip block (seconds), and $D'$ map to the modified duration value generated post-drag (seconds). The calculation for the updated target playback rate percentage ($S$) follows:
|
||||||
|
|
||||||
|
$$S = \frac{D}{D'} \times 100\%$$
|
||||||
|
|
||||||
|
|
||||||
|
* **Display Modifiers:**
|
||||||
|
* *Expanding rightward ($D' > D$):* Yields $S < 100\%$, meaning playback velocity drops (deceleration). Depending on DSP choices, pitches can either remain locked or drop proportionally.
|
||||||
|
* *Compressing leftward ($D' < D$):* Yields $S > 100\%$, accelerating the playback engine velocity through the clip.
|
||||||
|
|
||||||
|
|
||||||
|
* **Visual Metadata Tag:** A bright yellow text overlay displaying the calculated playback velocity percentage (e.g., `Speed: 75.0%` or `Speed: 120.5%`) is pinned directly to the upper-left boundary of the audio clip container.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Python Porting Manual (PyQt6 / PySide6)
|
||||||
|
|
||||||
|
When writing execution blocks for time-stretching and audio rate modulations onto the Python backend server layers, leverage standard scientific audio packages such as `numpy` or `rubberband` to scale signal arrays without warping Phase layouts:
|
||||||
|
|
||||||
|
```python
|
||||||
|
# [PYTHON PORTING BLUEPRINT] - Acoustic Time-Stretching Velocity Algorithm
|
||||||
|
import numpy as np
|
||||||
|
import librosa
|
||||||
|
|
||||||
|
def stretch_audio_clip_speed(y: np.ndarray, sr: int, speed_ratio: float) -> np.ndarray:
|
||||||
|
"""
|
||||||
|
Stretches or compresses a NumPy audio signal array using the target speed_ratio factor.
|
||||||
|
speed_ratio = 0.5 slows down velocity by half (expanding physical layout width by 2x).
|
||||||
|
speed_ratio = 2.0 doubles velocity (compressing physical layout width by half).
|
||||||
|
"""
|
||||||
|
if speed_ratio == 1.0:
|
||||||
|
return y
|
||||||
|
|
||||||
|
# Phase Vocoder approach via Librosa to alter speed while locking pitch (Pitch-preserving stretch):
|
||||||
|
# y_stretched = librosa.effects.time_stretch(y, rate=speed_ratio)
|
||||||
|
|
||||||
|
# Linear Resampling approach (Alters pitch along with velocity - vinyl style deceleration):
|
||||||
|
num_samples_new = int(len(y) / speed_ratio)
|
||||||
|
y_resampled = np.interp(
|
||||||
|
np.linspace(0, len(y) - 1, num_samples_new),
|
||||||
|
np.arange(len(y)),
|
||||||
|
y
|
||||||
|
)
|
||||||
|
return y_resampled.astype(np.float32)
|
||||||
|
|
||||||
|
```
|
||||||
+907
-387
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user