use seify::Args;
use seify::AsyncDevice;
use seify::AsyncRxDevice;
use seify::AsyncTxDevice;
use seify::Direction;
use seify::DynAsyncDevice;
use seify::MaybeSend;
use seify::dev::DynAsyncDeviceBackend;
use crate::blocks::seify::AsyncSink;
use crate::blocks::seify::AsyncSource;
use crate::blocks::seify::Config;
use crate::num_complex::Complex32;
use crate::runtime::BlockRef;
use crate::runtime::Error;
use crate::runtime::LocalDomainContext;
use crate::runtime::buffer::CpuBufferReader;
use crate::runtime::buffer::CpuBufferWriter;
use crate::runtime::scheduler::LocalScheduler;
use super::IntoAntenna;
pub struct AsyncBuilder<D> {
channels: Vec<usize>,
config: Config,
dev: AsyncDevice<D>,
ctrl: DynAsyncDevice,
start_time: Option<i64>,
min_input_buffer_size: Option<usize>,
}
impl AsyncBuilder<DynAsyncDevice> {
pub async fn new<A>(args: A) -> Result<Self, Error>
where
A: TryInto<Args> + MaybeSend + 'static,
{
let args = args.try_into().or(Err(Error::SeifyArgsConversionError))?;
Ok(Self::from_dyn_device(
DynAsyncDevice::from_args(args).await?,
))
}
pub fn from_dyn_device(ctrl: DynAsyncDevice) -> Self {
Self {
channels: vec![0],
config: Config::new(),
dev: AsyncDevice::from_impl(ctrl.clone()),
ctrl,
start_time: None,
min_input_buffer_size: None,
}
}
}
impl<D> AsyncBuilder<D>
where
D: DynAsyncDeviceBackend + Clone + 'static,
{
pub fn from_device(dev: AsyncDevice<D>) -> Self {
let ctrl = dev.to_dyn();
Self {
channels: vec![0],
config: Config::new(),
dev,
ctrl,
start_time: None,
min_input_buffer_size: None,
}
}
}
impl<D> AsyncBuilder<D> {
pub fn device<D2>(self, dev: AsyncDevice<D2>) -> AsyncBuilder<D2>
where
D2: DynAsyncDeviceBackend + Clone + 'static,
{
let ctrl = dev.to_dyn();
AsyncBuilder {
channels: self.channels,
config: self.config,
dev,
ctrl,
start_time: self.start_time,
min_input_buffer_size: self.min_input_buffer_size,
}
}
pub fn channel(mut self, channel: usize) -> Self {
self.channels = vec![channel];
self
}
pub fn channels(mut self, channels: Vec<usize>) -> Self {
self.channels = channels;
self
}
pub fn antenna<A: IntoAntenna>(mut self, antenna: A) -> Self {
self.config.antenna = antenna.into();
self
}
pub fn bandwidth(mut self, bandwidth: f64) -> Self {
self.config.bandwidth = Some(bandwidth);
self
}
pub fn frequency(mut self, frequency: f64) -> Self {
self.config.freq = Some(frequency);
self
}
pub fn gain(mut self, gain: f64) -> Self {
self.config.gain = Some(gain);
self
}
pub fn sample_rate(mut self, sample_rate: f64) -> Self {
self.config.sample_rate = Some(sample_rate);
self
}
pub fn start_time(mut self, start_time: i64) -> Self {
self.start_time = Some(start_time);
self
}
pub fn min_in_buffer_size(mut self, size: usize) -> Self {
self.min_input_buffer_size = Some(size);
self
}
pub async fn build_source(self) -> Result<AsyncSource<D>, Error>
where
D: AsyncRxDevice,
{
self.build_source_with_buffer().await
}
pub async fn build_source_in<LS>(
self,
context: &LocalDomainContext<'_, LS>,
) -> Result<BlockRef<AsyncSource<D>>, Error>
where
D: AsyncRxDevice + 'static,
LS: LocalScheduler,
{
Ok(context.add(self.build_source().await?))
}
pub async fn build_source_with_buffer<B>(self) -> Result<AsyncSource<D, B>, Error>
where
D: AsyncRxDevice,
B: CpuBufferWriter<Item = Complex32>,
{
self.config
.apply_async(&self.ctrl, &self.channels, Direction::Rx)
.await?;
Ok(AsyncSource::new(
self.dev,
self.ctrl,
self.channels,
self.start_time,
))
}
pub async fn build_sink(self) -> Result<AsyncSink<D>, Error>
where
D: AsyncTxDevice,
{
self.build_sink_with_buffer().await
}
pub async fn build_sink_in<LS>(
self,
context: &LocalDomainContext<'_, LS>,
) -> Result<BlockRef<AsyncSink<D>>, Error>
where
D: AsyncTxDevice + 'static,
LS: LocalScheduler,
{
Ok(context.add(self.build_sink().await?))
}
pub async fn build_sink_with_buffer<B>(self) -> Result<AsyncSink<D, B>, Error>
where
D: AsyncTxDevice,
B: CpuBufferReader<Item = Complex32>,
{
self.config
.apply_async(&self.ctrl, &self.channels, Direction::Tx)
.await?;
Ok(AsyncSink::new(
self.dev,
self.ctrl,
self.channels,
self.start_time,
self.min_input_buffer_size,
))
}
}