From 334cdcee2f34090992724a0dfb106781d86c9136 Mon Sep 17 00:00:00 2001 From: Scott Olsen Date: Sat, 29 Apr 2023 14:09:26 -0400 Subject: [PATCH] c-api: add c bindings for ctrl.h Defines an initial potential C API wrapping the underlying CPP objects for AnalogControl. This commit is primarily a proof-of-concept to illustrate how we might achieve this for other elements of the library. --- src/hid/ctrl.cpp | 63 ++++++++++++++++- src/hid/ctrl.h | 176 +++++++++++++++++++++++++++++++++++++---------- 2 files changed, 198 insertions(+), 41 deletions(-) diff --git a/src/hid/ctrl.cpp b/src/hid/ctrl.cpp index a9662be40..16fceb537 100644 --- a/src/hid/ctrl.cpp +++ b/src/hid/ctrl.cpp @@ -4,7 +4,7 @@ #define BOTTOM_THRESH 0.002f using namespace daisy; -void AnalogControl::Init(uint16_t *adcptr, +void AnalogControl::Init(uint16_t* adcptr, float sr, bool flip, bool invert, @@ -22,7 +22,7 @@ void AnalogControl::Init(uint16_t *adcptr, slew_seconds_ = slew_seconds; } -void AnalogControl::InitBipolarCv(uint16_t *adcptr, float sr) +void AnalogControl::InitBipolarCv(uint16_t* adcptr, float sr) { val_ = 0.0f; raw_ = adcptr; @@ -51,4 +51,61 @@ void AnalogControl::SetSampleRate(float sample_rate) samplerate_ = sample_rate; float slew = is_bipolar_ ? .002f : slew_seconds_; SetCoeff(1.0f / (slew * samplerate_ * 0.5f)); -} \ No newline at end of file +} + +extern "C" dsy_analog_ctrl* dsy_ctrl_new() +{ + return (dsy_analog_ctrl*)static_cast(new AnalogControl()); +} + +extern "C" void dsy_ctrl_destroy(dsy_analog_ctrl* ctrl) +{ + delete static_cast((void*)ctrl); +} + +extern "C" void dsy_ctrl_init(dsy_analog_ctrl* ctrl, + uint16_t* adcptr, + float sr, + bool flip, + bool invert, + float slew_seconds) +{ + static_cast((void*)ctrl) + ->Init(adcptr, sr, flip, invert, slew_seconds); +} + +extern "C" void +dsy_init_bipolar_cv(dsy_analog_ctrl* ctrl, uint16_t* adcptr, float sr) +{ + static_cast((void*)ctrl)->InitBipolarCv(adcptr, sr); +} + +extern "C" float dsy_ctrl_process(dsy_analog_ctrl* ctrl) +{ + return static_cast((void*)ctrl)->Process(); +} + +extern "C" float dsy_ctrl_value(dsy_analog_ctrl* ctrl) +{ + return static_cast((void*)ctrl)->Value(); +} + +extern "C" void dsy_ctrl_set_coeff(dsy_analog_ctrl* ctrl, float val) +{ + return static_cast((void*)ctrl)->SetCoeff(val); +} + +extern "C" uint16_t dsy_ctrl_get_raw_value(dsy_analog_ctrl* ctrl) +{ + return static_cast((void*)ctrl)->GetRawValue(); +} + +extern "C" float dsy_ctrl_get_raw_float(dsy_analog_ctrl* ctrl) +{ + return static_cast((void*)ctrl)->GetRawFloat(); +} + +extern "C" void dsy_ctrl_set_sample_rate(dsy_analog_ctrl* ctrl, float sr) +{ + static_cast((void*)ctrl)->SetSampleRate(sr); +} diff --git a/src/hid/ctrl.h b/src/hid/ctrl.h index b915bc830..78182b3d0 100644 --- a/src/hid/ctrl.h +++ b/src/hid/ctrl.h @@ -7,13 +7,13 @@ namespace daisy { /** - @brief Hardware Interface for control inputs \n - Primarily designed for ADC input controls such as \n - potentiometers, and control voltage. \n - @author Stephen Hensley - @date November 2019 - @ingroup controls -*/ + * @brief Hardware Interface for control inputs \n + * Primarily designed for ADC input controls such as \n + * potentiometers, and control voltage. \n + * @author Stephen Hensley + * @date November 2019 + * @ingroup controls + */ class AnalogControl { public: @@ -23,63 +23,81 @@ class AnalogControl ~AnalogControl() {} /** - Initializes the control - \param *adcptr is a pointer to the raw adc read value -- This can be acquired with dsy_adc_get_rawptr(), or dsy_adc_get_mux_rawptr() - \param sr is the samplerate in Hz that the Process function will be called at. - \param flip determines whether the input is flipped (i.e. 1.f - input) or not before being processed.1 - \param invert determines whether the input is inverted (i.e. -1.f * input) or note before being processed. - \param slew_seconds is the slew time in seconds that it takes for the control to change to a new value. - */ - void Init(uint16_t *adcptr, + * Initializes an AnalogControl. + * + * @param adcptr a pointer to the raw ADC read value. This can be acquired with dsy_adc_get_rawptr() or dsy_adc_get_mux_rawptr() + * @param sr the samplerate in Hz that the AnalogControl::Process function will be called at. + * @param flip determines whether the input is flipped (i.e. 1.f - input) or not before being processed.1 + * @param invert determines whether the input is inverted (i.e. -1.f * input) or note before being processed. + * @param slew_seconds is the slew time in seconds that it takes for the control to change to a new value. + */ + void Init(uint16_t* adcptr, float sr, bool flip = false, bool invert = false, float slew_seconds = 0.002f); /** - This Initializes the AnalogControl for a -5V to 5V inverted input - All of the Init details are the same otherwise - \param *adcptr Pointer to analog digital converter - \param sr Audio engine sample rate - */ - void InitBipolarCv(uint16_t *adcptr, float sr); + * Initializes an AnalogControl to handle -5V to 5V inverted input. + * + * All other aspects of the initialization are the same as those of + * AnalogControl::Init. + * + * @param *adcptr Pointer to analog digital converter + * @param sr Audio engine sample rate + */ + void InitBipolarCv(uint16_t* adcptr, float sr); /** - Filters, and transforms a raw ADC read into a normalized range. - this should be called at the rate of specified by samplerate at Init time. - Default Initializations will return 0.0 -> 1.0 - Bi-polar CV inputs will return -1.0 -> 1.0 - */ + * Filters, and transforms a raw ADC read into a normalized range. + * + * This method should be called at the rate specified when intiailizing the + * control with AnalogControl::Init or AnalogControl::InitBipolarCv. + * + * If the control was initialized with AnalogControl::Init, this method + * returns values in the range [0.0, 1.0], inclusive. + * + * If the conrol was initialized with AnalogControl::InitBipolarCv, this + * method returns values in the range [-1.0, 1.0], inclusive. + */ float Process(); - /** Returns the current stored value, without reprocessing */ + /** + * Returns the value currently stored by the AnalogControl, without + * reprocessing. + */ inline float Value() const { return val_; } - /** Directly set the Coefficient of the one pole smoothing filter. - \param val Value to set coefficient to. Max of 1, min of 0. - */ - // using conditionals since clamp() is unavailable + /** Sets the coefficient of the one pole smoothing filter. + * + * @param val value to set coefficient to, must be in the range [0.0, 1.0], inclusive. + */ inline void SetCoeff(float val) { + // using conditionals since clamp() is unavailable val = val > 1.f ? 1.f : val; val = val < 0.f ? 0.f : val; coeff_ = val; } - /** Returns the raw unsigned 16-bit value from the ADC */ + /** Returns the raw unsigned 16-bit value from the ADC. */ inline uint16_t GetRawValue() { return *raw_; } /** Returns a normalized float value representing the current ADC value. */ inline float GetRawFloat() { return (float)(*raw_) / 65535.f; } - /** Set a new sample rate after the ctrl has been initialized - * \param sample_rate New update rate for the switch in hz - */ + /** + * Sets a new sampling rate for an AnalogControl after the control has + * already been initialized via AnalogControl::Init or + * AnalogControl::InitBipolarCv. + * + * @param sample_rate New update rate for the switch in hz + */ void SetSampleRate(float sample_rate); private: - uint16_t *raw_; + uint16_t* raw_; float coeff_, samplerate_, val_; float scale_, offset_; bool flip_; @@ -88,5 +106,87 @@ class AnalogControl float slew_seconds_; }; } // namespace daisy -#endif -#endif +#endif // __cplusplus + +// C API: +typedef struct dsy_analog_ctrl {}dsy_analog_ctrl; + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + /** Returns a new analog control. + * + * This function is a wrapper for AnalogControl::AnalogControl. + */ + dsy_analog_ctrl* dsy_ctrl_new(); + + /** + * Destroy a control, freeing associated memory. + * + * This function is a wrapper for AnalogControl::~AnalogControl. + */ + void dsy_ctrl_destroy(dsy_analog_ctrl* ctrl); + + /** + * Initializes an analog control. + * + * This function is a wrapper for AnalogControl::Init. + */ + void dsy_ctrl_init(dsy_analog_ctrl* ctrl, + uint16_t* adcptr, + float sr, + bool flip, + bool invert, + float slew_seconds); + /** + * Initializes an analog control for inverted input. + * + * This function is a wrapper for AnalogControl::InitBipolarCv. + */ + void + dsy_ctrl_init_bipolar_cv(dsy_analog_ctrl* ctrl, uint16_t* adcptr, float sr); + + /** Reads a value from an analog control's ADC and transforms it into a normalized range. + * + * This function is a wrapper for AnalogControl::Process. + */ + float dsy_ctrl_process(dsy_analog_ctrl* ctrl); + + /** + * Returns the latest value from an analog control without reprocessing. + * + * This function is a wrapper for AnalogControl::Value. + */ + inline float dsy_ctrl_value(dsy_analog_ctrl* ctrl); + + /** Sets the coefficient for an analog control's one pole smoothing filter. + * + * This function is a wrapper for AnalogControl::SetCoeff. + */ + inline void dsy_ctrl_set_coeff(dsy_analog_ctrl* ctrl, float val); + + /** + * Returns the raw unsigned 16 bit value from an analog control's ADC. + * + * This function is a wrapper for AnalogControl::GetRawValue. + */ + inline uint16_t dsy_ctrl_get_raw_value(dsy_analog_ctrl* ctrl); + + /** + * Returns the raw value from an analog control's ADC as a float. + * + * This function is a wrapper for AnalogControl::GetRawFloat. + */ + inline float dsy_ctrl_get_raw_float(dsy_analog_ctrl* ctrl); + + /** Sets the sampling rate of an analog control. + * + * This function is a wrapper for AnalogControl::SetSampleRate. + */ + void dsy_ctrl_set_sample_rate(dsy_analog_ctrl* ctrl, float sr); +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // DSY_KNOB_H \ No newline at end of file