| @@ -12,6 +12,7 @@ namespace rack { | |||||
| namespace dsp { | namespace dsp { | ||||
| /** Resamples by a fixed rational factor. */ | |||||
| template<int CHANNELS> | template<int CHANNELS> | ||||
| struct SampleRateConverter { | struct SampleRateConverter { | ||||
| SpeexResamplerState *st = NULL; | SpeexResamplerState *st = NULL; | ||||
| @@ -101,6 +102,7 @@ struct SampleRateConverter { | |||||
| }; | }; | ||||
| /** Downsamples by an integer factor. */ | |||||
| template<int OVERSAMPLE, int QUALITY> | template<int OVERSAMPLE, int QUALITY> | ||||
| struct Decimator { | struct Decimator { | ||||
| float inBuffer[OVERSAMPLE*QUALITY]; | float inBuffer[OVERSAMPLE*QUALITY]; | ||||
| @@ -135,6 +137,7 @@ struct Decimator { | |||||
| }; | }; | ||||
| /** Upsamples by an integer factor. */ | |||||
| template<int OVERSAMPLE, int QUALITY> | template<int OVERSAMPLE, int QUALITY> | ||||
| struct Upsampler { | struct Upsampler { | ||||
| float inBuffer[QUALITY]; | float inBuffer[QUALITY]; | ||||
| @@ -15,21 +15,21 @@ struct Engine { | |||||
| Engine(); | Engine(); | ||||
| ~Engine(); | ~Engine(); | ||||
| /** Starts engine thread */ | |||||
| /** Starts engine thread. */ | |||||
| void start(); | void start(); | ||||
| /** Stops engine thread */ | |||||
| /** Stops engine thread. */ | |||||
| void stop(); | void stop(); | ||||
| void setThreadCount(int threadCount); | void setThreadCount(int threadCount); | ||||
| int getThreadCount(); | int getThreadCount(); | ||||
| void setPaused(bool paused); | void setPaused(bool paused); | ||||
| bool isPaused(); | bool isPaused(); | ||||
| /** Does not transfer pointer ownership */ | |||||
| /** Does not transfer pointer ownership. */ | |||||
| void addModule(Module *module); | void addModule(Module *module); | ||||
| void removeModule(Module *module); | void removeModule(Module *module); | ||||
| void resetModule(Module *module); | void resetModule(Module *module); | ||||
| void randomizeModule(Module *module); | void randomizeModule(Module *module); | ||||
| void bypassModule(Module *module, bool bypass); | void bypassModule(Module *module, bool bypass); | ||||
| /** Does not transfer pointer ownership */ | |||||
| /** Does not transfer pointer ownership. */ | |||||
| void addCable(Cable *cable); | void addCable(Cable *cable); | ||||
| void removeCable(Cable *cable); | void removeCable(Cable *cable); | ||||
| void setParam(Module *module, int paramId, float value); | void setParam(Module *module, int paramId, float value); | ||||
| @@ -7,11 +7,12 @@ namespace engine { | |||||
| struct Light { | struct Light { | ||||
| /** The mean-square of the brightness | |||||
| /** The mean-square of the brightness. | |||||
| Unstable API. Use set/getBrightness(). | Unstable API. Use set/getBrightness(). | ||||
| */ | */ | ||||
| float value = 0.f; | float value = 0.f; | ||||
| /** Sets the brightness directly with no LED modeling. */ | |||||
| void setBrightness(float brightness) { | void setBrightness(float brightness) { | ||||
| value = (brightness > 0.f) ? std::pow(brightness, 2) : 0.f; | value = (brightness > 0.f) ? std::pow(brightness, 2) : 0.f; | ||||
| } | } | ||||
| @@ -21,7 +22,8 @@ struct Light { | |||||
| } | } | ||||
| /** Emulates slow fall (but immediate rise) of LED brightness. | /** Emulates slow fall (but immediate rise) of LED brightness. | ||||
| `frames` rescales the timestep. For example, if your module calls this method every 16 frames, use 16.f. | |||||
| `frames` rescales the timestep. | |||||
| For example, if your module calls this method every 16 frames, use 16.f. | |||||
| */ | */ | ||||
| void setBrightnessSmooth(float brightness, float frames = 1.f) { | void setBrightnessSmooth(float brightness, float frames = 1.f) { | ||||
| float v = (brightness > 0.f) ? std::pow(brightness, 2) : 0.f; | float v = (brightness > 0.f) ? std::pow(brightness, 2) : 0.f; | ||||
| @@ -13,42 +13,44 @@ namespace engine { | |||||
| struct Module { | struct Module { | ||||
| /** Automatically generated by the engine. */ | |||||
| int id = 0; | int id = 0; | ||||
| std::vector<Param> params; | std::vector<Param> params; | ||||
| std::vector<Output> outputs; | std::vector<Output> outputs; | ||||
| std::vector<Input> inputs; | std::vector<Input> inputs; | ||||
| std::vector<Light> lights; | std::vector<Light> lights; | ||||
| /** For power meter */ | |||||
| /** For CPU meter. */ | |||||
| float cpuTime = 0.f; | float cpuTime = 0.f; | ||||
| bool bypass = false; | bool bypass = false; | ||||
| /** Constructs a Module with no params, inputs, outputs, and lights */ | |||||
| /** Constructs a Module with no params, inputs, outputs, and lights. */ | |||||
| Module(); | Module(); | ||||
| /** Deprecated. Use config() instead. */ | |||||
| /** Use config() instead. */ | |||||
| DEPRECATED Module(int numParams, int numInputs, int numOutputs, int numLights = 0) : Module() { | DEPRECATED Module(int numParams, int numInputs, int numOutputs, int numLights = 0) : Module() { | ||||
| config(numParams, numInputs, numOutputs, numLights); | config(numParams, numInputs, numOutputs, numLights); | ||||
| } | } | ||||
| virtual ~Module() {} | virtual ~Module() {} | ||||
| /** Configures the number of Params, Outputs, Inputs, and Lights. */ | |||||
| void config(int numParams, int numInputs, int numOutputs, int numLights = 0); | void config(int numParams, int numInputs, int numOutputs, int numLights = 0); | ||||
| json_t *toJson(); | json_t *toJson(); | ||||
| void fromJson(json_t *rootJ); | void fromJson(json_t *rootJ); | ||||
| void reset(); | void reset(); | ||||
| void randomize(); | void randomize(); | ||||
| /** Advances the module by 1 audio frame with duration 1.0 / gSampleRate | |||||
| Override this method to read inputs and params, and to write outputs and lights. | |||||
| /** Advances the module by one audio sample. | |||||
| Override this method to read Inputs and Params, and to write Outputs and Lights. | |||||
| */ | */ | ||||
| virtual void step() {} | virtual void step() {} | ||||
| /** Called when the engine sample rate is changed */ | |||||
| /** Called when the engine sample rate is changed. */ | |||||
| virtual void onSampleRateChange() {} | virtual void onSampleRateChange() {} | ||||
| /** Called when user clicks Initialize in the module context menu */ | |||||
| /** Called when user clicks Initialize in the module context menu. */ | |||||
| virtual void onReset() {} | virtual void onReset() {} | ||||
| /** Called when user clicks Randomize in the module context menu */ | |||||
| /** Called when user clicks Randomize in the module context menu. */ | |||||
| virtual void onRandomize() {} | virtual void onRandomize() {} | ||||
| /** Override these to store extra internal data in the "data" property of the module's JSON object */ | |||||
| /** Override to store extra internal data in the "data" property of the module's JSON object. */ | |||||
| virtual json_t *dataToJson() { return NULL; } | virtual json_t *dataToJson() { return NULL; } | ||||
| virtual void dataFromJson(json_t *root) {} | virtual void dataFromJson(json_t *root) {} | ||||
| }; | }; | ||||
| @@ -22,30 +22,33 @@ struct ParamQuantityFactory { | |||||
| struct Param { | struct Param { | ||||
| /** Unstable API. Use set/getValue() instead. */ | |||||
| /** Unstable API. Use setValue() and getValue() instead. */ | |||||
| float value = 0.f; | float value = 0.f; | ||||
| /** The minimum allowed value. */ | |||||
| float minValue = 0.f; | float minValue = 0.f; | ||||
| /** The maximum allowed value. Must be greater than minValue. */ | |||||
| float maxValue = 1.f; | float maxValue = 1.f; | ||||
| /** The initial value. */ | |||||
| float defaultValue = 0.f; | float defaultValue = 0.f; | ||||
| /** The name of the parameter in sentence capitalization | |||||
| /** The name of the parameter, using sentence capitalization. | |||||
| e.g. "Frequency", "Pulse width", "Alternative mode" | e.g. "Frequency", "Pulse width", "Alternative mode" | ||||
| */ | */ | ||||
| std::string label; | std::string label; | ||||
| /** The numerical unit of measurement | |||||
| /** The numerical unit of measurement appended to the value. | |||||
| Use a space before non-abbreviations to separate the numerical value. | Use a space before non-abbreviations to separate the numerical value. | ||||
| e.g. " semitones", "Hz", "%", "V" | e.g. " semitones", "Hz", "%", "V" | ||||
| */ | */ | ||||
| std::string unit; | std::string unit; | ||||
| /** Set to 0 for linear, nonzero for exponential */ | |||||
| /** Set to 0 for linear, nonzero for exponential. */ | |||||
| float displayBase = 0.f; | float displayBase = 0.f; | ||||
| float displayMultiplier = 1.f; | float displayMultiplier = 1.f; | ||||
| float displayOffset = 0.f; | float displayOffset = 0.f; | ||||
| /** An optional one-sentence description of the parameter */ | |||||
| /** An optional one-sentence description of the parameter. */ | |||||
| std::string description; | std::string description; | ||||
| ParamQuantityFactory *paramQuantityFactory = NULL; | ParamQuantityFactory *paramQuantityFactory = NULL; | ||||
| /** Determines whether this param will be randomized automatically when the user requests to randomize the module state */ | |||||
| /** Determines whether this Param will be randomized when the user requests to randomize the Module. */ | |||||
| bool randomizable = true; | bool randomizable = true; | ||||
| ~Param() { | ~Param() { | ||||
| @@ -82,6 +85,7 @@ struct Param { | |||||
| this->value = math::clamp(value, minValue, maxValue); | this->value = math::clamp(value, minValue, maxValue); | ||||
| } | } | ||||
| /** Returns whether the Param has finite range between minValue and maxValue. */ | |||||
| bool isBounded(); | bool isBounded(); | ||||
| json_t *toJson(); | json_t *toJson(); | ||||
| void fromJson(json_t *rootJ); | void fromJson(json_t *rootJ); | ||||
| @@ -13,7 +13,7 @@ static const int PORT_MAX_CHANNELS = 16; | |||||
| struct Port { | struct Port { | ||||
| /** Voltage of the port. */ | /** Voltage of the port. */ | ||||
| union { | union { | ||||
| /** Unstable API. Use set/getVoltage() instead. */ | |||||
| /** Unstable API. Use getVoltage() and setVoltage() instead. */ | |||||
| float voltages[PORT_MAX_CHANNELS] = {}; | float voltages[PORT_MAX_CHANNELS] = {}; | ||||
| /** DEPRECATED. Unstable API. Use getVoltage() and setVoltage() instead. */ | /** DEPRECATED. Unstable API. Use getVoltage() and setVoltage() instead. */ | ||||
| float value; | float value; | ||||
| @@ -26,7 +26,7 @@ struct Port { | |||||
| /** Unstable API. Use isConnected() instead. */ | /** Unstable API. Use isConnected() instead. */ | ||||
| bool active; | bool active; | ||||
| /** For rendering plug lights on cables. | /** For rendering plug lights on cables. | ||||
| Green for positive, red for negative, and blue for polyphonic | |||||
| Green for positive, red for negative, and blue for polyphonic. | |||||
| */ | */ | ||||
| Light plugLights[3]; | Light plugLights[3]; | ||||
| @@ -55,6 +55,7 @@ struct Port { | |||||
| return isConnected() ? getPolyVoltage(channel) : normalVoltage; | return isConnected() ? getPolyVoltage(channel) : normalVoltage; | ||||
| } | } | ||||
| /** Sets the number of polyphony channels. */ | |||||
| void setChannels(int channels) { | void setChannels(int channels) { | ||||
| // Set higher channel voltages to 0 | // Set higher channel voltages to 0 | ||||
| for (int c = channels; c < this->channels; c++) { | for (int c = channels; c < this->channels; c++) { | ||||
| @@ -67,12 +68,16 @@ struct Port { | |||||
| return channels; | return channels; | ||||
| } | } | ||||
| /** Returns if a cable is connected to the Port. | |||||
| You can use this for skipping code that generates output voltages. | |||||
| */ | |||||
| bool isConnected() { | bool isConnected() { | ||||
| return active; | return active; | ||||
| } | } | ||||
| void step(); | void step(); | ||||
| /** Use getNormalVoltage() instead. */ | |||||
| DEPRECATED float normalize(float normalVoltage) { | DEPRECATED float normalize(float normalVoltage) { | ||||
| return getNormalVoltage(normalVoltage); | return getNormalVoltage(normalVoltage); | ||||
| } | } | ||||