NhanNguyen1309/audio-separation-api
0
1from __future__ import annotations2 3from dataclasses import dataclass4from datetime import datetime5from pathlib import Path6from typing import Literal7 8 9StemMode = Literal["2-stem", "4-stem"]10JobStatus = Literal["queued", "processing", "completed", "failed", "expired"]11 12 13@dataclass(slots=True)14class JobRecord:15 id: str16 status: JobStatus17 stem_mode: StemMode18 progress: int19 stage: str20 created_at: datetime21 updated_at: datetime22 input_path: Path23 output_dir: Path24 zip_path: Path25 input_duration_sec: float | None = None26 processing_time_sec: float | None = None27 error: str | None = None28 29 30@dataclass(slots=True)31class ChordSegmentRecord:32 start_sec: float33 end_sec: float34 chord: str35 confidence: float | None = None36 37 38@dataclass(slots=True)39class BpmCandidateRecord:40 bpm: float41 score: float42 source: str43 44 45@dataclass(slots=True)46class TimeSignatureRecord:47 numerator: int48 denominator: int49 50 51@dataclass(slots=True)52class VisualGridCellRecord:53 index: int54 visual_bar_index: int55 cell_in_bar: int56 start_sec: float57 end_sec: float58 is_bar_start: bool59 beat_index: int | None = None60 61 62@dataclass(slots=True)63class VisualGridRecord:64 visual_cells_per_bar: int65 cells: list[VisualGridCellRecord]66 67 68@dataclass(slots=True)69class KeyScoreComponentsRecord:70 chroma_score: float71 chord_fit_score: float72 tonic_duration_score: float73 first_last_score: float74 cadence_score: float75 bass_root_score: float76 section_vote_score: float77 78 79@dataclass(slots=True)80class KeyCandidateRecord:81 key: str82 tonic: str83 scale: str84 score: float85 components: KeyScoreComponentsRecord86 87 88@dataclass(slots=True)89class SectionKeyResultRecord:90 start_sec: float91 end_sec: float92 key: str93 scale: str94 confidence: float95 96 97@dataclass(slots=True)98class KeyDetectionResultRecord:99 key: str100 tonic: str101 scale: str102 confidence: float103 method: str104 candidates: list[KeyCandidateRecord]105 section_keys: list[SectionKeyResultRecord] | None = None106 warnings: list[str] | None = None107 108 109@dataclass(slots=True)110class SnapConfigRecord:111 chord_snap_tolerance_sec: float112 downbeat_snap_tolerance_sec: float113 visual_cell_snap_tolerance_sec: float114 downbeat_snap_enabled: bool115 forward_downbeat_tolerance_sec: float = 0.35116 backward_downbeat_tolerance_sec: float = 0.25117 118 119 120@dataclass(slots=True)121class MusicAnalysisRecord:122 bpm: float123 bpm_confidence: float124 raw_bpm_candidates: list[BpmCandidateRecord]125 beats: list[float]126 downbeats: list[float]127 bar_start_offset_sec: float128 time_signature: TimeSignatureRecord129 beats_per_bar: int130 visual_grid: VisualGridRecord131 chords: list[ChordSegmentRecord]132 chord_source: str133 beat_source: str134 warnings: list[str]135 original_key: KeyDetectionResultRecord | None = None136 chord_audio_source: str | None = None137 snap_config: SnapConfigRecord | None = None138 key_analysis_chords: list[ChordSegmentRecord] | None = None139 key_audio_source: str | None = None140 key_detection_source: str | None = None141 142 143@dataclass(slots=True)144class ChordJobRecord:145 id: str146 status: JobStatus147 progress: int148 stage: str149 created_at: datetime150 updated_at: datetime151 input_path: Path152 working_dir: Path153 prepared_path: Path154 duration_sec: float | None = None155 result: list[ChordSegmentRecord] | None = None156 analysis: MusicAnalysisRecord | None = None157 error_code: str | None = None158 error: str | None = None159 