
Trò chuyện với Gemini
Hãy chuyển nội dung sau sang dạng markdown:

Kế Hoạch & Tài Liệu Kỹ Thuật: Porting DSP Engine Từ Frontend (JS) Sang Python (Docker)

Tài liệu này đóng vai trò là cẩm nang kỹ thuật hướng dẫn chi tiết cách dịch chuyển (port) các thuật toán tương tác âm thanh, bộ xử lý tín hiệu số (DSP) và cấu trúc quản lý từ mã nguồn Frontend (Web Audio API) sang hệ thống xử lý tập trung phía Server bằng Python, chạy trong container Docker.

1. Bản Đồ Ánh Xạ Công Nghệ (Technology Mapping)

Để đảm bảo hiệu năng xử lý tệp tin âm thanh lớn và triệt tiêu sai số thời gian thực, các tác vụ tính toán tương đương trên trình duyệt sẽ được ánh xạ sang các thư viện Python chuyên dụng như sau:

Chức năng ở Frontend (JS)

Cơ chế hoạt động của Web Audio

Thư viện & Module Python thay thế

Giải mã âm thanh

AudioContext.decodeAudioData()

librosa.load() hoặc soundfile.read()

Tìm Zero-Crossing

Duyệt mảng Float32Array thủ công

Phép toán mảng numpy.diff() & numpy.sign()

Cắt & Tạo Loop

AudioBuffer.slice() & AudioBufferSourceNode.loop

pydub.AudioSegment hoặc Slicing trên numpy.ndarray

Fade-in / Fade-out

GainNode.gain.linearRampToValueAtTime()

pydub.fade() hoặc Nhân mảng với numpy.linspace()

Thay đổi Volume (Gain)

GainNode.gain.value

Phép nhân số thực trên mảng numpy hoặc pydub + dB

Trộn âm đa kênh

OfflineAudioContext (Mixdown)

pydub.AudioSegment.overlay() hoặc Phép cộng mảng Numpy

Xuất tệp WAV/MP3/OGG

Ghi dữ liệu nhị phân RIFF thủ công

soundfile.write() (WAV) và pydub/FFmpeg (MP3, OGG)

2. Porting Thuật Toán DSP Cốt Lõi (Core DSP Algorithms)

2.1. Tìm kiếm điểm Zero-Crossing (Triệt tiêu tiếng Click/Pop)

Trong JavaScript, ta quét một cửa sổ $\pm 40\text{ms}$ quanh vị trí đích. Trong Python, ta tối ưu hóa tốc độ quét bằng các phép toán vectơ hóa trên Numpy để tìm ra chỉ số mảng có biên độ đổi dấu từ dương sang âm (hoặc ngược lại) gần nhất.

Mã nguồn Python nguyên mẫu (dsp_utils.py):

import numpy as np



def find_zero_crossing(y: np.ndarray, sr: int, target_time: float, window_seconds: float = 0.04) -> float:

"""

Tìm điểm zero-crossing gần nhất với mốc thời gian đích (giây) để tránh click/pop.


y: Mảng biên độ âm thanh (1D numpy array, Mono)

sr: Tần số lấy mẫu (Sample Rate)

target_time: Vị trí mong muốn cắt (giây)

window_seconds: Cửa sổ quét (mặc định 40ms)

"""

target_sample = int(target_time * sr)

window_samples = int(window_seconds * sr)


# Xác định giới hạn vùng quét an toàn

start_idx = max(0, target_sample - window_samples)

end_idx = min(len(y) - 2, target_sample + window_samples)


# Lấy phân khúc sóng âm trong cửa sổ quét

y_window = y[start_idx:end_idx]


# Tìm các điểm đổi dấu: y[i] * y[i+1] <= 0

# Sử dụng np.sign và np.diff để tìm điểm đổi dấu nhanh chóng

signs = np.sign(y_window)

# Bất kỳ vị trí nào diff != 0 nghĩa là có sự đổi dấu (đi qua điểm 0)

zero_crossings = np.where(np.diff(signs) != 0)[0]


if len(zero_crossings) == 0:

return target_time # Không tìm thấy, trả về vị trí gốc


# Chuyển chỉ số vùng quét về chỉ số mảng tuyệt đối

absolute_crossings = zero_crossings + start_idx


# Tìm điểm gần với target_sample nhất

distances = np.abs(absolute_crossings - target_sample)

closest_sample_idx = absolute_crossings[np.argmin(distances)]


# Trả về thời gian tương ứng (giây)

return float(closest_sample_idx / sr)

2.2. Biên Tập Cắt, Ghép & Tạo Fade (Slicing, Fading & Looping)

Khi thực hiện cắt một phân đoạn từ start_time đến end_time, áp dụng dải chuyển tiếp (Micro-fades) ở hai đầu phân đoạn là bắt buộc để triệt tiêu vĩnh viễn nhiễu biên độ đột ngột.

Mã nguồn Python nguyên mẫu (audio_editor.py):

from pydub import AudioSegment

import os



def cut_and_loop_segment(

file_path: str,

start_sec: float,

end_sec: float,

loop_count: int = 1,

fade_in_ms: int = 50,

fade_out_ms: int = 50,

volume_db_change: float = 0.0

) -> AudioSegment:

"""

Cắt đoạn âm thanh, áp dụng gain, fade-in/out và lặp lại đoạn đó.

pydub sử dụng mili-giây (ms) làm đơn vị chuẩn.

"""

# Tải tệp tin âm thanh gốc

sound = AudioSegment.from_file(file_path)


# Chuyển đổi giây sang mili-giây

start_ms = int(start_sec * 1000)

end_ms = int(end_sec * 1000)


# Trích xuất phân đoạn (Slicing)

clip = sound[start_ms:end_ms]


# Thay đổi âm lượng nếu có yêu cầu

if volume_db_change != 0.0:

clip = clip + volume_db_change


# Áp dụng hiệu ứng mờ đầu và mờ cuối (Fading)

if fade_in_ms > 0:

clip = clip.fade_in(fade_in_ms)

if fade_out_ms > 0:

clip = clip.fade_out(fade_out_ms)


# Tạo chuỗi lặp (Looping)

looped_clip = clip * loop_count


return looped_clip

2.3. Hòa Âm Đa Kênh Thống Nhất (Multitrack Mixdown)

Tương tự như OfflineAudioContext gộp nhiều luồng âm thanh ở Frontend, máy chủ Python sẽ duyệt qua danh sách các Track hoạt động, điều chỉnh Gain độc lập của từng track, và gộp chúng vào một tệp âm thanh Master duy nhất.

def mix_multitrack_session(tracks_meta: list, output_path: str, sample_rate: int = 44100, bit_depth: int = 16):

"""

tracks_meta: Danh sách cấu hình của từng track:

[{"file_path": "...", "volume": 0.8, "muted": False}, ...]

"""

master_mix = None


for track in tracks_meta:

if track.get("muted", False):

continue


# Đọc tệp âm thanh của track

sound = AudioSegment.from_file(track["file_path"])


# Áp dụng Gain (chuyển đổi từ tỷ lệ 0.0 -> 1.0 sang decibels dB)

gain_raw = track.get("volume", 1.0)

if gain_raw <= 0.001:

continue # Xem như tắt tiếng hoàn toàn

gain_db = 20 * np.log10(gain_raw)

sound = sound + gain_db


# Gộp vào Master Mix

if master_mix is None:

master_mix = sound

else:

# overlay tự động đồng bộ thời điểm bắt đầu tại mốc 0ms

master_mix = master_mix.overlay(sound, position=0)


if master_mix is not None:

# Xuất tệp tin WAV chất lượng cao thông qua Soundfile

# Chuyển đổi định dạng xuất bản theo yêu cầu

temp_wav = "temp_mix.wav"

master_mix.export(temp_wav, format="wav")


import soundfile as sf

y, sr = sf.read(temp_wav)


# Xác định subtype mã hóa bit-depth

subtype_map = {8: "PCM_S8", 16: "PCM_16", 24: "PCM_24"}

selected_subtype = subtype_map.get(bit_depth, "PCM_16")


# Ghi tệp nén/không nén hoàn chỉnh

sf.write(output_path, y, sample_rate, subtype=selected_subtype)


# Dọn dẹp tệp tạm

if os.path.exists(temp_wav):

os.remove(temp_wav)

3. Thiết Kế Luồng Dữ Liệu & Giao Tiếp API (FastAPI)

Khi người dùng thao tác trên giao diện SonicForge Studio và thực hiện một lệnh xử lý (như Cắt, Phân tích AI, Xuất bản), Frontend sẽ gửi cấu hình JSON lên FastAPI Gateway.

3.1. Thiết kế JSON Payload gửi từ Client lên Server

{

"session_id": "session_pro_2026_07_18",

"export_settings": {

"sample_rate": 44100,

"bit_depth": 24,

"format": "wav"

},

"tracks": [

{

"track_id": "1",

"file_id": "source_audio_drum_loop.wav",

"volume": 0.85,

"muted": false,

"clips": [

{

"clip_id": "clip_01",

"start_time_seconds": 2.450,

"end_time_seconds": 12.800,

"loop_count": 4,

"apply_zero_crossing": true,

"fade_in_ms": 150,

"fade_out_ms": 150

}

]

}

]

}

4. Kế Hoạch Triển Khai Phát Triển (5-Week Porting Roadmap)

Để quá trình tích hợp mã nguồn diễn ra liền mạch không phát sinh lỗi lệch pha âm thanh (Phase cancellation) hoặc lệch nhịp, lộ trình 5 tuần được phân chia cụ thể như sau:

[ TUẦN 1 ] ──► Thiết lập môi trường Docker, cài đặt FFmpeg & Cấu trúc FastAPI Gateway.

[ TUẦN 2 ] ──► Chuyển giao thuật toán Zero-Crossing & vẽ Peak Waveform đồng bộ sang Python.

[ TUẦN 3 ] ──► Viết bộ xử lý biên dịch đa kênh (Multitrack Overlay Engine) trên Celery Worker.

[ TUẦN 4 ] ──► Tích hợp OpenAI Compatible API kết nối DeepSeek/Ollama để phân tích cấu trúc khuôn nhạc.

[ TUẦN 5 ] ──► Kiểm định chất lượng âm thanh (Phát hiện Pop/Click, lệch pha) & Đóng gói hoàn tất.

Chi tiết các bước thực thi:

Tuần 1: Khởi tạo Hạ tầng Docker & API Gateway

Cài đặt Docker image tích hợp python:3.11-slim, biên dịch bổ sung gói phần mềm ffmpeg và libsndfile1.

Xây dựng các Endpoint cơ bản phục vụ tải lên (/upload) và tải xuống (/download) tệp tin âm nhạc.

Tuần 2: Porting & Kiểm nghiệm Thuật toán Zero-Crossing

Viết kịch bản kiểm thử (Unit tests) so sánh vị trí Zero-Crossing tìm được bằng JavaScript (trên Client) và bằng Numpy (trên Server).

Đảm bảo sai số định vị mẫu âm học giữa hai môi trường tiến về mức $0$ (tuyệt đối đồng bộ).

Tuần 3: Biên tập và Hòa âm Đa kênh

Triển khai bộ xử lý hàng đợi Celery kết nối Redis để thực thi các tác vụ xử lý âm thanh nặng dưới nền.

Đảm bảo tính năng tăng giảm âm lượng tuyến tính và logarit không xảy ra hiện tượng méo tiếng (Clipping distortion).

Tuần 4: Phân tích Âm học và Tích hợp Trí tuệ Nhân tạo (AI)

Gọi API OpenAI tương thích để phân tích, phân đoạn bố cục cấu trúc tệp nhạc (vào các phân khúc Intro, Verse, Chorus, Outro) dựa trên siêu dữ liệu (metadata) và sóng âm.

Sử dụng librosa.beat.beat_track để tự động xác định nhịp độ (Tempo - BPM) và vị trí phách của khuôn nhạc (bars).

Tuần 5: Kiểm định Chất lượng & Triển khai Hệ thống

Kiểm tra hiệu năng khi có nhiều người dùng đồng thời tải lên và thao tác cắt ghép trên dòng thời gian.

Tối ưu hóa dung lượng bộ nhớ tạm (Temporary storage) trong Docker, tự động dọn dẹp các tệp kết xuất hết hạn sau 24 giờ.

Python
import os

markdown_content = """# Kế Hoạch & Tài Liệu Kỹ Thuật: Porting DSP Engine Từ Frontend (JS) Sang Python (Docker)

Tài liệu này đóng vai trò là cẩm nang kỹ thuật hướng dẫn chi tiết cách dịch chuyển (port) các thuật toán tương tác âm thanh, bộ xử lý tín hiệu số (DSP) và cấu trúc quản lý từ mã nguồn Frontend (Web Audio API) sang hệ thống xử lý tập trung phía Server bằng Python, chạy trong container Docker.

---

## 1. Bản Đồ Ánh Xạ Công Nghệ (Technology Mapping)

Để đảm bảo hiệu năng xử lý tệp tin âm thanh lớn và triệt tiêu sai số thời gian thực, các tác vụ tính toán tương đương trên trình duyệt sẽ được ánh xạ sang các thư viện Python chuyên dụng như sau:

| Chức năng ở Frontend (JS) | Cơ chế hoạt động của Web Audio | Thư viện & Module Python thay thế |
| :--- | :--- | :--- |
| **Giải mã âm thanh** | `AudioContext.decodeAudioData()` | `librosa.load()` hoặc `soundfile.read()` |
| **Tìm Zero-Crossing** | Duyệt mảng `Float32Array` thủ công | Phép toán mảng `numpy.diff()` & `numpy.sign()` |
| **Cắt & Tạo Loop** | `AudioBuffer.slice()` & `AudioBufferSourceNode.loop` | `pydub.AudioSegment` hoặc Slicing trên `numpy.ndarray` |
| **Fade-in / Fade-out** | `GainNode.gain.linearRampToValueAtTime()` | `pydub.fade()` hoặc Nhân mảng với `numpy.linspace()` |
| **Thay đổi Volume (Gain)** | `GainNode.gain.value` | Phép nhân số thực trên mảng `numpy` hoặc `pydub` + dB |
| **Trộn âm đa kênh** | `OfflineAudioContext` (Mixdown) | `pydub.AudioSegment.overlay()` hoặc Phép cộng mảng `Numpy` |
| **Xuất tệp WAV/MP3/OGG** | Ghi dữ liệu nhị phân RIFF thủ công | `soundfile.write()` (WAV) và `pydub`/`FFmpeg` (MP3, OGG) |

---

## 2. Porting Thuật Toán DSP Cốt Lõi (Core DSP Algorithms)

### 2.1. Tìm kiếm điểm Zero-Crossing (Triệt tiêu tiếng Click/Pop)

Trong JavaScript, ta quét một cửa sổ $\pm 40\text{ms}$ quanh vị trí đích. Trong Python, ta tối ưu hóa tốc độ quét bằng các phép toán vectơ hóa trên Numpy để tìm ra chỉ số mảng có biên độ đổi dấu từ dương sang âm (hoặc ngược lại) gần nhất.

**Mã nguồn Python nguyên mẫu (`dsp_utils.py`):**

```python
import numpy as np

def find_zero_crossing(y: np.ndarray, sr: int, target_time: float, window_seconds: float = 0.04) -> float:
    \"\"\"
    Tìm điểm zero-crossing gần nhất với mốc thời gian đích (giây) để tránh click/pop.
    
    y: Mảng biên độ âm thanh (1D numpy array, Mono)
    sr: Tần số lấy mẫu (Sample Rate)
    target_time: Vị trí mong muốn cắt (giây)
    window_seconds: Cửa sổ quét (mặc định 40ms)
    \"\"\"
    target_sample = int(target_time * sr)
    window_samples = int(window_seconds * sr)
    
    # Xác định giới hạn vùng quét an toàn
    start_idx = max(0, target_sample - window_samples)
    end_idx = min(len(y) - 2, target_sample + window_samples)
    
    # Lấy phân khúc sóng âm trong cửa sổ quét
    y_window = y[start_idx:end_idx]
    
    # Tìm các điểm đổi dấu: y[i] * y[i+1] <= 0
    # Sử dụng np.sign và np.diff để tìm điểm đổi dấu nhanh chóng
    signs = np.sign(y_window)
    # Bất kỳ vị trí nào diff != 0 nghĩa là có sự đổi dấu (đi qua điểm 0)
    zero_crossings = np.where(np.diff(signs) != 0)[0]
    
    if len(zero_crossings) == 0:
        return target_time  # Không tìm thấy, trả về vị trí gốc
        
    # Chuyển chỉ số vùng quét về chỉ số mảng tuyệt đối
    absolute_crossings = zero_crossings + start_idx
    
    # Tìm điểm gần với target_sample nhất
    distances = np.abs(absolute_crossings - target_sample)
    closest_sample_idx = absolute_crossings[np.argmin(distances)]
    
    # Trả về thời gian tương ứng (giây)
    return float(closest_sample_idx / sr)
2.2. Biên Tập Cắt, Ghép & Tạo Fade (Slicing, Fading & Looping)
Khi thực hiện cắt một phân đoạn từ start_time đến end_time, áp dụng dải chuyển tiếp (Micro-fades) ở hai đầu phân đoạn là bắt buộc để triệt tiêu vĩnh viễn nhiễu biên độ đột ngột.

Mã nguồn Python nguyên mẫu (audio_editor.py):

Python
from pydub import AudioSegment
import os

def cut_and_loop_segment(
    file_path: str, 
    start_sec: float, 
    end_sec: float, 
    loop_count: int = 1,
    fade_in_ms: int = 50, 
    fade_out_ms: int = 50,
    volume_db_change: float = 0.0
) -> AudioSegment:
    \"\"\"
    Cắt đoạn âm thanh, áp dụng gain, fade-in/out và lặp lại đoạn đó.
    pydub sử dụng mili-giây (ms) làm đơn vị chuẩn.
    \"\"\"
    # Tải tệp tin âm thanh gốc
    sound = AudioSegment.from_file(file_path)
    
    # Chuyển đổi giây sang mili-giây
    start_ms = int(start_sec * 1000)
    end_ms = int(end_sec * 1000)
    
    # Trích xuất phân đoạn (Slicing)
    clip = sound[start_ms:end_ms]
    
    # Thay đổi âm lượng nếu có yêu cầu
    if volume_db_change != 0.0:
        clip = clip + volume_db_change
        
    # Áp dụng hiệu ứng mờ đầu và mờ cuối (Fading)
    if fade_in_ms > 0:
        clip = clip.fade_in(fade_in_ms)
    if fade_out_ms > 0:
        clip = clip.fade_out(fade_out_ms)
        
    # Tạo chuỗi lặp (Looping)
    looped_clip = clip * loop_count
    
    return looped_clip
2.3. Hòa Âm Đa Kênh Thống Nhất (Multitrack Mixdown)
Tương tự như OfflineAudioContext gộp nhiều luồng âm thanh ở Frontend, máy chủ Python sẽ duyệt qua danh sách các Track hoạt động, điều chỉnh Gain độc lập của từng track, và gộp chúng vào một tệp âm thanh Master duy nhất.

Python
def mix_multitrack_session(tracks_meta: list, output_path: str, sample_rate: int = 44100, bit_depth: int = 16):
    \"\"\"
    tracks_meta: Danh sách cấu hình của từng track:
                 [{"file_path": "...", "volume": 0.8, "muted": False}, ...]
    \"\"\"
    master_mix = None
    
    for track in tracks_meta:
        if track.get("muted", False):
            continue
            
        # Đọc tệp âm thanh của track
        sound = AudioSegment.from_file(track["file_path"])
        
        # Áp dụng Gain (chuyển đổi từ tỷ lệ 0.0 -> 1.0 sang decibels dB)
        gain_raw = track.get("volume", 1.0)
        if gain_raw <= 0.001:
            continue  # Xem như tắt tiếng hoàn toàn
        gain_db = 20 * np.log10(gain_raw)
        sound = sound + gain_db
        
        # Gộp vào Master Mix
        if master_mix is None:
            master_mix = sound
        else:
            # overlay tự động đồng bộ thời điểm bắt đầu tại mốc 0ms
            master_mix = master_mix.overlay(sound, position=0)
            
    if master_mix is not None:
        # Xuất tệp tin WAV chất lượng cao thông qua Soundfile
        # Chuyển đổi định dạng xuất bản theo yêu cầu
        temp_wav = "temp_mix.wav"
        master_mix.export(temp_wav, format="wav")
        
        import soundfile as sf
        y, sr = sf.read(temp_wav)
        
        # Xác định subtype mã hóa bit-depth
        subtype_map = {8: "PCM_S8", 16: "PCM_16", 24: "PCM_24"}
        selected_subtype = subtype_map.get(bit_depth, "PCM_16")
        
        # Ghi tệp nén/không nén hoàn chỉnh
        sf.write(output_path, y, sample_rate, subtype=selected_subtype)
        
        # Dọn dẹp tệp tạm
        if os.path.exists(temp_wav):
            os.remove(temp_wav)
3. Thiết Kế Luồng Dữ Liệu & Giao Tiếp API (FastAPI)
Khi người dùng thao tác trên giao diện SonicForge Studio và thực hiện một lệnh xử lý (như Cắt, Phân tích AI, Xuất bản), Frontend sẽ gửi cấu hình JSON lên FastAPI Gateway.

3.1. Thiết kế JSON Payload gửi từ Client lên Server
JSON
{
  "session_id": "session_pro_2026_07_18",
  "export_settings": {
    "sample_rate": 44100,
    "bit_depth": 24,
    "format": "wav"
  },
  "tracks": [
    {
      "track_id": "1",
      "file_id": "source_audio_drum_loop.wav",
      "volume": 0.85,
      "muted": false,
      "clips": [
        {
          "clip_id": "clip_01",
          "start_time_seconds": 2.450,
          "end_time_seconds": 12.800,
          "loop_count": 4,
          "apply_zero_crossing": true,
          "fade_in_ms": 150,
          "fade_out_ms": 150
        }
      ]
    }
  ]
}
4. Kế Hoạch Triển Khai Phát Triển (5-Week Porting Roadmap)
Để quá trình tích hợp mã nguồn diễn ra liền mạch không phát sinh lỗi lệch pha âm thanh (Phase cancellation) hoặc lệch nhịp, lộ trình 5 tuần được phân chia cụ thể như sau:

Plaintext
[ TUẦN 1 ] ──► Thiết lập môi trường Docker, cài đặt FFmpeg & Cấu trúc FastAPI Gateway.
[ TUẦN 2 ] ──► Chuyển giao thuật toán Zero-Crossing & vẽ Peak Waveform đồng bộ sang Python.
[ TUẦN 3 ] ──► Viết bộ xử lý biên dịch đa kênh (Multitrack Overlay Engine) trên Celery Worker.
[ TUẦN 4 ] ──► Tích hợp OpenAI Compatible API kết nối DeepSeek/Ollama để phân tích cấu trúc khuôn nhạc.
[ TUẦN 5 ] ──► Kiểm định chất lượng âm thanh (Phát hiện Pop/Click, lệch pha) & Đóng gói hoàn tất.
Chi tiết các bước thực thi:
Tuần 1: Khởi tạo Hạ tầng Docker & API Gateway
Cài đặt Docker image tích hợp python:3.11-slim, biên dịch bổ sung gói phần mềm ffmpeg và libsndfile1.

Xây dựng các Endpoint cơ bản phục vụ tải lên (/upload) và tải xuống (/download) tệp tin âm nhạc.

Tuần 2: Porting & Kiểm nghiệm Thuật toán Zero-Crossing
Viết kịch bản kiểm thử (Unit tests) so sánh vị trí Zero-Crossing tìm được bằng JavaScript (trên Client) và bằng Numpy (trên Server).

Đảm bảo sai số định vị mẫu âm học giữa hai môi trường tiến về mức 0 (tuyệt đối đồng bộ).

Tuần 3: Biên tập và Hòa âm Đa kênh
Triển khai bộ xử lý hàng đợi Celery kết nối Redis để thực thi các tác vụ xử lý âm thanh nặng dưới nền.

Đảm bảo tính năng tăng giảm âm lượng tuyến tính và logarit không xảy ra hiện tượng méo tiếng (Clipping distortion).

Tuần 4: Phân tích Âm học và Tích hợp Trí tuệ Nhân tạo (AI)
Gọi API OpenAI tương thích để phân tích, phân đoạn bố cục cấu trúc tệp nhạc (vào các phân khúc Intro, Verse, Chorus, Outro) dựa trên siêu dữ liệu (metadata) và sóng âm.

Sử dụng librosa.beat.beat_track để tự động xác định nhịp độ (Tempo - BPM) và vị trí phách của khuôn nhạc (bars).

Tuần 5: Kiểm định Chất lượng & Triển khai Hệ thống
Kiểm tra hiệu năng khi có nhiều người dùng đồng thời tải lên và thao tác cắt ghép trên dòng thời gian.

Tối ưu hóa dung lượng bộ nhớ tạm (Temporary storage) trong Docker, tự động dọn dẹp các tệp kết xuất hết hạn sau 24 giờ.
"""

with open("Porting_DSP_Engine_Plan.md", "w", encoding="utf-8") as f:
f.write(markdown_content)
print("File written successfully.")


```text?code_stdout&code_event_index=1
File written successfully.

Your Markdown file is ready
Biểu tượng MD
Porting_DSP_Engine_Plan
 MD 
Đang mở

Dưới đây là toàn bộ nội dung đã được chuyển đổi sang định dạng Markdown chuẩn, căn chỉnh bảng biểu, tối ưu hóa code block syntax highlighting (python, json, text), cũng như giữ nguyên các công thức dạng toán học LaTeX:

Kế Hoạch & Tài Liệu Kỹ Thuật: Porting DSP Engine Từ Frontend (JS) Sang Python (Docker)
Tài liệu này đóng vai trò là cẩm nang kỹ thuật hướng dẫn chi tiết cách dịch chuyển (port) các thuật toán tương tác âm thanh, bộ xử lý tín hiệu số (DSP) và cấu trúc quản lý từ mã nguồn Frontend (Web Audio API) sang hệ thống xử lý tập trung phía Server bằng Python, chạy trong container Docker.

1. Bản Đồ Ánh Xạ Công Nghệ (Technology Mapping)
Để đảm bảo hiệu năng xử lý tệp tin âm thanh lớn và triệt tiêu sai số thời gian thực, các tác vụ tính toán tương đương trên trình duyệt sẽ được ánh xạ sang các thư viện Python chuyên dụng như sau:

Chức năng ở Frontend (JS)	Cơ chế hoạt động của Web Audio	Thư viện & Module Python thay thế
Giải mã âm thanh	AudioContext.decodeAudioData()	librosa.load() hoặc soundfile.read()
Tìm Zero-Crossing	Duyệt mảng Float32Array thủ công	Phép toán mảng numpy.diff() & numpy.sign()
Cắt & Tạo Loop	AudioBuffer.slice() & AudioBufferSourceNode.loop	pydub.AudioSegment hoặc Slicing trên numpy.ndarray
Fade-in / Fade-out	GainNode.gain.linearRampToValueAtTime()	pydub.fade() hoặc Nhân mảng với numpy.linspace()
Thay đổi Volume (Gain)	GainNode.gain.value	Phép nhân số thực trên mảng numpy hoặc pydub + dB
Trộn âm đa kênh	OfflineAudioContext (Mixdown)	pydub.AudioSegment.overlay() hoặc Phép cộng mảng Numpy
Xuất tệp WAV/MP3/OGG	Ghi dữ liệu nhị phân RIFF thủ công	soundfile.write() (WAV) và pydub/FFmpeg (MP3, OGG)
2. Porting Thuật Toán DSP Cốt Lõi (Core DSP Algorithms)
2.1. Tìm kiếm điểm Zero-Crossing (Triệt tiêu tiếng Click/Pop)
Trong JavaScript, ta quét một cửa sổ ±40ms quanh vị trí đích. Trong Python, ta tối ưu hóa tốc độ quét bằng các phép toán vectơ hóa trên Numpy để tìm ra chỉ số mảng có biên độ đổi dấu từ dương sang âm (hoặc ngược lại) gần nhất.

Mã nguồn Python nguyên mẫu (dsp_utils.py):

Python
import numpy as np

def find_zero_crossing(y: np.ndarray, sr: int, target_time: float, window_seconds: float = 0.04) -> float:
    """
    Tìm điểm zero-crossing gần nhất với mốc thời gian đích (giây) để tránh click/pop.
    
    y: Mảng biên độ âm thanh (1D numpy array, Mono)
    sr: Tần số lấy mẫu (Sample Rate)
    target_time: Vị trí mong muốn cắt (giây)
    window_seconds: Cửa sổ quét (mặc định 40ms)
    """
    target_sample = int(target_time * sr)
    window_samples = int(window_seconds * sr)
    
    # Xác định giới hạn vùng quét an toàn
    start_idx = max(0, target_sample - window_samples)
    end_idx = min(len(y) - 2, target_sample + window_samples)
    
    # Lấy phân khúc sóng âm trong cửa sổ quét
    y_window = y[start_idx:end_idx]
    
    # Tìm các điểm đổi dấu: y[i] * y[i+1] <= 0
    # Sử dụng np.sign và np.diff để tìm điểm đổi dấu nhanh chóng
    signs = np.sign(y_window)
    # Bất kỳ vị trí nào diff != 0 nghĩa là có sự đổi dấu (đi qua điểm 0)
    zero_crossings = np.where(np.diff(signs) != 0)[0]
    
    if len(zero_crossings) == 0:
        return target_time  # Không tìm thấy, trả về vị trí gốc
        
    # Chuyển chỉ số vùng quét về chỉ số mảng tuyệt đối
    absolute_crossings = zero_crossings + start_idx
    
    # Tìm điểm gần với target_sample nhất
    distances = np.abs(absolute_crossings - target_sample)
    closest_sample_idx = absolute_crossings[np.argmin(distances)]
    
    # Trả về thời gian tương ứng (giây)
    return float(closest_sample_idx / sr)
2.2. Biên Tập Cắt, Ghép & Tạo Fade (Slicing, Fading & Looping)
Khi thực hiện cắt một phân đoạn từ start_time đến end_time, áp dụng dải chuyển tiếp (Micro-fades) ở hai đầu phân đoạn là bắt buộc để triệt tiêu vĩnh viễn nhiễu biên độ đột ngột.

Mã nguồn Python nguyên mẫu (audio_editor.py):

Python
from pydub import AudioSegment
import os

def cut_and_loop_segment(
    file_path: str, 
    start_sec: float, 
    end_sec: float, 
    loop_count: int = 1,
    fade_in_ms: int = 50, 
    fade_out_ms: int = 50,
    volume_db_change: float = 0.0
) -> AudioSegment:
    """
    Cắt đoạn âm thanh, áp dụng gain, fade-in/out và lặp lại đoạn đó.
    pydub sử dụng mili-giây (ms) làm đơn vị chuẩn.
    """
    # Tải tệp tin âm thanh gốc
    sound = AudioSegment.from_file(file_path)
    
    # Chuyển đổi giây sang mili-giây
    start_ms = int(start_sec * 1000)
    end_ms = int(end_sec * 1000)
    
    # Trích xuất phân đoạn (Slicing)
    clip = sound[start_ms:end_ms]
    
    # Thay đổi âm lượng nếu có yêu cầu
    if volume_db_change != 0.0:
        clip = clip + volume_db_change
        
    # Áp dụng hiệu ứng mờ đầu và mờ cuối (Fading)
    if fade_in_ms > 0:
        clip = clip.fade_in(fade_in_ms)
    if fade_out_ms > 0:
        clip = clip.fade_out(fade_out_ms)
        
    # Tạo chuỗi lặp (Looping)
    looped_clip = clip * loop_count
    
    return looped_clip
2.3. Hòa Âm Đa Kênh Thống Nhất (Multitrack Mixdown)
Tương tự như OfflineAudioContext gộp nhiều luồng âm thanh ở Frontend, máy chủ Python sẽ duyệt qua danh sách các Track hoạt động, điều chỉnh Gain độc lập của từng track, và gộp chúng vào một tệp âm thanh Master duy nhất.

Python
def mix_multitrack_session(tracks_meta: list, output_path: str, sample_rate: int = 44100, bit_depth: int = 16):
    """
    tracks_meta: Danh sách cấu hình của từng track:
                 [{"file_path": "...", "volume": 0.8, "muted": False}, ...]
    """
    master_mix = None
    
    for track in tracks_meta:
        if track.get("muted", False):
            continue
            
        # Đọc tệp âm thanh của track
        sound = AudioSegment.from_file(track["file_path"])
        
        # Áp dụng Gain (chuyển đổi từ tỷ lệ 0.0 -> 1.0 sang decibels dB)
        gain_raw = track.get("volume", 1.0)
        if gain_raw <= 0.001:
            continue  # Xem như tắt tiếng hoàn toàn
        gain_db = 20 * np.log10(gain_raw)
        sound = sound + gain_db
        
        # Gộp vào Master Mix
        if master_mix is None:
            master_mix = sound
        else:
            # overlay tự động đồng bộ thời điểm bắt đầu tại mốc 0ms
            master_mix = master_mix.overlay(sound, position=0)
            
    if master_mix is not None:
        # Xuất tệp tin WAV chất lượng cao thông qua Soundfile
        # Chuyển đổi định dạng xuất bản theo yêu cầu
        temp_wav = "temp_mix.wav"
        master_mix.export(temp_wav, format="wav")
        
        import soundfile as sf
        y, sr = sf.read(temp_wav)
        
        # Xác định subtype mã hóa bit-depth
        subtype_map = {8: "PCM_S8", 16: "PCM_16", 24: "PCM_24"}
        selected_subtype = subtype_map.get(bit_depth, "PCM_16")
        
        # Ghi tệp nén/không nén hoàn chỉnh
        sf.write(output_path, y, sample_rate, subtype=selected_subtype)
        
        # Dọn dẹp tệp tạm
        if os.path.exists(temp_wav):
            os.remove(temp_wav)
3. Thiết Kế Luồng Dữ Liệu & Giao Tiếp API (FastAPI)
Khi người dùng thao tác trên giao diện SonicForge Studio và thực hiện một lệnh xử lý (như Cắt, Phân tích AI, Xuất bản), Frontend sẽ gửi cấu hình JSON lên FastAPI Gateway.

3.1. Thiết kế JSON Payload gửi từ Client lên Server
JSON
{
  "session_id": "session_pro_2026_07_18",
  "export_settings": {
    "sample_rate": 44100,
    "bit_depth": 24,
    "format": "wav"
  },
  "tracks": [
    {
      "track_id": "1",
      "file_id": "source_audio_drum_loop.wav",
      "volume": 0.85,
      "muted": false,
      "clips": [
        {
          "clip_id": "clip_01",
          "start_time_seconds": 2.450,
          "end_time_seconds": 12.800,
          "loop_count": 4,
          "apply_zero_crossing": true,
          "fade_in_ms": 150,
          "fade_out_ms": 150
        }
      ]
    }
  ]
}
4. Kế Hoạch Triển Khai Phát Triển (5-Week Porting Roadmap)
Để quá trình tích hợp mã nguồn diễn ra liền mạch không phát sinh lỗi lệch pha âm thanh (Phase cancellation) hoặc lệch nhịp, lộ trình 5 tuần được phân chia cụ thể như sau:

Plaintext
[ TUẦN 1 ] ──► Thiết lập môi trường Docker, cài đặt FFmpeg & Cấu trúc FastAPI Gateway.
[ TUẦN 2 ] ──► Chuyển giao thuật toán Zero-Crossing & vẽ Peak Waveform đồng bộ sang Python.
[ TUẦN 3 ] ──► Viết bộ xử lý biên dịch đa kênh (Multitrack Overlay Engine) trên Celery Worker.
[ TUẦN 4 ] ──► Tích hợp OpenAI Compatible API kết nối DeepSeek/Ollama để phân tích cấu trúc khuôn nhạc.
[ TUẦN 5 ] ──► Kiểm định chất lượng âm thanh (Phát hiện Pop/Click, lệch pha) & Đóng gói hoàn tất.
Chi tiết các bước thực thi:
Tuần 1: Khởi tạo Hạ tầng Docker & API Gateway
Cài đặt Docker image tích hợp python:3.11-slim, biên dịch bổ sung gói phần mềm ffmpeg và libsndfile1.

Xây dựng các Endpoint cơ bản phục vụ tải lên (/upload) và tải xuống (/download) tệp tin âm nhạc.

Tuần 2: Porting & Kiểm nghiệm Thuật toán Zero-Crossing
Viết kịch bản kiểm thử (Unit tests) so sánh vị trí Zero-Crossing tìm được bằng JavaScript (trên Client) và bằng Numpy (trên Server).

Đảm bảo sai số định vị mẫu âm học giữa hai môi trường tiến về mức 0 (tuyệt đối đồng bộ).

Tuần 3: Biên tập và Hòa âm Đa kênh
Triển khai bộ xử lý hàng đợi Celery kết nối Redis để thực thi các tác vụ xử lý âm thanh nặng dưới nền.

Đảm bảo tính năng tăng giảm âm lượng tuyến tính và logarit không xảy ra hiện tượng méo tiếng (Clipping distortion).

Tuần 4: Phân tích Âm học và Tích hợp Trí tuệ Nhân tạo (AI)
Gọi API OpenAI tương thích để phân tích, phân đoạn bố cục cấu trúc tệp nhạc (vào các phân khúc Intro, Verse, Chorus, Outro) dựa trên siêu dữ liệu (metadata) và sóng âm.

Sử dụng librosa.beat.beat_track để tự động xác định nhịp độ (Tempo - BPM) và vị trí phách của khuôn nhạc (bars).

Tuần 5: Kiểm định Chất lượng & Triển khai Hệ thống
Kiểm tra hiệu năng khi có nhiều người dùng đồng thời tải lên và thao tác cắt ghép trên dòng thời gian.

Tối ưu hóa dung lượng bộ nhớ tạm (Temporary storage) trong Docker, tự động dọn dẹp các tệp kết xuất hết hạn sau 24 giờ.




Gemini là AI và có thể mắc sai sót.

# Kế Hoạch & Tài Liệu Kỹ Thuật: Porting DSP Engine Từ Frontend (JS) Sang Python (Docker)

Tài liệu này đóng vai trò là cẩm nang kỹ thuật hướng dẫn chi tiết cách dịch chuyển (port) các thuật toán tương tác âm thanh, bộ xử lý tín hiệu số (DSP) và cấu trúc quản lý từ mã nguồn Frontend (Web Audio API) sang hệ thống xử lý tập trung phía Server bằng Python, chạy trong container Docker.

---

## 1. Bản Đồ Ánh Xạ Công Nghệ (Technology Mapping)

Để đảm bảo hiệu năng xử lý tệp tin âm thanh lớn và triệt tiêu sai số thời gian thực, các tác vụ tính toán tương đương trên trình duyệt sẽ được ánh xạ sang các thư viện Python chuyên dụng như sau:

| Chức năng ở Frontend (JS) | Cơ chế hoạt động của Web Audio | Thư viện & Module Python thay thế |
| :--- | :--- | :--- |
| **Giải mã âm thanh** | `AudioContext.decodeAudioData()` | `librosa.load()` hoặc `soundfile.read()` |
| **Tìm Zero-Crossing** | Duyệt mảng `Float32Array` thủ công | Phép toán mảng `numpy.diff()` & `numpy.sign()` |
| **Cắt & Tạo Loop** | `AudioBuffer.slice()` & `AudioBufferSourceNode.loop` | `pydub.AudioSegment` hoặc Slicing trên `numpy.ndarray` |
| **Fade-in / Fade-out** | `GainNode.gain.linearRampToValueAtTime()` | `pydub.fade()` hoặc Nhân mảng với `numpy.linspace()` |
| **Thay đổi Volume (Gain)** | `GainNode.gain.value` | Phép nhân số thực trên mảng `numpy` hoặc `pydub` + dB |
| **Trộn âm đa kênh** | `OfflineAudioContext` (Mixdown) | `pydub.AudioSegment.overlay()` hoặc Phép cộng mảng `Numpy` |
| **Xuất tệp WAV/MP3/OGG** | Ghi dữ liệu nhị phân RIFF thủ công | `soundfile.write()` (WAV) và `pydub`/`FFmpeg` (MP3, OGG) |

---

## 2. Porting Thuật Toán DSP Cốt Lõi (Core DSP Algorithms)

### 2.1. Tìm kiếm điểm Zero-Crossing (Triệt tiêu tiếng Click/Pop)

Trong JavaScript, ta quét một cửa sổ $\pm 40	ext{ms}$ quanh vị trí đích. Trong Python, ta tối ưu hóa tốc độ quét bằng các phép toán vectơ hóa trên Numpy để tìm ra chỉ số mảng có biên độ đổi dấu từ dương sang âm (hoặc ngược lại) gần nhất.

**Mã nguồn Python nguyên mẫu (`dsp_utils.py`):**

```python
import numpy as np

def find_zero_crossing(y: np.ndarray, sr: int, target_time: float, window_seconds: float = 0.04) -> float:
    """
    Tìm điểm zero-crossing gần nhất với mốc thời gian đích (giây) để tránh click/pop.
    
    y: Mảng biên độ âm thanh (1D numpy array, Mono)
    sr: Tần số lấy mẫu (Sample Rate)
    target_time: Vị trí mong muốn cắt (giây)
    window_seconds: Cửa sổ quét (mặc định 40ms)
    """
    target_sample = int(target_time * sr)
    window_samples = int(window_seconds * sr)
    
    # Xác định giới hạn vùng quét an toàn
    start_idx = max(0, target_sample - window_samples)
    end_idx = min(len(y) - 2, target_sample + window_samples)
    
    # Lấy phân khúc sóng âm trong cửa sổ quét
    y_window = y[start_idx:end_idx]
    
    # Tìm các điểm đổi dấu: y[i] * y[i+1] <= 0
    # Sử dụng np.sign và np.diff để tìm điểm đổi dấu nhanh chóng
    signs = np.sign(y_window)
    # Bất kỳ vị trí nào diff != 0 nghĩa là có sự đổi dấu (đi qua điểm 0)
    zero_crossings = np.where(np.diff(signs) != 0)[0]
    
    if len(zero_crossings) == 0:
        return target_time  # Không tìm thấy, trả về vị trí gốc
        
    # Chuyển chỉ số vùng quét về chỉ số mảng tuyệt đối
    absolute_crossings = zero_crossings + start_idx
    
    # Tìm điểm gần với target_sample nhất
    distances = np.abs(absolute_crossings - target_sample)
    closest_sample_idx = absolute_crossings[np.argmin(distances)]
    
    # Trả về thời gian tương ứng (giây)
    return float(closest_sample_idx / sr)
```

### 2.2. Biên Tập Cắt, Ghép & Tạo Fade (Slicing, Fading & Looping)

Khi thực hiện cắt một phân đoạn từ `start_time` đến `end_time`, áp dụng dải chuyển tiếp (Micro-fades) ở hai đầu phân đoạn là bắt buộc để triệt tiêu vĩnh viễn nhiễu biên độ đột ngột.

**Mã nguồn Python nguyên mẫu (`audio_editor.py`):**

```python
from pydub import AudioSegment
import os

def cut_and_loop_segment(
    file_path: str, 
    start_sec: float, 
    end_sec: float, 
    loop_count: int = 1,
    fade_in_ms: int = 50, 
    fade_out_ms: int = 50,
    volume_db_change: float = 0.0
) -> AudioSegment:
    """
    Cắt đoạn âm thanh, áp dụng gain, fade-in/out và lặp lại đoạn đó.
    pydub sử dụng mili-giây (ms) làm đơn vị chuẩn.
    """
    # Tải tệp tin âm thanh gốc
    sound = AudioSegment.from_file(file_path)
    
    # Chuyển đổi giây sang mili-giây
    start_ms = int(start_sec * 1000)
    end_ms = int(end_sec * 1000)
    
    # Trích xuất phân đoạn (Slicing)
    clip = sound[start_ms:end_ms]
    
    # Thay đổi âm lượng nếu có yêu cầu
    if volume_db_change != 0.0:
        clip = clip + volume_db_change
        
    # Áp dụng hiệu ứng mờ đầu và mờ cuối (Fading)
    if fade_in_ms > 0:
        clip = clip.fade_in(fade_in_ms)
    if fade_out_ms > 0:
        clip = clip.fade_out(fade_out_ms)
        
    # Tạo chuỗi lặp (Looping)
    looped_clip = clip * loop_count
    
    return looped_clip
```

### 2.3. Hòa Âm Đa Kênh Thống Nhất (Multitrack Mixdown)

Tương tự như `OfflineAudioContext` gộp nhiều luồng âm thanh ở Frontend, máy chủ Python sẽ duyệt qua danh sách các Track hoạt động, điều chỉnh Gain độc lập của từng track, và gộp chúng vào một tệp âm thanh Master duy nhất.

```python
def mix_multitrack_session(tracks_meta: list, output_path: str, sample_rate: int = 44100, bit_depth: int = 16):
    """
    tracks_meta: Danh sách cấu hình của từng track:
                 [{"file_path": "...", "volume": 0.8, "muted": False}, ...]
    """
    master_mix = None
    
    for track in tracks_meta:
        if track.get("muted", False):
            continue
            
        # Đọc tệp âm thanh của track
        sound = AudioSegment.from_file(track["file_path"])
        
        # Áp dụng Gain (chuyển đổi từ tỷ lệ 0.0 -> 1.0 sang decibels dB)
        gain_raw = track.get("volume", 1.0)
        if gain_raw <= 0.001:
            continue  # Xem như tắt tiếng hoàn toàn
        gain_db = 20 * np.log10(gain_raw)
        sound = sound + gain_db
        
        # Gộp vào Master Mix
        if master_mix is None:
            master_mix = sound
        else:
            # overlay tự động đồng bộ thời điểm bắt đầu tại mốc 0ms
            master_mix = master_mix.overlay(sound, position=0)
            
    if master_mix is not None:
        # Xuất tệp tin WAV chất lượng cao thông qua Soundfile
        # Chuyển đổi định dạng xuất bản theo yêu cầu
        temp_wav = "temp_mix.wav"
        master_mix.export(temp_wav, format="wav")
        
        import soundfile as sf
        y, sr = sf.read(temp_wav)
        
        # Xác định subtype mã hóa bit-depth
        subtype_map = {8: "PCM_S8", 16: "PCM_16", 24: "PCM_24"}
        selected_subtype = subtype_map.get(bit_depth, "PCM_16")
        
        # Ghi tệp nén/không nén hoàn chỉnh
        sf.write(output_path, y, sample_rate, subtype=selected_subtype)
        
        # Dọn dẹp tệp tạm
        if os.path.exists(temp_wav):
            os.remove(temp_wav)
```

---

## 3. Thiết Kế Luồng Dữ Liệu & Giao Tiếp API (FastAPI)

Khi người dùng thao tác trên giao diện *SonicForge Studio* và thực hiện một lệnh xử lý (như Cắt, Phân tích AI, Xuất bản), Frontend sẽ gửi cấu hình JSON lên FastAPI Gateway.

### 3.1. Thiết kế JSON Payload gửi từ Client lên Server

```json
{
  "session_id": "session_pro_2026_07_18",
  "export_settings": {
    "sample_rate": 44100,
    "bit_depth": 24,
    "format": "wav"
  },
  "tracks": [
    {
      "track_id": "1",
      "file_id": "source_audio_drum_loop.wav",
      "volume": 0.85,
      "muted": false,
      "clips": [
        {
          "clip_id": "clip_01",
          "start_time_seconds": 2.450,
          "end_time_seconds": 12.800,
          "loop_count": 4,
          "apply_zero_crossing": true,
          "fade_in_ms": 150,
          "fade_out_ms": 150
        }
      ]
    }
  ]
}
```

---

## 4. Kế Hoạch Triển Khai Phát Triển (5-Week Porting Roadmap)

Để quá trình tích hợp mã nguồn diễn ra liền mạch không phát sinh lỗi lệch pha âm thanh (*Phase cancellation*) hoặc lệch nhịp, lộ trình 5 tuần được phân chia cụ thể như sau:

```text
[ TUẦN 1 ] ──► Thiết lập môi trường Docker, cài đặt FFmpeg & Cấu trúc FastAPI Gateway.
[ TUẦN 2 ] ──► Chuyển giao thuật toán Zero-Crossing & vẽ Peak Waveform đồng bộ sang Python.
[ TUẦN 3 ] ──► Viết bộ xử lý biên dịch đa kênh (Multitrack Overlay Engine) trên Celery Worker.
[ TUẦN 4 ] ──► Tích hợp OpenAI Compatible API kết nối DeepSeek/Ollama để phân tích cấu trúc khuôn nhạc.
[ TUẦN 5 ] ──► Kiểm định chất lượng âm thanh (Phát hiện Pop/Click, lệch pha) & Đóng gói hoàn tất.
```

### Chi tiết các bước thực thi:

#### **Tuần 1: Khởi tạo Hạ tầng Docker & API Gateway**
* Cài đặt Docker image tích hợp `python:3.11-slim`, biên dịch bổ sung gói phần mềm `ffmpeg` và `libsndfile1`.
* Xây dựng các Endpoint cơ bản phục vụ tải lên (`/upload`) và tải xuống (`/download`) tệp tin âm nhạc.

#### **Tuần 2: Porting & Kiểm nghiệm Thuật toán Zero-Crossing**
* Viết kịch bản kiểm thử (Unit tests) so sánh vị trí Zero-Crossing tìm được bằng JavaScript (trên Client) và bằng Numpy (trên Server).
* Đảm bảo sai số định vị mẫu âm học giữa hai môi trường tiến về mức $0$ (tuyệt đối đồng bộ).

#### **Tuần 3: Biên tập và Hòa âm Đa kênh**
* Triển khai bộ xử lý hàng đợi Celery kết nối Redis để thực thi các tác vụ xử lý âm thanh nặng dưới nền.
* Đảm bảo tính năng tăng giảm âm lượng tuyến tính và logarit không xảy ra hiện tượng méo tiếng (*Clipping distortion*).

#### **Tuần 4: Phân tích Âm học và Tích hợp Trí tuệ Nhân tạo (AI)**
* Gọi API OpenAI tương thích để phân tích, phân đoạn bố cục cấu trúc tệp nhạc (vào các phân khúc Intro, Verse, Chorus, Outro) dựa trên siêu dữ liệu (*metadata*) và sóng âm.
* Sử dụng `librosa.beat.beat_track` để tự động xác định nhịp độ (Tempo - BPM) và vị trí phách của khuôn nhạc (*bars*).

#### **Tuần 5: Kiểm định Chất lượng & Triển khai Hệ thống**
* Kiểm tra hiệu năng khi có nhiều người dùng đồng thời tải lên và thao tác cắt ghép trên dòng thời gian.
* Tối ưu hóa dung lượng bộ nhớ tạm (*Temporary storage*) trong Docker, tự động dọn dẹp các tệp kết xuất hết hạn sau 24 giờ.
Porting_DSP_Engine_Plan.md
Đang hiển thị Porting_DSP_Engine_Plan.md.