Skip to content
Draft
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
45 changes: 25 additions & 20 deletions common/src/process.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use clap_sys::process::*;
use std::fmt::Debug;
use std::ptr::addr_of;

mod constant_mask;
pub use constant_mask::*;
Expand Down Expand Up @@ -77,9 +78,15 @@ use clap_sys::audio_buffer::clap_audio_buffer;

/// Processing-related information about an audio port.
pub struct AudioPortProcessingInfo {
channel_count: u32,
latency: u32,
constant_mask: ConstantMask,
/// The number of audio channels this port provides.
pub channel_count: u32,
/// The latency to or from the audio interface, in samples.
///
/// Whether this latency is to or from the audio interface depends on which kind of port
/// this describes, an output port or an input port respectively.
pub latency: u32,
/// The [`ConstantMask`] of this port, hinting which audio channels are constant.
pub constant_mask: ConstantMask,
}

impl AudioPortProcessingInfo {
Expand All @@ -94,24 +101,22 @@ impl AudioPortProcessingInfo {
}
}

/// Returns the number of audio channels this port provides.
#[inline]
pub fn channel_count(&self) -> u32 {
self.channel_count
}

/// Returns the latency to or from the audio interface, in samples.
/// Extracts the processing-related information from a raw, C-FFI compatible audio buffer
/// descriptor.
///
/// Whether this latency is to or from the audio interface depends on which kind of port
/// this describes, an output port or an input port respectively
#[inline]
pub fn latency(&self) -> u32 {
self.latency
}

/// Returns the [`ConstantMask`] of this port, hinting which audio channels are constant.
/// Unlike [`from_raw`](Self::from_raw), this method does not require any references to perform
/// the read.
///
/// # Safety
///
/// The caller must ensure the given pointer is well-aligned, and points to an initialized
/// `clap_audio_buffer` instance that is valid for reads.
#[inline]
pub fn constant_mask(&self) -> ConstantMask {
self.constant_mask
pub unsafe fn from_raw_ptr(raw: *const clap_audio_buffer) -> Self {
Self {
channel_count: addr_of!((*raw).channel_count).read(),
latency: addr_of!((*raw).latency).read(),
constant_mask: ConstantMask::from_bits(addr_of!((*raw).constant_mask).read()),
}
}
}
8 changes: 0 additions & 8 deletions common/src/process/constant_mask.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,14 +105,6 @@ impl Debug for ConstantMask {
}
}

impl Default for ConstantMask {
/// Returns an empty constant mask, i.e. one where every channel is considered dynamic.
#[inline]
fn default() -> Self {
ConstantMask::FULLY_DYNAMIC
}
}

impl IntoIterator for ConstantMask {
type Item = bool;
type IntoIter = ConstantMaskIter;
Expand Down
4 changes: 2 additions & 2 deletions host/examples/cpal/src/host/audio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ impl StreamAudioProcessor {
self.buffers.ensure_buffer_size_matches(data.len());
let sample_count = self.buffers.cpal_buf_len_to_frame_count(data.len());

let (ins, mut outs) = self.buffers.prepare_plugin_buffers(data.len());
let (ins, outs) = self.buffers.prepare_plugin_buffers(data.len());

let events = if let Some(midi) = self.midi_receiver.as_mut() {
midi.receive_all_events(sample_count as u64)
Expand All @@ -150,7 +150,7 @@ impl StreamAudioProcessor {

match self.audio_processor.process(
&ins,
&mut outs,
&outs,
&events,
&mut OutputEvents::void(),
Some(self.steady_counter),
Expand Down
5 changes: 2 additions & 3 deletions host/examples/cpal/src/host/audio/buffers.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use crate::host::audio::config::FullAudioConfig;
use clack_host::prelude::{
AudioPortBuffer, AudioPortBufferType, AudioPorts, InputAudioBuffers, InputChannel,
OutputAudioBuffers,
AudioBuffers, AudioPortBuffer, AudioPortBufferType, AudioPorts, InputChannel,
};
use cpal::{FromSample, Sample};

Expand Down Expand Up @@ -122,7 +121,7 @@ impl HostAudioBuffers {
pub fn prepare_plugin_buffers(
&mut self,
cpal_buf_len: usize,
) -> (InputAudioBuffers<'_>, OutputAudioBuffers<'_>) {
) -> (AudioBuffers<'_>, AudioBuffers<'_>) {
let sample_count = self.cpal_buf_len_to_frame_count(cpal_buf_len);
assert!(sample_count <= self.actual_frame_count);

Expand Down
11 changes: 4 additions & 7 deletions host/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,9 @@
//!
//! Those buffer wrappers are [`InputEvents`](events::io::InputEvents) and
//! [`OutputEvents`](events::io::OutputEvents) for events, and
//! [`InputAudioBuffers`](process::audio_buffers::InputAudioBuffers) 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.
//! [`AudioPorts::with_output_buffers`](process::audio_buffers::AudioPorts::with_output_buffers)
//! respectively).
//! [`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)).
//!
//! 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 Expand Up @@ -292,8 +290,7 @@ pub mod prelude {
AudioPortProcessingInfo, PluginAudioConfiguration, PluginAudioProcessor, ProcessStatus,
StartedPluginAudioProcessor, StoppedPluginAudioProcessor,
audio_buffers::{
AudioPortBuffer, AudioPortBufferType, AudioPorts, InputAudioBuffers, InputChannel,
OutputAudioBuffers,
AudioBuffers, AudioPortBuffer, AudioPortBufferType, AudioPorts, InputChannel,
},
},
utils::ClapId,
Expand Down
24 changes: 13 additions & 11 deletions host/src/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@

#![deny(missing_docs)]

use self::audio_buffers::InputAudioBuffers;
use self::audio_buffers::AudioBuffers;
use crate::host::HostHandlers;
use crate::plugin::{PluginAudioProcessorHandle, PluginInstanceError, PluginSharedHandle};
use crate::prelude::{OutputAudioBuffers, PluginInstance};
use crate::prelude::PluginInstance;
use crate::process::PluginAudioProcessor::*;
use clack_common::events::event_types::TransportEvent;
use clack_common::events::io::{InputEvents, OutputEvents};
Expand All @@ -33,6 +33,8 @@ pub use clack_common::process::*;
#[allow(missing_docs)] // TODO: doc this
pub mod audio_buffers;

pub(crate) mod celled_audio_buffers;

/// A handle to a plugin's audio processor that can be in either its `started` or `stopped` state.
///
/// This is a convenience type that can be used where the type-states [`StartedPluginAudioProcessor`] and
Expand Down Expand Up @@ -417,10 +419,10 @@ impl<H: HostHandlers> StartedPluginAudioProcessor<H> {
/// Process a chunk of audio frames and events.
///
/// This plugin function requires the following arguments:
/// * `audio_inputs`: The [`InputAudioBuffers`] the plugin is going to read audio frames from.
/// Can be [`InputAudioBuffers::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_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 [`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 All @@ -435,7 +437,7 @@ impl<H: HostHandlers> StartedPluginAudioProcessor<H> {
/// other plugin instances may receive.
///
/// The only requirement is that this value must be increased by at least the frame count
/// of the audio buffers (see [`InputAudioBuffers::min_available_frames_with`]) for the next
/// of the audio buffers (see [`AudioBuffers::min_available_frames_with`]) for the next
/// call to `process`.
///
/// This value can never decrease between two calls to `process`, unless [`reset`]
Expand Down Expand Up @@ -463,8 +465,8 @@ impl<H: HostHandlers> StartedPluginAudioProcessor<H> {
/// [`reset`]: Self::reset
pub fn process(
&mut self,
audio_inputs: &InputAudioBuffers,
audio_outputs: &mut OutputAudioBuffers,
audio_inputs: &AudioBuffers,
audio_outputs: &AudioBuffers,
input_events: &InputEvents,
output_events: &mut OutputEvents,
steady_time: Option<u64>,
Expand All @@ -478,8 +480,8 @@ impl<H: HostHandlers> StartedPluginAudioProcessor<H> {
in_events: input_events.as_raw(),
out_events: output_events.as_raw_mut(),

audio_inputs: audio_inputs.as_raw_buffers().as_ptr(),
audio_outputs: audio_outputs.as_raw_buffers().as_mut_ptr(),
audio_inputs: audio_inputs.as_raw_buffers().cast(),
audio_outputs: audio_outputs.as_raw_buffers().cast(),
audio_inputs_count: audio_inputs.port_count(),
audio_outputs_count: audio_outputs.port_count(),

Expand Down
Loading
Loading