diff --git a/DEVELOP_PLAN.md b/1_DEVELOP_PLAN.md similarity index 100% rename from DEVELOP_PLAN.md rename to 1_DEVELOP_PLAN.md diff --git a/UI_PLAN.md b/2_UI_PLAN.md similarity index 100% rename from UI_PLAN.md rename to 2_UI_PLAN.md diff --git a/LOOP_MAKER.md b/3_LOOP_MAKER.md similarity index 100% rename from LOOP_MAKER.md rename to 3_LOOP_MAKER.md diff --git a/LOOP_EDITOR.md b/4_LOOP_EDITOR.md similarity index 100% rename from LOOP_EDITOR.md rename to 4_LOOP_EDITOR.md diff --git a/LOOP_EDITOR_2.md b/5_LOOP_EDITOR_2.md similarity index 100% rename from LOOP_EDITOR_2.md rename to 5_LOOP_EDITOR_2.md diff --git a/NEW_PLAN.md b/6_NEW_PLAN.md similarity index 100% rename from NEW_PLAN.md rename to 6_NEW_PLAN.md diff --git a/SUB_EDITOR.md b/SUB_EDITOR.md new file mode 100644 index 0000000..ed03259 --- /dev/null +++ b/SUB_EDITOR.md @@ -0,0 +1,182 @@ +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, sơ đồ luồng ASCII và các công thức toán học dạng LaTeX: + +# Technical Specification: Sub-Tab Audio Clip Editor & DSP Operations + +This document outlines the software engineering specification for the temporary isolated Sub-Tab Audio Clip Editor. It defines internal clipboard mechanics, DSP algorithms for selection-based operations, Context Menu structures, and main application menu shortcuts. + +--- + +## 1. Clipboard & Cursor-Aligned Insertion Mechanics + +The Sub-Tab workspace features an isolated, low-latency stereo/mono audio buffer. The editor tracks a local virtual playhead position $t_{\text{cursor}}$ and handles clipboard buffers using non-destructive splicing techniques. + +```text + Local Timeline Buffer ++-------------------------------------------------------+ +| Track Waveform Segment │ | ++-------------------------------┼-----------------------+ + ▲ + t_cursor (Insertion Point) + │ + ▼ [ PASTE TRIGGERED ] ++-------------------------------------------------------+ +| Track Waveform Segment │ CLIPBOARD DATA │ | ++-------------------------------------------------------+ + ◄──────────────► + clip_duration + +``` + +### 1.1. Cursor Paste Action + +When a paste command is issued (either via Context Menu, Application Menu, or Hotkey): + +* **Payload Extraction:** Retrieve the copied `AudioBufferSegment` from the system/application clipboard. +* **Splicing Boundary Calculations:** Slice the current active timeline buffer at $t_{\text{cursor}}$. +* **Re-allocation & Stitching:** +* Compute the new duration: $T_{\text{new}} = T_{\text{original}} + T_{\text{clipboard}}$. +* Allocate a new virtual audio array $Y_{\text{new}}$: + + + +$$Y_{\text{new}}(t) = \begin{cases} Y_{\text{original}}(t) & 0 \le t < t_{\text{cursor}} \\ Y_{\text{clipboard}}(t - t_{\text{cursor}}) & t_{\text{cursor}} \le t < t_{\text{cursor}} + T_{\text{clipboard}} \\ Y_{\text{original}}(t - T_{\text{clipboard}}) & t_{\text{cursor}} + T_{\text{clipboard}} \le t \le T_{\text{new}} \end{cases}$$ + +* **Playhead Update:** Advance the active playhead $t_{\text{cursor}}$ immediately to $t_{\text{cursor}} + T_{\text{clipboard}}$. + +--- + +## 2. Selection Context Menu & DSP Engine + +Right-clicking inside a highlighted region $[T_{\text{start}}, T_{\text{end}}]$ of the Waveform Canvas triggers an overlay context menu containing the following DSP and editing commands. + +```text ++---------------------------------------------+ +| Selection: [ 01:02.100 - 01:05.400 ] | ++---------------------------------------------+ +| Normalize Selection To Peak | +| Adjust Gain/Volume... | +| Adjust Panning (Stereo Balance)... | +| Fade In (Linear/Exponential) | +| Fade Out (Linear/Exponential) | +|---------------------------------------------| +| Cut Ctrl+X | +| Copy Ctrl+C | +| Paste Ctrl+V | +| Delete Selected Segment Del | +|---------------------------------------------| +| Loop Selection: [ ▲ ] [ 4 ] [ ▼ ] times | ++---------------------------------------------+ + +``` + +### 2.1. Normalize Selection + +Scales the peak amplitude of the selected segment to a target ceiling $A_{\text{target}}$ (defaulting to $1.0$ or $0\text{ dBFS}$): + +$$Y_{\text{norm}}(t) = Y(t) \cdot \frac{A_{\text{target}}}{\max_{u \in [T_{\text{start}}, T_{\text{end}}]} \vert{}Y(u)\vert{}} \quad \text{for } t \in [T_{\text{start}}, T_{\text{end}}]$$ + +### 2.2. Volume (Gain dB) Adjustment + +Applies a static linear gain multiplier derived from user-specified decibel scaling values ($\Delta\text{dB}$): + +$$G = 10^{\frac{\Delta\text{dB}}{20}}$$ + +$$Y_{\text{gained}}(t) = Y(t) \cdot G \quad \text{for } t \in [T_{\text{start}}, T_{\text{end}}]$$ + +### 2.3. Panning (Stereo Balance) + +Applies a constant-power panning law across Left ($L$) and Right ($R$) channels based on the panning angle $\theta \in [0, \pi/2]$, where $\theta = \pi/4$ represents absolute center: + +$$Y_L(t) = Y_{\text{mono}}(t) \cdot \cos(\theta), \quad Y_R(t) = Y_{\text{mono}}(t) \cdot \sin(\theta)$$ + +### 2.4. Fade-In and Fade-Out (Linear / Exponential) + +* **Linear Fade-In Curve:** + +$$f_{\text{in}}(t) = \frac{t - T_{\text{start}}}{T_{\text{end}} - T_{\text{start}}} \quad \text{for } t \in [T_{\text{start}}, T_{\text{end}}]$$ + +* **Linear Fade-Out Curve:** + +$$f_{\text{out}}(t) = 1.0 - \frac{t - T_{\text{start}}}{T_{\text{end}} - T_{\text{start}}} \quad \text{for } t \in [T_{\text{start}}, T_{\text{end}}]$$ + +### 2.5. Delete, Cut, and Copy + +* **Delete:** Erases the selected segment $[T_{\text{start}}, T_{\text{end}}]$ and shifts all subsequent samples leftward. +* **Cut:** Copies the selected samples to the clipboard, then executes the *Delete* routine. +* **Copy:** Writes the targeted buffer segment to the clip memory without modifying the timeline. + +### 2.6. Segment Looping with Step Multiplier + +Repeats the selected segment $[T_{\text{start}}, T_{\text{end}}]$ consecutively $N$ times. The menu provides a numeric spinner (Up/Down buttons) to adjust $N$: + +1. Extract segment: $Y_{\text{segment}} = Y(t)$ for $t \in [T_{\text{start}}, T_{\text{end}}]$. +2. Compute new duration adjustment: $\Delta L = (N - 1) \cdot (T_{\text{end}} - T_{\text{start}})$. +3. Duplicate and insert $Y_{\text{segment}}$ array $N-1$ times directly after $T_{\text{end}}$. + +--- + +## 3. Global Menu Bar & Keyboard Shortcut Matrix + +All context-dependent sub-tab actions are mapped directly to the global Menu Bar at the top of the DAW window, as specified in `image_e0e462.png`. + +```text +File Edit View Insert Track Options Actions Extensions Help + │ + ├── Normalize Selection [Ctrl+Alt+N] + ├── Adjust Volume... [V] + ├── Adjust Panning... [P] + ├── Fade In [F] + ├── Fade Out [G] + ├── Cut [Ctrl+X] + ├── Copy [Ctrl+C] + ├── Paste [Ctrl+V] + ├── Delete [Del] + └── Loop Clip... [Ctrl+L] + +``` + +### 3.1. Keyboard Mapping Table + +To maximize speed and accessibility, the system listens for global key event hooks within the Sub-Tab window focus: + +| Action Command | Main Menu Category | Recommended Keyboard Shortcut | Python Event Trigger (`QKeyEvent`) | +| --- | --- | --- | --- | +| **Cut** | Edit -> Cut | `Ctrl + X` | `Qt.Key.Key_X` + `ControlModifier` | +| **Copy** | Edit -> Copy | `Ctrl + C` | `Qt.Key.Key_C` + `ControlModifier` | +| **Paste** | Edit -> Paste | `Ctrl + V` | `Qt.Key.Key_V` + `ControlModifier` | +| **Delete** | Edit -> Delete | `Del` / `Backspace` | `Qt.Key.Key_Delete` / `Key_Backspace` | +| **Normalize** | Actions -> Normalize | `Ctrl + Alt + N` | `Qt.Key.Key_N` + `ControlModifier` + `AltModifier` | +| **Fade In** | Actions -> Fade In | `F` | `Qt.Key.Key_F` | +| **Fade Out** | Actions -> Fade Out | `G` | `Qt.Key.Key_G` | +| **Loop Segment** | Actions -> Loop... | `Ctrl + L` | `Qt.Key.Key_L` + `ControlModifier` | +| **Adjust Volume** | Actions -> Gain... | `V` | `Qt.Key.Key_V` | +| **Adjust Panning** | Actions -> Panning... | `P` | `Qt.Key.Key_P` | + +--- + +## 4. Python Implementation Notes for Docker Server Porting + +When porting these sub-tab operations to your Python DSP engine (`core/audio_editor.py`), use NumPy slice vectors to perform non-destructive edits on waveforms: + +```python +# Prototype helper for non-destructive volume adjustment in Python +import numpy as np + +def apply_gain_on_segment(y: np.ndarray, sr: int, start_sec: float, end_sec: float, gain_db: float) -> np.ndarray: + """ + Applies gain in dB to a selected segment of a mono numpy audio array. + """ + # 1. Translate time coordinates securely with boundary checking + start_sample = max(0, int(start_sec * sr)) + end_sample = min(len(y), int(end_sec * sr)) + + # 2. Convert dB value to linear multiplier + multiplier = 10.0 ** (gain_db / 20.0) + + # 3. Create a deep copy and modify segment in-place + y_edited = np.copy(y) + y_edited[start_sample:end_sample] *= multiplier + + return y_edited + +``` \ No newline at end of file diff --git a/app/templates/index.html b/app/templates/index.html index f741938..695f82c 100644 --- a/app/templates/index.html +++ b/app/templates/index.html @@ -6,9 +6,9 @@ SonicForge Studio - Professional DAW Editor - - - + + +