Skip to content

Commit

Permalink
docs wip
Browse files Browse the repository at this point in the history
  • Loading branch information
prokopyl committed Aug 28, 2024
1 parent 1aec02d commit 7c0530e
Show file tree
Hide file tree
Showing 8 changed files with 44 additions and 56 deletions.
7 changes: 3 additions & 4 deletions host/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,10 @@
//!
//! Those buffer wrappers are [`InputEvents`](events::io::InputEvents) and
//! [`OutputEvents`](events::io::OutputEvents) for events, and
//! [`InputAudioBuffers`](process::audio_buffers::AudioBuffers) and
//! [`OutputAudioBuffers`](process::audio_buffers::OutputAudioBuffers) for audio (obtained via a call to
//! [`AudioPorts::with_input_buffers`](process::audio_buffers::AudioPorts::with_input_buffers) and.
//! [`AudioBuffers`](process::audio_buffers::AudioBuffers) for audio (obtained via a call to
//! [`AudioPorts::with_input_buffers`](process::audio_buffers::AudioPorts::with_input_buffers) or
//! [`AudioPorts::with_output_buffers`](process::audio_buffers::AudioPorts::with_output_buffers)
//! respectively).
//! ).
//!
//! See the documentation of those buffer types for more detail on what types they support, as
//! well as the [`process`](process::StartedPluginAudioProcessor::process) method's
Expand Down
4 changes: 2 additions & 2 deletions host/src/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -418,8 +418,8 @@ impl<H: HostHandlers> StartedPluginAudioProcessor<H> {
/// This plugin function requires the following arguments:
/// * `audio_inputs`: The [`AudioBuffers`] the plugin is going to read audio frames from.
/// Can be [`AudioBuffers::empty`] if the plugin takes no audio input at all.
/// * `audio_output`: The [`OutputAudioBuffers`] the plugin is going to read audio frames from.
/// Can be [`OutputAudioBuffers::empty`] if the plugin produces no audio output at all.
/// * `audio_output`: The [`AudioBuffers`] the plugin is going to read audio frames from.
/// Can be [`AudioBuffers::empty`] if the plugin produces no audio output at all.
/// * `input_events`: The [`InputEvents`] list the plugin is going to receive events from.
/// Can be [`InputEvents::empty`] if the plugin doesn't need to receive any events.
/// * `output_events`: The [`OutputEvents`] buffer the plugin is going to write the events it
Expand Down
45 changes: 32 additions & 13 deletions plugin/src/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
//! All of those types are exclusively used in the [`Plugin::process`](crate::plugin::PluginAudioProcessor::process)
//! method. See the [`Plugin`](crate::plugin::PluginAudioProcessor) trait documentation for examples on how these types interact.
use crate::internal_utils::slice_from_external_parts;
use clack_common::events::event_types::TransportEvent;
use clack_common::events::io::{InputEvents, OutputEvents};
pub use clack_common::process::*;
use clap_sys::audio_buffer::clap_audio_buffer;
use clap_sys::process::clap_process;
use std::ops::RangeBounds;

pub mod audio;
use crate::internal_utils::slice_from_external_parts;
use audio::*;

/// Metadata about the current process call.
Expand Down Expand Up @@ -92,7 +93,7 @@ impl<'a> Events<'a> {
/// * Each channel is a raw buffer (i.e. slice) of either [`f32`] or [`f64`] samples.
///
/// This structure applies both to inputs and outputs: the [`Audio`] struct allows to retrieve
/// [`Port`]s and [`OutputPort`]s separately, but they can also be accessed together as
/// input and output [`Port`]s separately, but they can also be accessed together as
/// Input/Output [`PortPair`]s. This allows for the common use-case of borrowing both an input
/// and its matching output for processing, while also being safe to hosts using the same buffer for
/// both.
Expand All @@ -101,7 +102,7 @@ impl<'a> Events<'a> {
/// an index, or all at once with an iterator. For instance, [`Port`]s can be accessed either
/// one-at-a-time with [`Audio::input_port`], or with an iterator from [`Audio::input_ports`]. A
/// [`Audio::input_port_count`] method is also available. The same methods are available for
/// [`OutputPort`]s and [`PortPair`]s.
/// the output [`Port`]s and [`PortPair`]s.
///
/// Note that because ports can individually hold either 32-bit or 64-bit sample data, an extra
/// sample type detection step is necessary before the port's channels themselves can be accessed.
Expand Down Expand Up @@ -229,8 +230,8 @@ impl<'a> Audio<'a> {
///
/// # Safety
///
/// The caller must ensure the given pointers to all buffer structs are valid for 'a,
/// including all the buffer pointers they themselves contain.
/// The caller must ensure the given pointers to all buffer structs are valid for both reads
/// and writes for the duration of 'a, including all the buffer pointers they themselves contain.
///
/// The caller must also ensure `frames_count` is lower than or equal to the sizes of the
/// channel buffers pointed to by `buffers`.
Expand All @@ -247,8 +248,26 @@ impl<'a> Audio<'a> {
}
}

/// Returns a raw pointer to a C array of the raw output buffers structs.
// TODO: safety of creating & or &mut from this
/// Returns a raw pointer to a slice of the raw input buffers structs.
///
/// # Safety
///
/// While this function is safe to use, there are many cases where using the resulting pointer
/// is not.
///
/// This is because the contents slice of buffer structs (as well as the raw audio buffers these
/// point to) are valid for both reads and writes from other, potentially aliased pointers to
/// that data.
///
/// This means it is not valid to create either shared (`&`) or mutable (`&mut`) Rust references
/// to these buffers or their data.
///
/// In order to safely access the data, you can either use [`Cell`]s, or perform direct
/// read or write operations, e.g. using [`ptr::read`] or [`ptr::write`].
///
/// [`ptr::read`]: core::ptr::read
/// [`ptr::write`]: core::ptr::write
/// [`Cell`]: core::cell::Cell
#[inline]
pub fn raw_inputs(&self) -> *const [clap_audio_buffer] {
core::ptr::slice_from_raw_parts(self.inputs.as_ptr().cast(), self.inputs.len())
Expand All @@ -261,7 +280,7 @@ impl<'a> Audio<'a> {
core::ptr::slice_from_raw_parts(self.outputs.as_ptr().cast(), self.outputs.len())
}

/// Retrieves the [`Port`] at a given index.
/// Retrieves the input [`Port`] at a given index.
///
/// This returns [`None`] if there is no input port at the given index.
///
Expand All @@ -275,13 +294,13 @@ impl<'a> Audio<'a> {
.map(|buf| unsafe { Port::from_raw(buf, self.frames_count) })
}

/// Retrieves the number of available [`Port`]s.
/// Retrieves the number of available input [`Port`]s.
#[inline]
pub fn input_port_count(&self) -> usize {
self.inputs.len()
}

/// Returns an iterator of all the available [`Port`]s at once.
/// Returns an iterator of all the available input [`Port`]s at once.
///
/// See also the [`input_port`](Audio::input_port) method to retrieve a single input port by
/// its index.
Expand All @@ -290,7 +309,7 @@ impl<'a> Audio<'a> {
PortsIter::new(self.inputs, self.frames_count)
}

/// Retrieves the [`OutputPort`] at a given index.
/// Retrieves the output [`Port`] at a given index.
///
/// This returns [`None`] if there is no output port at the given index.
///
Expand All @@ -304,13 +323,13 @@ impl<'a> Audio<'a> {
.map(|buf| unsafe { Port::from_raw(buf, self.frames_count) })
}

/// Retrieves the number of available [`OutputPort`]s.
/// Retrieves the number of available output [`Port`]s.
#[inline]
pub fn output_port_count(&self) -> usize {
self.outputs.len()
}

/// Returns an iterator of all the available [`OutputPort`]s at once.
/// Returns an iterator of all the available output [`Port`]s at once.
///
/// See also the [`output_port`](Audio::output_port) method to retrieve a single output port by
/// its index.
Expand Down
12 changes: 0 additions & 12 deletions plugin/src/process/audio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ mod port;
mod sample_type;

pub use buffer::AudioBuffer;
use clack_common::process::{AudioPortProcessingInfo, ConstantMask};
pub use error::BufferError;
pub use pair::*;
pub use port::*;
Expand All @@ -23,17 +22,6 @@ pub(crate) struct CelledClapAudioBuffer {
pub constant_mask: Cell<u64>, // Cell has the same memory layout as the inner type
}

impl CelledClapAudioBuffer {
#[inline]
pub(crate) fn info(&self) -> AudioPortProcessingInfo {
AudioPortProcessingInfo {
channel_count: self.channel_count,
latency: self.latency,
constant_mask: ConstantMask::from_bits(self.constant_mask.get()),
}
}
}

#[cfg(test)]
pub mod tests {
use super::*;
Expand Down
3 changes: 1 addition & 2 deletions plugin/src/process/audio/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ pub enum BufferError {
///
/// This happens when both the [`f32`] and [`f64`] buffer pointers provided by the host are null.
///
/// This error can be returned by the [`InputPort::channels`](super::Port::channels),
/// [`OutputPort::channels`](super::OutputPort::channels), or
/// This error can be returned by the [`InputPort::channels`](super::Port::channels) or
/// [`PortPair::channels`](super::PortPair::channels) methods.
InvalidChannelBuffer,
/// A pair of mismatched buffer types (i.e. one [`f32`] and the other [`f64`]) were tried to
Expand Down
21 changes: 2 additions & 19 deletions plugin/src/process/audio/pair.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use crate::process::audio::pair::ChannelPair::*;
use crate::process::audio::{AudioBuffer, BufferError, CelledClapAudioBuffer, Port, SampleType};
use crate::process::Audio;
use clack_common::process::AudioPortProcessingInfo;
use std::slice::Iter;

/// A pair of Input and Output ports.
Expand Down Expand Up @@ -40,7 +39,7 @@ impl<'a> PortPair<'a> {
}
}

/// Gets the [`Port`] of this pair.
/// Gets the input [`Port`] of this pair.
///
/// If the port layout is asymmetric and there is no input port, this returns [`None`].
#[inline]
Expand All @@ -50,7 +49,7 @@ impl<'a> PortPair<'a> {
.map(|i| unsafe { Port::from_raw(i, self.frames_count) })
}

/// Gets the [`OutputPort`] of this pair.
/// Gets the output [`Port`] of this pair.
///
/// If the port layout is asymmetric and there is no output port, this returns [`None`].
#[inline]
Expand All @@ -60,22 +59,6 @@ impl<'a> PortPair<'a> {
.map(|i| unsafe { Port::from_raw(i, self.frames_count) })
}

/// Retrieves the port info for the input of this pair.
///
/// If the port layout is asymmetric and there is no input port, this returns [`None`].
#[inline]
pub fn input_info(&self) -> Option<AudioPortProcessingInfo> {
self.input.map(|buf| buf.info())
}

/// Retrieves the port info for the output of this pair.
///
/// If the port layout is asymmetric and there is no output port, this returns [`None`].
#[inline]
pub fn output_info(&self) -> Option<AudioPortProcessingInfo> {
self.output.map(|buf| buf.info())
}

/// Retrieves the port pair's channels.
///
/// Because each port can hold either [`f32`] or [`f64`] sample data, this method returns a
Expand Down
2 changes: 2 additions & 0 deletions plugin/src/process/audio/port.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ use clack_common::process::ConstantMask;
use std::slice::Iter;

/// An iterator of all the available [`Port`]s from an [`Audio`] struct.
///
/// [`Audio`]: crate::process::Audio
pub struct PortsIter<'a> {
inputs: Iter<'a, CelledClapAudioBuffer>,
frames_count: u32,
Expand Down
6 changes: 2 additions & 4 deletions plugin/src/process/audio/sample_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,8 @@ use crate::process::audio::{BufferError, CelledClapAudioBuffer};
///
/// This type is used by methods that detect which types of sample buffers are available:
///
/// * [`InputPort::channels`](super::Port::channels) returns a [`SampleType`] of
/// [`InputChannels`](super::PortChannels);
/// * [`OutputPort::channels`](super::OutputPort::channels) returns a [`SampleType`] of
/// [`OutputChannels`](super::OutputChannels);
/// * [`Port::channels`](super::Port::channels) returns a [`SampleType`] of
/// [`PortChannels`](super::PortChannels);
/// * [`PortPair::channels`](super::PortPair::channels) returns a [`SampleType`] of
/// [`PairedChannels`](super::PairedChannels);
#[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq)]
Expand Down

0 comments on commit 7c0530e

Please sign in to comment.