डेस्कटॉप ऑडियो पाइपलाइन
adk-audio क्रेट desktop-audio फीचर फ़्लैग के पीछे क्रॉस-प्लेटफ़ॉर्म डेस्कटॉप ऑडियो I/O प्रदान करता है। तीन घटक — AudioCapture, AudioPlayback, और VadTurnManager — डेस्कटॉप वॉइस एजेंट बनाने के लिए माइक्रोफ़ोन कैप्चर, स्पीकर प्लेबैक और VAD-आधारित टर्न-टेकिंग सक्षम करते हैं।
अवलोकन
डेस्कटॉप ऑडियो पाइपलाइन सिस्टम ऑडियो हार्डवेयर को मौजूदा adk-audio पाइपलाइन सिस्टम से जोड़ती है:
Microphone → AudioCapture → AudioStream → [VAD → STT → Agent → TTS] → AudioPlayback → Speaker
सभी घटक क्रॉस-प्लेटफ़ॉर्म ऑडियो के लिए cpal क्रेट (macOS पर CoreAudio, Linux पर PipeWire/ALSA/PulseAudio, Windows पर WASAPI) का उपयोग करते हैं और मानक AudioFrame प्रकार का उत्पादन/उपभोग करते हैं।
फीचर फ़्लैग
[dependencies]
# Cross-platform (macOS, Linux, Windows) via cpal
adk-audio = { version = "2.1.0", features = ["desktop-audio"] }
desktop-audio फीचर vad (VadProcessor के लिए) को निहित करता है और निर्भरता के रूप में cpal जोड़ता है। CI बिल्ड में प्लेटफ़ॉर्म-विशिष्ट ऑडियो निर्भरताएँ शामिल होने से बचाने के लिए इसे जानबूझकर all फीचर से बाहर रखा गया है।
PipeWire सपोर्ट
आधुनिक Linux (Fedora 34+, Ubuntu 22.10+, Arch) पर PipeWire ने डिफ़ॉल्ट ऑडियो सर्वर के रूप में PulseAudio और ALSA का स्थान ले लिया है। desktop-audio फीचर अपने ALSA संगतता स्तर के माध्यम से PipeWire पर पारदर्शी रूप से काम करता है — किसी अतिरिक्त कॉन्फ़िगरेशन की आवश्यकता नहीं है।
pipewire क्रेट (v0.9) का उपयोग करने वाला एक नेटिव PipeWire बैकएंड (desktop-pipewire) भविष्य के रिलीज़ के लिए नियोजित है। नेटिव PipeWire कम लेटेंसी और प्रत्यक्ष सेशन प्रबंधन प्रदान करेगा। यह वर्तमान में एक निर्भरता संघर्ष के कारण अवरुद्ध है: redis-protocol 6.0.0, cookie-factory =0.3.2 को पिन करता है, जबकि pipewire का libspa, 0.3.3 की आवश्यकता रखता है। अपस्ट्रीम द्वारा यह पिन शिथिल किए जाने के बाद नेटिव बैकएंड जोड़ा जा सकता है।
त्वरित शुरुआत
ऑडियो डिवाइस सूचीबद्ध करें
use adk_audio::{AudioCapture, AudioPlayback};
let inputs = AudioCapture::list_input_devices()?;
for device in &inputs {
println!("Mic: {} ({})", device.name(), device.id());
}
let outputs = AudioPlayback::list_output_devices()?;
for device in &outputs {
println!("Speaker: {} ({})", device.name(), device.id());
}
माइक्रोफ़ोन ऑडियो कैप्चर करें
use adk_audio::{AudioCapture, CaptureConfig};
use std::time::{Duration, Instant};
let mut capture = AudioCapture::new();
let devices = AudioCapture::list_input_devices()?;
let device = devices.first().expect("no input device");
let config = CaptureConfig::default(); // 16kHz, mono, 20ms frames
let mut stream = capture.start_capture(device.id(), &config)?;
let start = Instant::now();
while start.elapsed() < Duration::from_secs(3) {
if let Some(frame) = stream.recv().await {
// frame.data: PCM-16 LE bytes
// frame.sample_rate: 16000
// frame.channels: 1
// frame.duration_ms: 20
}
}
capture.stop_capture();
स्पीकर के माध्यम से ऑडियो चलाएँ
use adk_audio::{AudioFrame, AudioPlayback};
let mut playback = AudioPlayback::new();
let devices = AudioPlayback::list_output_devices()?;
let device = devices.first().expect("no output device");
let frame = AudioFrame::silence(16000, 1, 1000); // 1 second
playback.play(device.id(), &frame).await?;
playback.stop();
VAD टर्न-टेकिंग
use std::sync::Arc;
use adk_audio::{
AudioCapture, CaptureConfig, VadConfig, VadMode,
VadTurnManager, VoiceActivityEvent, VadProcessor,
};
let vad: Arc<dyn VadProcessor> = /* your VadProcessor impl */;
let config = VadConfig {
mode: VadMode::HandsFree,
silence_threshold_ms: 500,
speech_threshold_ms: 200,
};
let mut manager = VadTurnManager::new(vad, config)?;
let mut capture = AudioCapture::new();
let stream = capture.start_capture(device_id, &CaptureConfig::default())?;
manager.start(stream, |event| {
match event {
VoiceActivityEvent::SpeechStarted => println!("Speech started"),
VoiceActivityEvent::SpeechEnded { duration_ms } => {
println!("Speech ended ({duration_ms}ms)");
}
}
});
घटक
AudioDevice
सिस्टम ऑडियो डिवाइस (इनपुट या आउटपुट) का वर्णनकर्ता। इसमें एक अपारदर्शी id और मानव-पठनीय name शामिल हैं।
CaptureConfig
माइक्रोफ़ोन कैप्चर के लिए कॉन्फ़िगरेशन:
| फ़ील्ड | प्रकार | डिफ़ॉल्ट | विवरण |
|---|---|---|---|
sample_rate | u32 | 16000 | Hz में सैंपल दर |
channels | u8 | 1 | चैनल संख्या (1=मोनो, 2=स्टीरियो) |
frame_duration_ms | u32 | 20 | प्रत्येक AudioFrame की अवधि |
उपयोग से पहले validate() को कॉल करें — AudioError::Device के साथ शून्य मानों को अस्वीकार करता है।
AudioCapture
cpal के माध्यम से माइक्रोफ़ोन कैप्चर। start_capture() विधि एक AudioStream लौटाती है (क्षमता 64 वाला सीमित mpsc::Receiver<AudioFrame>)। फ़्रेम PCM-16 LE प्रारूप में frame_duration_ms अंतराल पर बनाए जाते हैं।
AudioPlayback
cpal के माध्यम से स्पीकर प्लेबैक। play() विधि एक AudioFrame के सैंपल को साझा बफ़र में कतारबद्ध करती है, जिसे cpal आउटपुट कॉलबैक खाली करता है। डिवाइस को रिलीज़ करने के लिए stop() को कॉल करें।
VadTurnManager
एक AudioStream का उपभोग करता है, प्रत्येक फ़्रेम पर VadProcessor::is_speech() लागू करता है, और पंजीकृत कॉलबैक के माध्यम से VoiceActivityEvent मान जारी करता है।
दो मोड:
- HandsFree — कॉन्फ़िगर किए जा सकने वाले मौन और वाक् अवधि थ्रेशोल्ड का उपयोग करके स्वचालित वाक् सीमा पहचान
- PushToTalk — कोई स्वचालित इवेंट नहीं; कॉलर बाहरी रूप से गेटिंग नियंत्रित करता है
VadConfig
| फ़ील्ड | प्रकार | विवरण |
|---|---|---|
mode | VadMode | HandsFree या PushToTalk |
silence_threshold_ms | u32 | SpeechEnded से पहले लगातार मौन |
speech_threshold_ms | u32 | SpeechStarted से पहले लगातार भाषण |
उपयोग से पहले validate() को कॉल करें — AudioError::Vad के साथ शून्य थ्रेशोल्ड अस्वीकार करता है।
वॉइस एजेंट बनाना
पूर्ण संवादात्मक वॉइस एजेंट पैटर्न:
- माइक्रोफ़ोन से ऑडियो कैप्चर करें
- VAD के साथ वाक् सीमाओं का पता लगाएँ
- GeminiStt (या किसी भी
SttProvider) के साथ वाक् को ट्रांसक्राइब करें - तर्क के लिए ट्रांसक्रिप्ट को LlmAgent को भेजें
- GeminiTts (या किसी भी
TtsProvider) के साथ प्रतिक्रिया को संश्लेषित करें - संश्लेषित ऑडियो को स्पीकर के माध्यम से चलाएँ
वास्तविक Gemini क्लाउड प्रदाताओं का उपयोग करने वाले पूर्ण कार्यशील उदाहरण के लिए examples/desktop_audio/src/voice_agent.rs देखें।
थ्रेड सुरक्षा
सभी डेस्कटॉप ऑडियो प्रकार (AudioCapture, AudioPlayback, VadTurnManager) Send + Sync हैं, जिससे उन्हें Tokio टास्क के बीच साझा करना सुरक्षित होता है।
त्रुटि प्रबंधन
डेस्कटॉप ऑडियो त्रुटियाँ मौजूदा AudioError एनम का उपयोग करती हैं:
| घटक | त्रुटि प्रकार | कब |
|---|---|---|
| AudioCapture | AudioError::Device | डिवाइस नहीं मिला, होस्ट अनुपलब्ध, कॉन्फ़िगरेशन सत्यापन |
| AudioPlayback | AudioError::Device | डिवाइस नहीं मिला, होस्ट अनुपलब्ध, खोलने/लिखने में विफलता |
| VadTurnManager | AudioError::Vad | कॉन्फ़िगरेशन सत्यापन (शून्य सीमाएँ) |
प्लेटफ़ॉर्म समर्थन
| प्लेटफ़ॉर्म | ऑडियो बैकएंड | स्थिति |
|---|---|---|
| macOS | CoreAudio | समर्थित |
| Linux | PipeWire (ALSA compat के माध्यम से) | समर्थित (libasound2-dev इंस्टॉल करें) |
| Linux | ALSA / PulseAudio (विरासत) | समर्थित (libasound2-dev इंस्टॉल करें) |
| Windows | WASAPI | समर्थित |
आधुनिक Linux पर, PipeWire डिफ़ॉल्ट ऑडियो सर्वर है और इसने PulseAudio तथा ALSA का स्थान ले लिया है। desktop-audio सुविधा PipeWire पर इसकी ALSA संगतता परत के माध्यम से पारदर्शी रूप से काम करती है। pipewire crate का उपयोग करने वाला मूल PipeWire backend भविष्य की रिलीज़ के लिए नियोजित है (वर्तमान में redis-protocol में upstream dependency conflict के कारण अवरुद्ध है)।
उदाहरण
वास्तविक Gemini STT/TTS वाले एक पूर्ण संवादात्मक voice agent सहित 6 व्यावहारिक उदाहरणों के लिए examples/desktop_audio/ देखें।