use anyhow::Result;
use std::time::Duration;
use crate::audio::{AudioConfig, AudioFrame};
use crate::sounddevice_impl::AudioStreamBuilder;
pub struct SyncAudioClient {
inner: crate::sounddevice_impl::RemoteAudioStream,
config: AudioConfig,
}
impl SyncAudioClient {
pub fn connect(server_id: &str) -> Result<Self> {
Self::connect_with_config(server_id, AudioConfig::default())
}
pub fn connect_with_config(server_id: &str, config: AudioConfig) -> Result<Self> {
Self::connect_with_config_and_timeout(server_id, config, None)
}
pub fn connect_with_config_and_timeout(
server_id: &str,
config: AudioConfig,
timeout: Option<Duration>,
) -> Result<Self> {
let mut builder = AudioStreamBuilder::new(server_id)
.sample_rate(config.sample_rate)
.channels(config.channels)
.sample_format(config.sample_format);
if let Some(t) = timeout {
builder = builder.timeout(t);
}
let stream = builder.open()?;
Ok(Self {
inner: stream,
config,
})
}
pub fn connect_moq(path: &str) -> Result<Self> {
Self::connect_moq_with_config(path, AudioConfig::default())
}
pub fn connect_moq_with_config(path: &str, config: AudioConfig) -> Result<Self> {
let stream = AudioStreamBuilder::new(path)
.sample_rate(config.sample_rate)
.channels(config.channels)
.sample_format(config.sample_format)
.open()?;
Ok(Self {
inner: stream,
config,
})
}
pub fn connect_auto(source: &str) -> Result<Self> {
if source.contains('/') {
Self::connect_moq(source)
} else {
Self::connect(source)
}
}
pub fn read_chunk(&mut self) -> Result<AudioFrame> {
self.inner.read_chunk()
}
pub fn write_chunk(&mut self, frame: &AudioFrame) -> Result<()> {
self.inner.write_chunk(frame)
}
pub fn record(&mut self, frames: usize) -> Result<Vec<f32>> {
self.inner.record(frames)
}
pub fn play(&mut self, data: &[f32]) -> Result<()> {
self.inner.play(data)
}
pub fn config(&self) -> &AudioConfig {
&self.config
}
}