Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add C Bindings #580

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 60 additions & 3 deletions src/hid/ctrl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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;
Expand Down Expand Up @@ -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));
}
}

extern "C" dsy_analog_ctrl* dsy_ctrl_new()
{
return (dsy_analog_ctrl*)static_cast<void*>(new AnalogControl());
}

extern "C" void dsy_ctrl_destroy(dsy_analog_ctrl* ctrl)
{
delete static_cast<AnalogControl*>((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<AnalogControl*>((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<AnalogControl*>((void*)ctrl)->InitBipolarCv(adcptr, sr);
}

extern "C" float dsy_ctrl_process(dsy_analog_ctrl* ctrl)
{
return static_cast<AnalogControl*>((void*)ctrl)->Process();
}

extern "C" float dsy_ctrl_value(dsy_analog_ctrl* ctrl)
{
return static_cast<AnalogControl*>((void*)ctrl)->Value();
}

extern "C" void dsy_ctrl_set_coeff(dsy_analog_ctrl* ctrl, float val)
{
return static_cast<AnalogControl*>((void*)ctrl)->SetCoeff(val);
}

extern "C" uint16_t dsy_ctrl_get_raw_value(dsy_analog_ctrl* ctrl)
{
return static_cast<AnalogControl*>((void*)ctrl)->GetRawValue();
}

extern "C" float dsy_ctrl_get_raw_float(dsy_analog_ctrl* ctrl)
{
return static_cast<AnalogControl*>((void*)ctrl)->GetRawFloat();
}

extern "C" void dsy_ctrl_set_sample_rate(dsy_analog_ctrl* ctrl, float sr)
{
static_cast<AnalogControl*>((void*)ctrl)->SetSampleRate(sr);
}
176 changes: 138 additions & 38 deletions src/hid/ctrl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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_;
Expand All @@ -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