Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/audio_buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,8 @@ where
Some(Self { storage })
}

/// Create an audio buffer reference from non-interleaved data. This does *not* copy the data,
/// but creates a view over it, so that it can be accessed as any other audio buffer.
pub fn from_noninterleaved(data: &'a [T], channels: usize) -> Option<Self> {
let buffer_size = data.len() / channels;
let storage = ArrayView2::from_shape((channels, buffer_size), data).ok()?;
Expand All @@ -373,6 +375,12 @@ impl<'a, T: 'a> AudioMut<'a, T> {
Some(Self { storage })
}

/// Create an audio buffer mutable reference from interleaved data. This does *not* copy the
/// data, but creates a view over it, so that it can be accessed as any other audio buffer.
///
/// Writes to the resulting buffer directly map to the provided slice, and asking an
/// interleaved view out of the resulting buffer (with [`AudioBufferBase::as_interleaved`])
/// means the same slice is returned.
pub fn from_noninterleaved_mut(data: &'a mut [T], channels: usize) -> Option<Self> {
let buffer_size = data.len() / channels;
let storage = ArrayViewMut2::from_shape((channels, buffer_size), data).ok()?;
Expand Down
12 changes: 6 additions & 6 deletions src/backends/alsa/stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,14 @@ impl<Callback: 'static + Send> AlsaStream<Callback> {
let mut poll_descriptors = {
let mut buf = vec![rx.as_pollfd()];
let num_descriptors = device.pcm.count();
buf.extend(
std::iter::repeat(libc::pollfd {
buf.extend(std::iter::repeat_n(
libc::pollfd {
fd: 0,
events: 0,
revents: 0,
})
.take(num_descriptors),
);
},
num_descriptors,
));
buf
};
let (hwp, _, io) = device.apply_config(&stream_config)?;
Expand All @@ -70,7 +70,7 @@ impl<Callback: 'static + Send> AlsaStream<Callback> {
let stream_config = StreamConfig {
samplerate,
channels: ChannelMap32::default()
.with_indices(std::iter::repeat(1).take(num_channels)),
.with_indices(std::iter::repeat_n(1, num_channels)),
buffer_size_range: (Some(period_size), Some(period_size)),
exclusive: false,
};
Expand Down
8 changes: 8 additions & 0 deletions src/backends/pipewire/device.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! PipeWire device abstraction.

use super::stream::StreamHandle;
use crate::backends::pipewire::error::PipewireError;
use crate::{
Expand All @@ -12,15 +14,21 @@ use std::cell::{Cell, RefCell};
use std::collections::HashMap;
use std::rc::Rc;

/// A device (like a sound card) in PipeWire.
pub struct PipewireDevice {
pub(super) target_node: Option<u32>,
/// Additive flags describing the device (input/output/...)
pub device_type: DeviceType,
/// Serial number of the device node in the PipeWire graph.
pub object_serial: Option<String>,
/// Name to be used for the next created stream.
pub stream_name: Cow<'static, str>,
/// Properties for the next created stream.
pub stream_properties: HashMap<Vec<u8>, Vec<u8>>,
}

impl PipewireDevice {
/// Get PipeWire properties of the PipeWire device node.
pub fn properties(&self) -> Result<Option<Properties>, PipewireError> {
let Some(node_id) = self.target_node else {
return Ok(None);
Expand Down
3 changes: 3 additions & 0 deletions src/backends/pipewire/driver.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! PipeWire driver abstraction.

use super::error::PipewireError;
use crate::backends::pipewire::device::PipewireDevice;
use crate::backends::pipewire::utils;
Expand All @@ -6,6 +8,7 @@ use std::borrow::Cow;
use std::collections::HashMap;
use std::marker::PhantomData;

/// The Interflow PipeWire backend driver.
pub struct PipewireDriver {
__init: PhantomData<()>,
}
Expand Down
5 changes: 5 additions & 0 deletions src/backends/pipewire/error.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
//! PipeWire errors.

use thiserror::Error;

/// PipeWire error.
#[derive(Debug, Error)]
pub enum PipewireError {
/// Error originating in the PipeWire backend.
#[error("Pipewire error: {0}")]
BackendError(#[from] pipewire::Error),
/// Error creating a pipewire stream (SPA pod serialization problem).
#[error("Cannot create Pipewire stream: {0}")]
GenError(#[from] libspa::pod::serialize::GenError),
}
7 changes: 7 additions & 0 deletions src/backends/pipewire/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
//! # PipeWire backend
//!
//! PipeWire is a modern multimedia server for Linux systems, designed to handle both audio and
//! video streams. It provides low-latency performance and advanced routing capabilities while
//! maintaining compatibility with older APIs like ALSA and PulseAudio, making it a flexible and
//! future-oriented backend.

pub mod device;
pub mod driver;
pub mod error;
Expand Down
3 changes: 3 additions & 0 deletions src/backends/pipewire/stream.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! PipeWire streams.

use crate::audio_buffer::{AudioMut, AudioRef};
use crate::backends::pipewire::error::PipewireError;
use crate::channel_map::Bitset;
Expand Down Expand Up @@ -124,6 +126,7 @@ impl<Callback: AudioInputCallback> StreamInner<Callback> {
}
}

/// PipeWire stream handle.
pub struct StreamHandle<Callback> {
commands: rtrb::Producer<StreamCommands<Callback>>,
handle: JoinHandle<Result<(), PipewireError>>,
Expand Down
Loading