Intro
To put it simple, it's a audio effect that wraps a compiler and a texteditor into your audiostream. To elaborate a bit, it includes a dynamic compiler bridge which theoretically allows you to write in any language so long as it can provide a C bridge. The editor is based on the scintilla scilexer (e: can also use juce codeeditor now), which most of you probably know. Together with these tools and a console, it provides a small API that allows to create controls, metering tools and diagnostics.
APE's intended use is the development process - testing out and fine-tuning algorithms in an efficient manner before integrating it into your primary project. It allows for on-the-fly compilation and testing. Also, it's intended to provide a simple introduction to writing DSP code in a manner where you don't have to worry about anything but the actual relevant code. It is therefore an ideal tool for teaching/educational projects and demonstrating small algorithms and / or effects.
APE currently ships with a C compiler that, together with the API, provides a suite of tools and a system that makes it extremely easy to work with DSP-code. Here's an example 'script':
Code: Select all
#include <CInterface.h>
/*******************************************************************
* Limiter
* Written by Janus Thorborg
* Description:
* Limiting is basically a special case of
* compression, where your ratio is infinite and
* your attack is zero.
*******************************************************************/
struct PluginData
{
float threshold; // 0 .. 1
float env; // envelope follower
float release; // 0 .. 1000
};
GlobalData("limiter.c");
enum Status onLoad()
{
// set threshold to 1, this will just make sure nothing clips
self.threshold = 1.0f;
// release to 100 ms
self.release = 0.1;
// reset env
self.env = 1;
// knobs etc
api.createKnob("Treshold", &self.threshold, knobType.decibel);
api.createKnob("Release", &self.release, knobType.ms);
api.createLabel("Envelope", "%f", &self.env);
// print out starting settings
api.printLine(color.black, "Limiter loaded. Threshold: %f, release: %f",
self.threshold,
self.release);
return status.ready;
}
enum Status onUnload()
{
return status.ok;
}
enum Status processReplacing(float ** in, float ** out, int sampleFrames)
{
// amount of channels were working with
int numChannels = api.getNumInputs();
// this is our temporary sample
float sample;
// the gain we apply
float gain;
// our envelope
float env = self.env;
// our threshold
float threshold = self.threshold;
// absolute value of sample
float sampleAbs;
// how much the envelope decays each sample
// after the input volume has fallen below threshold
float decay = exp(-1.0 / (api.getSampleRate() * self.release));
// main loop
for(unsigned i = 0; i < sampleFrames; ++i) {
// loop for each channel
for(unsigned x = 0; x < numChannels; ++x) {
// catch the sample
sample = in[x][i];
// reset gain
gain = 1.0;
// calculate the absolute value of the sample (remove sign)
sampleAbs = fabs(sample);
// check if input volume is above our threshold
if(sampleAbs > threshold) {
// this is analogous to zero attack (because the envelope is
// instantly set to the input volume)
if(sampleAbs > env)
env = sampleAbs;
}
// apply gain only if volume envelope is above zero,
// else gain spins out of control
if(env > threshold)
gain = threshold/env;
// apply release to envelope if input is falling below threshold
if(sampleAbs < threshold)
env *= decay;
// lastly, gain the output sample!
out[x][i] = gain * sample;
}
}
// save the envelope variable
self.env = env;
return status.ok;
}
- resampling
additive synthesis
oscillators
oscilloscope
compressors
bit- and samplerate reduction
iir and fir filters, rms
ringmodulation & tremolo
pitch detection
About this release
I originally created this for own use in my education and for messing around in DSP code in a feasible manner. It quickly grew though, and i realized it might have potential / use for other people than me. I therefore continued to develop it to make a usable package for others.
About the code: It's a huge WIP, and to be honest, I'm not the best programmer in the world. Most of the code has to redesigned and rewritten, most have been written with the goal of getting a working product. As of such, it probably has multiple bugs and 'features', but it's now in a state where i want to share it.
APE's goal
I started doing small plugins but quickly realized it really was a hassle going through IDE's, project settings, dependencies and licenses, huge amounts of redundant code and compilations just to create a gain plugin... With this plugin, you can focus on writing that simple line:
Code: Select all
sampleOut *= self.gain;
In the long run, I really hope people enjoy this program as much as i do, and ideally, I hope people will create interesting and cool scripts so this project can develop into a library of DSP code with a working implementation (instead of scattered example/pseudo-code on the internet).
Changelog
What's new?Alpha 0.3.2: 23-04-2014Alpha 0.3.1: 14-04-2014
- Missing examples for x64 vst target on OSx
Alpha 0.3.0: 08-04-2014
- Fixed config.cfg's for windows targets; tcc should now find missing headers
Fixed a crash on host exit (directwrite disabled for now) on windowsAlpha 0.2: 10-02-2014
- Source code rewritten to support JUCE also, which is the primary target platform now.
x32 and x64 builds on both Windows and OSx as AudioUnit and VST 2.4
- this affects several things; notably the editor is switched from Scintilla to JUCE's inbuilt code editor now
this has the welcome side effect of hotkeys working again
syntax highlight only for C++ and friends for the moment.
Countless bug fixes / code rewrite
project recall now implemented
autosave now implemented
support for high dpi display
an actual threading- and multi-instance model is now implemented; it should be completely safe to run multiple plugins in the same or other processes
fix of fpu exceptions
improved header support for other compilers than tcc
improved graphics on some points, degraded on othersAlpha 0.1
- fixed uninitialized variable 'Engine::clocksPerSample'
scilexer now properly adds filenames to project struct even in case of singleString-compilation
scilexer now properly sets amount of files in the project
the console should now properly print strings with linebreaks in them, this affects the core, api and scripts.
fixed a bug where newlines will crash the console code.
output logging of console now properly contains newlines.
due to larger amounts of info being printed to the console, it is now scrollable and has a longer history
added new compiler: syswrap. syswrap allows to interface to installed system compilers.
fixed a bug where closing the editor would not reset the editor button in APE
pressing the editor button now properly restores the window if user had minimized it before
fixed a memory leak in the TCC compiler (early return caused no deallocation of plugin data)
fixed a wrong return value in CInterface.h
added a new knob function: api.createRangeKnob(). This knob formats it's display value based off a minimum, maximum and a callback function.
fixed a bug where knobs initially would have the wrong format
to enhance c++ compability, 'this' is now an illegal identifier
CInterface.h:
- added new valuestruct: scale
added f_mod() and f_sin()
added pi values
compatized header with various compilers
updated the example scripts to reflect these changes.
- Initial release.
The 0.3 release marks a complete overhaul of the program. Notably crossplatform support with both 32-bit and 64-bit, but also focus on making APE into a working plugin. Features that support this are project recall mostly, but improved saving and autosave is probably a welcomed feature.
Vast amounts of bugs have been eliminated, mostly cause of using proper threading safety and static data security. However, I'm still new to developing with both JUCE and OSx, so dont expect it to be bug free I will continue to work on it, of course.
I hope you enjoy this version, it for sure took a while to create.
Known bugs / peculiarities / missing stuff
Last words
- The transition to JUCE has brought along a pretty massive CPU load when rendering the graphics (mostly due to some weird osx redrawing of png's). This can be remedied by modifying the config.cfg. I'm trying to fix it, though. It is only a problem when the GUI is showing
Some 32-bit hosts on OSX have shown some hanging behaviour on exit, however it might be the hosts - unfortunately, i dont have a suite of 32-bit hosts to test the plugin with on osx
syswrap is not yet available on OSx, I'm working on it.
TCC has a hard time coping with system headers on OSX, if you experience problems prefix system includes with tcc: #include <tcc/stdio.h>
Legacy OSx support: I only have 10.8 atm, but it should work for 10.7 (i think? maybe lower) - im keeping an eye on it
If ape is initiated, but the editor never is opened, project recall will cause the message "Cannot open file 'Untitled'" to appear.
It could be so cool to create a community project out of this, as of such all of my code is released open-source under GPL 3 (and the whole package is free, of course) - it's in the package. I'm inviting everyone to contribute to the project with ideas / code examples for the library, whatever really. Helping out writing on the plugin itself is very welcomed, I don't have much time myself (full time studies, other projects etc.).
I hope you take some time to check out the project
Notes
I'm not sure if this is the right forum (or if you're even allowed to post your plugins), but this is IMO definitely where i think it belongs (as a tool for DSP and plugin development) - but please move it or contact me if anything is wrong.
Download link
Version 0.3 download link (Mac OSX + Windows 32/64bit VST + AudioUnit)
Version 0.2 download link (Windows 32-bit VST)
Version 0.1 download link (Windows 32-bit VST)