use std::marker::PhantomData;
use std::os::raw::c_void;
use std::ptr;
use crate::{
error::{check_status, Error},
usrp::Usrp,
utils::check_equal_buffer_lengths,
TransmitMetadata,
};
#[derive(Debug)]
pub struct TransmitStreamer<'usrp, I> {
handle: uhd_sys::uhd_tx_streamer_handle,
buffer_pointers: Vec<*const c_void>,
usrp: PhantomData<&'usrp Usrp>,
item_phantom: PhantomData<I>,
}
impl<I> TransmitStreamer<'_, I> {
pub(crate) fn new() -> Self {
TransmitStreamer {
handle: ptr::null_mut(),
buffer_pointers: Vec::new(),
usrp: PhantomData,
item_phantom: PhantomData,
}
}
pub(crate) fn handle_mut(&mut self) -> &mut uhd_sys::uhd_tx_streamer_handle {
&mut self.handle
}
pub(crate) fn handle(&mut self) -> uhd_sys::uhd_tx_streamer_handle {
self.handle
}
pub fn num_channels(&self) -> usize {
let mut num_channels = 0usize;
check_status(unsafe {
uhd_sys::uhd_tx_streamer_num_channels(
self.handle,
&mut num_channels as *mut usize as *mut _,
)
})
.unwrap();
num_channels
}
pub fn send(
&mut self,
buffers: &mut [&[I]],
metadata: &mut TransmitMetadata,
timeout: f64,
) -> Result<usize, Error> {
let mut samples_transmitted = 0usize;
if self.buffer_pointers.is_empty() {
self.buffer_pointers
.resize(self.num_channels(), ptr::null_mut());
}
assert_eq!(
buffers.len(),
self.buffer_pointers.len(),
"Number of buffers is not equal to this streamer's number of channels"
);
let buffer_length = check_equal_buffer_lengths(buffers);
for (entry, buffer) in self.buffer_pointers.iter_mut().zip(buffers.iter_mut()) {
*entry = buffer.as_ptr() as *mut c_void;
}
check_status(unsafe {
uhd_sys::uhd_tx_streamer_send(
self.handle,
self.buffer_pointers.as_mut_ptr(),
buffer_length as _,
metadata.handle_mut(),
timeout,
&mut samples_transmitted as *mut usize as *mut _,
)
})?;
metadata.set_samples(samples_transmitted);
Ok(samples_transmitted)
}
pub fn transmit(
&mut self,
buffers: &mut [&[I]],
timeout: f64,
) -> Result<TransmitMetadata, Error> {
let mut metadata = TransmitMetadata::default();
self.send(buffers, &mut metadata, timeout)?;
Ok(metadata)
}
pub fn transmit_simple(&mut self, buffer: &mut [I]) -> Result<TransmitMetadata, Error> {
self.transmit(&mut [buffer], 0.1)
}
}
impl<I> Drop for TransmitStreamer<'_, I> {
fn drop(&mut self) {
let _ = unsafe { uhd_sys::uhd_tx_streamer_free(&mut self.handle) };
}
}
unsafe impl<I> Send for TransmitStreamer<'_, I> {}
unsafe impl<I> Sync for TransmitStreamer<'_, I> {}