A C++ library for defining and evaluating piecewise functions, inspired by the Web Audio API AudioParam interface.
NFParam should compile and run on any platform with a C++11 compiler, but the following are tested in CI.
- 📱 iOS 9.0+
- 💻 OS X 10.11+
- 🐧 Ubuntu Trusty 14.04+ (clang 3.9 or gcc 4.9)
When designing a cross platform player that could be used for complex mixing and effects, we required a library that worked in the same way that the Web Audio API AudioParam worked but on none web based platforms. This led to the creation of this library, which is not only able to emulate the AudioParam library but can also handle seeks into the centre of a function being evaluated due to its architecture not being a state machine. In addition to supporting everything AudioParam supports, we have also added in some extra goodies such as smoothedValueForTimeRange and cumulativeValueForTimeRange.
NFParam is designed as a C++11 interface to define a control curve and interact with it in real time. The API allows you to create a parameter and then begin to add control curves to execute at specific times. The library is thread safe and can be written or read from any thread. The system works by having a list of events, doing a binary search on that list to find the correct function to execute, then executing that function on the current time being requested.
CMake 3.5 or later is required to generate the build.
brew install cmakeor
sudo apt-get install cmakeNFParam is a CMake project, so to use it within a larger CMake project, simply add the following line to your CMakeLists.txt file:
add_subdirectory(NFParam)
Alternatively, you can compile NFParam as a standalone library. The ci build scripts can be used to install all necessary dependencies, build the library, and run unit tests.
sh ci/linux.sh buildsh ci/osx.sh buildSpecify the default value, min, max, and a name. Until events are added, its value will be the default value for all times.
auto p = nativeformat::param::createParam(0, 1, -1, "testParam");
The setValueAtTime command behaves as a step function.
The value specified will be maintained until the next event anchor.
p->setValueAtTime(0.2f, 0.0);
p->setValueAtTime(0.3f, 0.1);
p->setValueAtTime(0.4f, 0.2);
The linearRampToValueAtTime event computes the slope necessary to reach the target value from the previous anchor point by the specified time.
p->linearRampToValueAtTime(1.0f, 0.3);
p->linearRampToValueAtTime(0.8f, 0.325);
The setTargetAtTime command will expoenentially approach the target value from the previous anchor with a rate specified by the time constant. It does not have a fixed end time.
p->setTargetAtTime(0.5f, 0.325, time_constant);
p->setValueAtTime(0.552f, 0.5);
The exponentialRampToValueAtTime event computes the constant necessary to
reach the target value from the previous anchor point by the specified time.
p->exponentialRampToValueAtTime(0.75f, 0.6);
p->exponentialRampToValueAtTime(0.05f, 0.7);
The setValueCurveAtTime event linearly interpolates between the points provided on the user-defined curve.
It cannot overlap with any other command anchors.
size_t curve_len = 44100;
std::vector<float> curve(curve_len);
for (int i = 0; i < curve_len; ++i) {
curve[i] = std::sin((3.14159265 * i) / curve_len);
}
p->setValueCurveAtTime(curve, 0.7, 0.3);
Finally, let's sample some values from the param we have defined!
size_t points = 1001;
std::vector<float> x(points), y(points);
p->valuesForTimeRange(y.data(), points, 0.0, 1.0);
double ts = 1.0 / (points - 1);
double t = 0;
for (int i = 0; i < x.size(); ++i) {
x[i] = t;
t += ts;
}
NFParamTests.cpp contains a number of test cases,
two of which generate TSV output files that should match the
AudioParam automation example
from the WAA spec. In the resources directory, there is a script that will plot the unit test output data
if you have gnuplot installed. The path where paramAutomation.txt is generated when the tests are run by the
ci scripts varies by platform.
sh plot.sh ../build/source/test/Debug/paramAutomation.txt out.png
Contributions are welcomed, have a look at the CONTRIBUTING.md document for more information.
The project is available under the Apache 2.0 license.
- Icon in readme banner is “Settings” by Bharat from the Noun Project.