Skip to content

Commit d2069a3

Browse files
committed
Implement audio.cpp source synchronization and build enhancements
- Introduced `_sync_git_checkout` method in `AudioCppManager` for managing source synchronization with Git, including fetching and resetting branches. - Added `_compile_tree` method to streamline the build process for audio.cpp, encapsulating configuration, building, and validation of binaries. - Enhanced API routes to support audio.cpp source synchronization, including task management and progress tracking. - Updated frontend components to reflect new synchronization capabilities and improve user interaction during build processes. - Added tests to validate the synchronization and build functionalities for audio.cpp.
1 parent bf3aa7a commit d2069a3

46 files changed

Lines changed: 5710 additions & 102 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

backend/audio_align_profiles.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
"""Curated forced-alignment family guidance."""
2+
3+
from __future__ import annotations
4+
5+
from typing import Any, Dict, List, Optional
6+
7+
from backend.audio_profile_fields import field_spec
8+
9+
_ALIGN_TASKS = frozenset({"align"})
10+
11+
12+
def is_align_task(task: Optional[str]) -> bool:
13+
return str(task or "").strip().lower() in _ALIGN_TASKS
14+
15+
16+
def align_profile_for_family(family: Optional[str]) -> Optional[Dict[str, Any]]:
17+
key = str(family or "").strip().lower()
18+
return _FAMILY_PROFILES.get(key) if key else None
19+
20+
21+
def alignment_request_field_groups(family: Optional[str]) -> List[Dict[str, Any]]:
22+
profile = align_profile_for_family(family) or {}
23+
groups: List[Dict[str, Any]] = []
24+
for group_id, label, description in _GROUP_META:
25+
keys = profile.get(f"{group_id}_fields") or []
26+
fields = [field_spec(key) for key in keys]
27+
if fields:
28+
groups.append({"id": group_id, "label": label, "description": description, "fields": fields})
29+
return groups
30+
31+
32+
_GROUP_META = [
33+
("audio", "Audio & transcript", "Speech audio and the exact transcript to align."),
34+
("context", "Language", "Transcript language hint."),
35+
("chunking", "Chunking", "Chunking mode for long audio."),
36+
]
37+
38+
_FAMILY_PROFILES: Dict[str, Dict[str, Any]] = {
39+
"qwen3_forced_aligner": {
40+
"label": "Qwen3 Forced Aligner",
41+
"workflows": ["offline"],
42+
"summary": "Map an exact transcript onto speech audio to produce word timestamps.",
43+
"audio_fields": ["audio", "transcript"],
44+
"context_fields": ["language"],
45+
"chunking_fields": ["audio_chunk_mode"],
46+
"api_hint": "Not an ASR route — the transcript is required input. For long audio timestamps, use Qwen3 ASR with words_out.",
47+
},
48+
}

backend/audio_analysis_profiles.py

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
"""Curated VAD and diarization family guidance."""
2+
3+
from __future__ import annotations
4+
5+
from typing import Any, Dict, List, Optional
6+
7+
from backend.audio_profile_fields import field_spec
8+
9+
_VAD_TASKS = frozenset({"vad"})
10+
_DIAR_TASKS = frozenset({"diar"})
11+
12+
13+
def is_vad_task(task: Optional[str]) -> bool:
14+
return str(task or "").strip().lower() in _VAD_TASKS
15+
16+
17+
def is_diar_task(task: Optional[str]) -> bool:
18+
return str(task or "").strip().lower() in _DIAR_TASKS
19+
20+
21+
def is_analysis_task(task: Optional[str]) -> bool:
22+
return is_vad_task(task) or is_diar_task(task)
23+
24+
25+
def analysis_profile_for_family(family: Optional[str]) -> Optional[Dict[str, Any]]:
26+
key = str(family or "").strip().lower()
27+
return _FAMILY_PROFILES.get(key) if key else None
28+
29+
30+
def analysis_request_field_groups(family: Optional[str]) -> List[Dict[str, Any]]:
31+
profile = analysis_profile_for_family(family) or {}
32+
groups: List[Dict[str, Any]] = []
33+
for group_id, label, description in _GROUP_META:
34+
keys = profile.get(f"{group_id}_fields") or []
35+
fields = [field_spec(key) for key in keys]
36+
if fields:
37+
groups.append({"id": group_id, "label": label, "description": description, "fields": fields})
38+
return groups
39+
40+
41+
_GROUP_META = [
42+
("audio", "Audio input", "Input audio for analysis."),
43+
("session", "Session mode", "Streaming requires server mode=streaming."),
44+
("chunking", "VAD chunk planning", "Offline VAD chunk window controls."),
45+
("options", "Detection options", "Threshold and segment timing controls."),
46+
]
47+
48+
_FAMILY_PROFILES: Dict[str, Dict[str, Any]] = {
49+
"silero_vad": {
50+
"label": "Silero VAD",
51+
"workflows": ["offline", "streaming"],
52+
"summary": "Speech activity detection with offline and streaming modes.",
53+
"audio_fields": ["audio"],
54+
"session_fields": ["stream"],
55+
"chunking_fields": [
56+
"vad_chunk_max_seconds",
57+
"vad_chunk_merge_gap_seconds",
58+
"vad_chunk_padding_seconds",
59+
],
60+
"options_fields": [
61+
"threshold",
62+
"neg_threshold",
63+
"min_speech_duration_ms",
64+
"min_silence_duration_ms",
65+
"speech_pad_ms",
66+
],
67+
"api_hint": "Use 16 kHz WAV. Streaming mode emits partial segments.",
68+
},
69+
"marblenet_vad": {
70+
"label": "MarbleNet VAD",
71+
"workflows": ["offline"],
72+
"summary": "Offline speech activity detection.",
73+
"audio_fields": ["audio"],
74+
"options_fields": ["threshold"],
75+
"api_hint": "Offline only; writes segment JSON.",
76+
},
77+
"marblenet": {
78+
"label": "MarbleNet VAD",
79+
"workflows": ["offline"],
80+
"summary": "Offline speech activity detection.",
81+
"audio_fields": ["audio"],
82+
"options_fields": ["threshold"],
83+
},
84+
"sortformer_diar": {
85+
"label": "Sortformer Diarization",
86+
"workflows": ["offline"],
87+
"summary": "Speaker diarization for meetings and conversations.",
88+
"audio_fields": ["audio"],
89+
"api_hint": "Default package supports up to 4 speakers.",
90+
},
91+
"sortformer": {
92+
"label": "Sortformer Diarization",
93+
"workflows": ["offline"],
94+
"summary": "Speaker diarization for meetings and conversations.",
95+
"audio_fields": ["audio"],
96+
},
97+
}

0 commit comments

Comments
 (0)