Skip to main content

aviutl2\filter\binding/
audio.rs

1use super::{FilterProcError, FilterProcResult, ObjectInfo, SceneInfo};
2
3/// オブジェクトの音声パラメータ構造体。
4#[derive(Debug, Clone, Copy)]
5pub struct ObjectAudioParam {
6    /// 左チャンネルの音量倍率。(1.0=等倍)
7    pub vol_l: f32,
8    /// 右チャンネルの音量倍率。(1.0=等倍)
9    pub vol_r: f32,
10}
11impl From<&aviutl2_sys::filter2::OBJECT_AUDIO_PARAM> for ObjectAudioParam {
12    fn from(value: &aviutl2_sys::filter2::OBJECT_AUDIO_PARAM) -> Self {
13        Self {
14            vol_l: value.vol_l,
15            vol_r: value.vol_r,
16        }
17    }
18}
19impl From<aviutl2_sys::filter2::OBJECT_AUDIO_PARAM> for ObjectAudioParam {
20    fn from(value: aviutl2_sys::filter2::OBJECT_AUDIO_PARAM) -> Self {
21        Self {
22            vol_l: value.vol_l,
23            vol_r: value.vol_r,
24        }
25    }
26}
27
28/// 音声フィルタのオブジェクト情報。
29#[derive(Debug, Clone, Copy)]
30pub struct AudioObjectInfo {
31    /// オブジェクトの現在の音声サンプル位置。
32    pub sample_index: u64,
33    /// オブジェクトの総サンプル数。
34    pub sample_total: u64,
35    /// オブジェクトの現在の音声サンプル数。
36    pub sample_num: u32,
37    /// オブジェクトの現在の音声チャンネル数。
38    /// 通常2になります。
39    pub channel_num: u32,
40}
41
42/// 音声フィルタ処理のための構造体。
43#[derive(Debug)]
44pub struct FilterProcAudio<U: super::FilterUserdata> {
45    /// シーン情報。
46    pub scene: SceneInfo,
47    /// オブジェクト情報。
48    pub object: ObjectInfo,
49    /// 音声フィルタ特有のオブジェクト情報。
50    pub audio_object: AudioObjectInfo,
51
52    /// オブジェクトの音声パラメータ。
53    ///
54    /// # Note
55    ///
56    /// このパラメータは音声出力項目のパラメータからの相対設定になります。
57    pub param: ObjectAudioParam,
58
59    /// エフェクト毎に保持されるユーザーデータ。
60    pub userdata: super::FilterUserdataHandle<U>,
61
62    pub(crate) read_section: crate::generic::ReadSection,
63    pub(crate) inner: *const aviutl2_sys::filter2::FILTER_PROC_AUDIO,
64}
65
66unsafe impl<U: super::FilterUserdata> Send for FilterProcAudio<U> {}
67unsafe impl<U: super::FilterUserdata> Sync for FilterProcAudio<U> {}
68
69#[derive(Debug, Clone, Copy, PartialEq, Eq)]
70pub enum AudioChannel {
71    Left,
72    Right,
73    Any(i32),
74}
75impl From<i32> for AudioChannel {
76    fn from(value: i32) -> Self {
77        match value {
78            0 => AudioChannel::Left,
79            1 => AudioChannel::Right,
80            v => AudioChannel::Any(v),
81        }
82    }
83}
84impl From<AudioChannel> for i32 {
85    fn from(value: AudioChannel) -> Self {
86        match value {
87            AudioChannel::Left => 0,
88            AudioChannel::Right => 1,
89            AudioChannel::Any(v) => v,
90        }
91    }
92}
93
94impl<U: super::FilterUserdata> FilterProcAudio<U> {
95    /// 可変長の汎用データ項目のサイズを変更する。
96    ///
97    /// データのread/writeガードが存在する場合は失敗します。
98    pub fn set_filter_config_data_size(
99        &self,
100        data: &mut crate::filter::VariableLengthFilterConfigDataHandle,
101        size: usize,
102    ) -> FilterProcResult<()> {
103        data.try_resize(size, |data, size| unsafe {
104            ((*self.inner).set_filter_item_data_size)(data, size);
105        })
106    }
107
108    /// 現在の音声のデータを取得する。
109    /// `channel` は 0 が左チャンネル、1 が右チャンネルです。
110    ///
111    /// # Panics
112    ///
113    /// `buffer` の長さが `sample_num` と一致しない場合、パニックします。
114    pub fn get_sample_data(&self, channel: AudioChannel, buffer: &mut [f32]) -> usize {
115        let sample_num = self.audio_object.sample_num as usize;
116        assert_eq!(
117            buffer.len(),
118            sample_num,
119            "buffer length does not match sample_num"
120        );
121        let inner = unsafe { &*self.inner };
122        unsafe { (inner.get_sample_data)(buffer.as_mut_ptr(), channel.into()) };
123        sample_num
124    }
125
126    /// 現在の音声のデータを設定する。
127    /// `channel` は 0 が左チャンネル、1 が右チャンネルです。
128    ///
129    /// # Panics
130    ///
131    /// `data` の長さが `sample_num` と一致しない場合、パニックします。
132    pub fn set_sample_data(&self, channel: AudioChannel, data: &[f32]) {
133        let sample_num = self.audio_object.sample_num as usize;
134        assert_eq!(
135            data.len(),
136            sample_num,
137            "data length does not match sample_num"
138        );
139        let inner = unsafe { &*self.inner };
140        unsafe { (inner.set_sample_data)(data.as_ptr(), channel.into()) };
141    }
142
143    /// 読み取り専用の編集セクション。
144    pub fn read_section(&self) -> &crate::generic::ReadSection {
145        &self.read_section
146    }
147
148    /// 指定オブジェクトの音声出力項目のパラメーターを取得する。
149    pub fn get_output_audio_param(
150        &self,
151        object: crate::generic::ObjectHandle,
152        offset: f64,
153    ) -> FilterProcResult<ObjectAudioParam> {
154        let inner = unsafe { &*self.inner };
155        let mut param = aviutl2_sys::filter2::OBJECT_AUDIO_PARAM {
156            vol_l: 0.0,
157            vol_r: 0.0,
158        };
159        let ok = unsafe {
160            (inner.get_output_audio_param)(
161                object.internal,
162                offset,
163                &mut param,
164                std::mem::size_of::<aviutl2_sys::filter2::OBJECT_AUDIO_PARAM>() as i32,
165            )
166        };
167        if ok {
168            Ok(param.into())
169        } else {
170            Err(FilterProcError::ApiCallFailed)
171        }
172    }
173
174    /// 指定のレイヤー位置にある音声オブジェクトを取得する。
175    pub fn get_audio_object(
176        &self,
177        layer: u32,
178        offset: f64,
179    ) -> Option<crate::generic::ObjectHandle> {
180        let handle = unsafe { ((*self.inner).get_audio_object)(layer as _, offset) };
181        if handle.is_null() {
182            None
183        } else {
184            Some(crate::generic::ObjectHandle { internal: handle })
185        }
186    }
187
188    pub(crate) fn apply_param(&self) {
189        let inner = unsafe { &mut *(*self.inner).param };
190        inner.vol_l = self.param.vol_l;
191        inner.vol_r = self.param.vol_r;
192    }
193}