39个版本 (12个重大变更)
0.12.0 | 2023年8月3日 |
---|---|
0.11.0 | 2023年2月25日 |
0.10.0 | 2023年1月31日 |
0.9.0 | 2022年12月22日 |
0.4.0 | 2020年7月29日 |
#157 in GUI
每月105次下载
用于 6 个crate(2个直接使用)
410KB
9K SLoC
Iced Audio
Iced GUI库的扩展,为VST / LV2插件等音频应用程序提供了有用的控件。
实现的控件
输入
-
HSlider
- 水平滑块 -
VSlider
- 垂直滑块 -
Knob
- 经典的旋钮控件。(暂无纹理样式) -
Ramp
- 用于控制两个时间点之间缓动的斜坡 -
XYPad
- XY垫,用于同时控制两个参数 -
ModRangeInput
- 用于控制参数调制范围的点。为HSlider
,VSlider
和Knob
控件存在添加视觉反馈的样式。
查看路线图以获取计划中的控件列表。
每个参数都可以映射到四个范围之一
FloatRange
- f32值的线性范围IntRange
- i32值的离散范围。这将导致控件在移动时“步进”。LogDBRange
- 分贝值的对数范围。围绕0 dB的值将比远离0 dB的值增加得更慢。FreqRange
- 频率值的对数范围。10个八度音阶频谱(从20 Hz到20480 Hz)均匀分布。
使用以下方式运行示例
cargo run --package inputs_tour --release
cargo run --package simple --release
安装
在您的 Cargo.toml
中将 iced_audio
添加为依赖项
iced_audio = "0.8"
或者如果您想使用GitHub上的iced
版本
iced_audio = { git = "https://github.com/iced-rs/iced_audio", branch = "iced_git" }
Both Iced Audio和Iced发展迅速,main
和iced_git
分支可能包含重大更改!如果您想了解特定版本的信息,请查看版本列表。
简单使用示例
本crate假设您已了解如何使用Iced。如果您还没有,请在此查看。
// Import iced modules.
use iced::widget::{column, container, text};
use iced::{Alignment, Element, Length, Sandbox, Settings};
// Import iced_audio modules.
use iced_audio::{
tick_marks, FloatRange, FreqRange, HSlider, IntRange, Knob, LogDBRange,
Normal, NormalParam, VSlider, XYPad,
};
// The message when a parameter widget is moved by the user
#[derive(Debug, Clone)]
pub enum Message {
HSliderInt(Normal),
VSliderDB(Normal),
KnobFreq(Normal),
XYPadFloat(Normal, Normal),
}
pub fn main() {
App::run(Settings::default()).unwrap();
}
pub struct App {
// The ranges handle converting the input/output of a parameter to and from
// a usable value.
//
// There are 4 built-in options available for a range:
//
// * FloatRange - a linear range of f32 values
// * IntRange - a discrete range of i32 values. This will cause the widget
// to "step" when moved.
// * LogDBRange - a logarithmic range of decibel values. Values around 0 dB
// will increment slower than values farther away from 0 dB.
// * FreqRange - a logarithmic range of frequency values. Each octave in
// the 10 octave spectrum (from 20 Hz to 20480 Hz) is spaced evenly.
//
float_range: FloatRange,
int_range: IntRange,
db_range: LogDBRange,
freq_range: FreqRange,
// The states of the widgets that will control the parameters.
h_slider_param: NormalParam,
v_slider_param: NormalParam,
knob_param: NormalParam,
xy_pad_x_param: NormalParam,
xy_pad_y_param: NormalParam,
// A group of tick marks with their size and position.
center_tick_mark: tick_marks::Group,
output_text: String,
}
impl Sandbox for App {
type Message = Message;
fn new() -> App {
// Initalize each range:
let float_range = FloatRange::default_bipolar();
let int_range = IntRange::new(0, 10);
let db_range = LogDBRange::new(-12.0, 12.0, 0.5.into());
let freq_range = FreqRange::default();
App {
// Add the ranges.
float_range,
int_range,
db_range,
freq_range,
// Initialize the state of the widgets with a normalized parameter
// that has a value and a default value.
h_slider_param: int_range.normal_param(5, 5),
v_slider_param: db_range.default_normal_param(),
knob_param: freq_range.normal_param(1000.0, 1000.0),
xy_pad_x_param: float_range.default_normal_param(),
xy_pad_y_param: float_range.default_normal_param(),
// Add a tick mark at the center position with the tier 2 size
center_tick_mark: tick_marks::Group::center(tick_marks::Tier::Two),
output_text: "Move a widget!".into(),
}
}
fn title(&self) -> String {
format!("Simple Example - Iced Audio")
}
fn update(&mut self, event: Message) {
match event {
// Retrieve the value by mapping the normalized value of the parameter
// to the corresponding range.
//
// Now do something useful with that value!
Message::HSliderInt(normal) => {
// Integer parameters must be snapped to make the widget "step" when moved.
self.h_slider_param.update(self.int_range.snapped(normal));
let value = self.int_range.unmap_to_value(normal);
self.output_text = format!("HSliderInt: {}", value);
}
Message::VSliderDB(normal) => {
self.v_slider_param.update(normal);
let value = self.db_range.unmap_to_value(normal);
self.output_text = format!("VSliderDB: {:.3}", value);
}
Message::KnobFreq(normal) => {
self.knob_param.update(normal);
let value = self.freq_range.unmap_to_value(normal);
self.output_text = format!("KnobFreq: {:.2}", value);
}
Message::XYPadFloat(normal_x, normal_y) => {
self.xy_pad_x_param.update(normal_x);
self.xy_pad_y_param.update(normal_y);
let value_x = self.float_range.unmap_to_value(normal_x);
let value_y = self.float_range.unmap_to_value(normal_y);
self.output_text =
format!("XYPadFloat: x: {:.2}, y: {:.2}", value_x, value_y);
}
}
}
fn view(&self) -> Element<Message> {
// Create each parameter widget, passing in the current state of the widget.
let h_slider_widget =
HSlider::new(self.h_slider_param, Message::HSliderInt)
// Add the tick mark group to this widget.
.tick_marks(&self.center_tick_mark);
let v_slider_widget =
VSlider::new(self.v_slider_param, Message::VSliderDB)
.tick_marks(&self.center_tick_mark);
let knob_widget =
Knob::new(self.knob_param, Message::KnobFreq, || None, || None);
let xy_pad_widget = XYPad::new(
self.xy_pad_x_param,
self.xy_pad_y_param,
Message::XYPadFloat,
);
// Push the widgets into the iced DOM
let content = column![
h_slider_widget,
v_slider_widget,
knob_widget,
xy_pad_widget,
container(text(&self.output_text)).width(Length::Fill),
]
.max_width(300)
.spacing(20)
.padding(20)
.align_items(Alignment::Center);
container(content)
.max_height(500)
.width(Length::Fill)
.height(Length::Fill)
.center_x()
.center_y()
.into()
}
}
VST / LV2 / AU 插件
如果您希望使用iced_audio为音频插件,请查看我的其他仓库。
请注意,这些是实验性的,目前缺少许多功能。
iced_baseview
- 使用baseview
作为后端运行Iced。iced-baseplug-examples
- 使用baseplug
作为插件包装器、iced_baseview
作为GUI后端和iced_audio小部件的示例音频插件。
贡献/反馈
非常感谢您的贡献!如果您想贡献,请阅读官方Iced 贡献指南以获取更多详细信息。
也欢迎反馈!您可以打开一个问题,或者如果您想交谈,来我们的Discord服务器聊天。此外,您可以在Rust社区Discord的#gui-and-ui
频道中找到我(以及一群很棒的伙伴)。我在那里的ID是BillyDM#3892
。
依赖项
~11–43MB
~750K SLoC