如何在JUCE中优雅地使用APVTS管理你的参数
前言
阅读此教程需要一定的C++和JUCE基础。
我的Bilibili频道:香芋派Taro
我的个人博客:taropie0224.github.io
我的公众号:香芋派的烘焙坊
我的音频技术交流群:1136403177
我的个人微信:JazzyTaroPie
其实我一直觉得JUCE官方做的教程很烂…官网上的tutorial甚至还是在用xml做参数存储,目前最常用的apvts连一个影子都没见着,所以在这里整理一下。
新建一个Plugin模版
PluginProcessor.h
在public中添加以下成员函数:
1 | public: |
PluginProcessor.cpp
总共有四种参数类型,分别是int, float, bool和choice
AudioParameterFloat
写法一
1 | juce::AudioProcessorValueTreeState::ParameterLayout yourPluginsNameAudioProcessor::createParameterLayout() |
你肯定注意到了AudioParameterFloat这个函数,官方doc中的定义如下:
- parameterID
极为重要,它代表了你准备定义的这个参数的身份证,无论是在外面调用这个数据,还是在后面设计sliderAttachment跟slider绑定都需要用到它。 - parameterName
顾名思义啦 - NormalisableRange
他也有四个参数,分别是最小值、最大值、变动范围精度、斜率、(其实还有第五个,就是是否反对称,反正我是没用过这个)。注意都是float。 - defaultValue
参数的默认值 - parameterLabel
一般直接使用String(),如果你想给参数加上单位的话,可以用”Hz”这样的写法代替 - parameterCategory
一般直接使用AudioProcessorParameter::genericParameter - stringFromValue
一个lambda表达式,可以把值转化成字符串并定义字符串的最大长度,用于在界面上显示参数的值。 - valueFromString
一个lambda表达式,可以把字符串转化成值,用于让用户输入。
举个例子:
1 | layout.add (std::make_unique<juce::AudioParameterFloat> ("Room Size", |
这是混响中RoomSize参数的一个例子,其中,最小值为0,最大值为1,变动范围精度为0.001,斜率为1,默认值为0.5。
你会发现使用了stringFromValue的一个lambda表达式,这里解释一下用意。 由于参数在设计时时准备用百分比表示的,所以先乘上100。然后会比较是个位数还是两位数,如果是个位数的话就显示小数点后两位,十位数的话就显示小数点后一位。这样能保持数值总体的长度不变,是一个保持美观的小细节。
写法二
这种写法较为简单,也是最常用的写法,只需要五个参数,分别是ID,Name,最小值,最大值和默认值。
举个例子
1 | layout.add (std::make_unique<juce::AudioParameterFloat> ("Room Size", |
AudioParameterInt
基本与float的写法一相同,只是所有的float都变成了int,这里略过
AudioParameterChoice
JUCE的官方doc中定义如下:
其实也基本大同小异,直接举个例子看吧:
1 | layout.add (std::make_unique<juce::AudioParameterChoice> ("OSC", "Oscillator", juce::StringArray { "Sine", "Saw", "Square" }, 0)); |
以振荡器为例,这里列出了三种波形的选项,以及默认的波形为0,就是数组中的第一个,即Sine正弦波。
AudioParameterBool
JUCE的官方doc中定义如下:
多用于配合botton使用,举个例子,混响中的freeze开关:
1 | layout.add (std::make_unique<juce::AudioParameterBool> ("Freeze", "Freeze", false)); |
与组件的绑定
AudioParameterFloat/AudioParameterInt
以Gain效果器为例,在Plugin.h中的private部分创建slider和对应的attachment:
1 | juce::Slider gainSlider; |
在Plugin.cpp中的构造函数中完成绑定(最后一行):
1 | gainSlider.setSliderStyle(juce::Slider::SliderStyle::LinearHorizontal); |
其中用到的函数是juce::AudioProcessorValueTreeState::SliderAttachment,里面的三个参数分别是你创建的APVTS名称,parameterID和需要绑定的slider的名称。
AudioParameterChoice
以Osc选择为例,在Plugin.h中的private部分创建ComboBox和对应的attachment:
1 | juce::ComboBox oscSelector; |
在Plugin.cpp中的构造函数中完成绑定:
1 | juce::StringArray oscChoices { "Sine", "Saw", "Square" }; |
AudioParameterBool
以reverb中的freeze button选择为例,在Plugin.h中的private部分创建TextButton/ToggleButton和对应的attachment:
1 | juce::TextButton freezeButton; |
在Plugin.cpp中的构造函数中完成绑定:
freezeAttachment = std::make_unique<juce::AudioProcessorValueTreeState::ButtonAttachment>(apvts, "Freeze", freezeButton);