use super::{FilterProcError, FilterProcResult, ObjectInfo, SceneInfo};
#[derive(Debug, Clone, Copy)]
pub struct ObjectAudioParam {
pub vol_l: f32,
pub vol_r: f32,
}
impl From<&aviutl2_sys::filter2::OBJECT_AUDIO_PARAM> for ObjectAudioParam {
fn from(value: &aviutl2_sys::filter2::OBJECT_AUDIO_PARAM) -> Self {
Self {
vol_l: value.vol_l,
vol_r: value.vol_r,
}
}
}
impl From<aviutl2_sys::filter2::OBJECT_AUDIO_PARAM> for ObjectAudioParam {
fn from(value: aviutl2_sys::filter2::OBJECT_AUDIO_PARAM) -> Self {
Self {
vol_l: value.vol_l,
vol_r: value.vol_r,
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct AudioObjectInfo {
pub sample_index: u64,
pub sample_total: u64,
pub sample_num: u32,
pub channel_num: u32,
}
#[derive(Debug)]
pub struct FilterProcAudio<U: super::FilterUserdata> {
pub scene: SceneInfo,
pub object: ObjectInfo,
pub audio_object: AudioObjectInfo,
pub param: ObjectAudioParam,
pub userdata: super::FilterUserdataHandle<U>,
pub(crate) read_section: crate::generic::ReadSection,
pub(crate) inner: *const aviutl2_sys::filter2::FILTER_PROC_AUDIO,
}
unsafe impl<U: super::FilterUserdata> Send for FilterProcAudio<U> {}
unsafe impl<U: super::FilterUserdata> Sync for FilterProcAudio<U> {}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum AudioChannel {
Left,
Right,
Any(i32),
}
impl From<i32> for AudioChannel {
fn from(value: i32) -> Self {
match value {
0 => AudioChannel::Left,
1 => AudioChannel::Right,
v => AudioChannel::Any(v),
}
}
}
impl From<AudioChannel> for i32 {
fn from(value: AudioChannel) -> Self {
match value {
AudioChannel::Left => 0,
AudioChannel::Right => 1,
AudioChannel::Any(v) => v,
}
}
}
impl<U: super::FilterUserdata> FilterProcAudio<U> {
pub fn set_filter_config_data_size(
&self,
data: &mut crate::filter::VariableLengthFilterConfigDataHandle,
size: usize,
) -> FilterProcResult<()> {
data.try_resize(size, |data, size| unsafe {
((*self.inner).set_filter_item_data_size)(data, size);
})
}
pub fn get_sample_data(&mut self, channel: AudioChannel, buffer: &mut [f32]) -> usize {
let sample_num = self.audio_object.sample_num as usize;
assert_eq!(
buffer.len(),
sample_num,
"buffer length does not match sample_num"
);
let inner = unsafe { &*self.inner };
unsafe { (inner.get_sample_data)(buffer.as_mut_ptr(), channel.into()) };
sample_num
}
pub fn set_sample_data(&mut self, channel: AudioChannel, data: &[f32]) {
let sample_num = self.audio_object.sample_num as usize;
assert_eq!(
data.len(),
sample_num,
"data length does not match sample_num"
);
let inner = unsafe { &*self.inner };
unsafe { (inner.set_sample_data)(data.as_ptr(), channel.into()) };
}
pub fn read_section(&mut self) -> &crate::generic::ReadSection {
&self.read_section
}
pub fn get_output_audio_param(
&self,
object: crate::generic::ObjectHandle,
offset: f64,
) -> FilterProcResult<ObjectAudioParam> {
let inner = unsafe { &*self.inner };
let mut param = aviutl2_sys::filter2::OBJECT_AUDIO_PARAM {
vol_l: 0.0,
vol_r: 0.0,
};
let ok = unsafe {
(inner.get_output_audio_param)(
object.internal,
offset,
&mut param,
std::mem::size_of::<aviutl2_sys::filter2::OBJECT_AUDIO_PARAM>() as i32,
)
};
if ok {
Ok(param.into())
} else {
Err(FilterProcError::ApiCallFailed)
}
}
pub fn get_audio_object(
&self,
layer: u32,
offset: f64,
) -> Option<crate::generic::ObjectHandle> {
let handle = unsafe { ((*self.inner).get_audio_object)(layer as _, offset) };
if handle.is_null() {
None
} else {
Some(crate::generic::ObjectHandle { internal: handle })
}
}
pub(crate) fn apply_param(&mut self) {
let inner = unsafe { &mut *(*self.inner).param };
inner.vol_l = self.param.vol_l;
inner.vol_r = self.param.vol_r;
}
}