annotate include/Utilities.h @ 301:e4392164b458 prerelease

RENAMED BeagleRT to Bela AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, scripts probably not working
author Giulio Moro <giuliomoro@yahoo.it>
date Fri, 27 May 2016 14:34:41 +0100
parents d7148d21aaa5
children 421a69d42943
rev   line source
andrewm@66 1 /**
andrewm@66 2 * @file
andrewm@66 3 * @brief Wiring-inspired utility functions and macros
andrewm@0 4 *
andrewm@66 5 * Macros and functions for I/O and data processing taking after the Wiring
andrewm@66 6 * (Arduino) language. This code began as part of the Hackable Instruments
andrewm@66 7 * project (EPSRC) at Queen Mary University of London, 2013-14.
andrewm@66 8 *
andrewm@66 9 * (c) 2014-15 Andrew McPherson, Victor Zappi and Giulio Moro,
andrewm@66 10 * Queen Mary University of London
andrewm@0 11 */
andrewm@0 12
andrewm@0 13 #ifndef UTILITIES_H_
andrewm@0 14 #define UTILITIES_H_
andrewm@0 15
giuliomoro@301 16 #include "Bela.h"
andrewm@45 17
andrewm@95 18 /**
andrewm@95 19 * \defgroup iofunctions I/O functions and constants
andrewm@95 20 *
andrewm@95 21 * These functions and macros are used for audio, analog and digital I/O. All the
giuliomoro@301 22 * I/O functions require the BelaContext data structure from render() to be passed
andrewm@95 23 * in. This means that these functions are, by design, \b only usable from within
andrewm@95 24 * the rendering thread.
andrewm@95 25 *
andrewm@95 26 * The naming conventions are loosely derived from the Arduino environment, and the
andrewm@95 27 * syntax is similar. Unlike Arduino, the I/O functions require the frame number at which
andrewm@95 28 * the read or write should take place, since all I/O happens synchronously with the
andrewm@95 29 * audio clock.
andrewm@95 30 *
andrewm@95 31 * @{
andrewm@95 32 */
andrewm@95 33
giuliomoro@187 34 #ifndef INPUT
giuliomoro@187 35 #define INPUT 0x0
giuliomoro@187 36 #endif /* INPUT */
andrewm@72 37
giuliomoro@187 38 #ifndef OUTPUT
giuliomoro@187 39 #define OUTPUT 0x1
giuliomoro@187 40 #endif /* OUTPUT */
andrewm@72 41
andrewm@95 42 /** @} */
andrewm@95 43
andrewm@95 44 /**
andrewm@95 45 * \ingroup wiring
andrewm@95 46 *
andrewm@95 47 * @{
andrewm@95 48 */
andrewm@95 49
andrewm@66 50 /// Set the given bit in \c word to 1.
andrewm@45 51 #define setBit(word,bit) ((word) | (1 << (bit)))
andrewm@66 52
andrewm@66 53 /// Clear the given bit in \c word to 0.
andrewm@45 54 #define clearBit(word,bit) ((word) &~ (1 << (bit)))
andrewm@66 55
andrewm@66 56 /// Check if the given bit in \c word is 1 (returns nonzero) or 0 (returns zero).
andrewm@45 57 #define getBit(word,bit) (((word) >> (bit)) & 1)
andrewm@66 58
andrewm@66 59 /// Set/clear the given bit in \c word to \c value.
andrewm@45 60 #define changeBit(word,bit,value) ((clearBit((word),(bit))) | ((value) << (bit)))
andrewm@45 61
andrewm@95 62 /** @} */
andrewm@95 63
andrewm@95 64 /**
andrewm@95 65 * \ingroup iofunctions
andrewm@95 66 *
andrewm@95 67 * @{
andrewm@95 68 */
andrewm@95 69
andrewm@45 70 #if 1
andrewm@56 71 // Note: pinMode(), analogWrite() and digitalWrite() should be able to be called from setup()
andrewm@56 72 // Likewise, thread launch should be able to be called from setup()
andrewm@45 73 // Also, make volume change functions callable from render() thread -- as an aux task?
andrewm@45 74
andrewm@68 75 /**
giuliomoro@179 76 * \brief Read an audio input, specifying the frame number (when to read) and the channel.
giuliomoro@179 77 *
giuliomoro@179 78 * This function returns the value of an audio input, at the time indicated by \c frame.
giuliomoro@179 79 * The returned value ranges from -1 to 1.
giuliomoro@179 80 *
giuliomoro@301 81 * \param context The I/O data structure which is passed by Bela to render().
giuliomoro@179 82 * \param frame Which frame (i.e. what time) to read the audio input. Valid values range
giuliomoro@179 83 * from 0 to (context->audioFrames - 1).
giuliomoro@179 84 * \param channel Which audio input to read. Valid values are between 0 and
giuliomoro@179 85 * (context->audioChannels - 1), typically 0 to 1 by default.
giuliomoro@179 86 * \return Value of the analog input, range to 1.
giuliomoro@179 87 */
giuliomoro@301 88 static inline float audioReadFrame(BelaContext *context, int frame, int channel);
giuliomoro@179 89
giuliomoro@179 90 /**
giuliomoro@179 91 * \brief Write an audio output, specifying the frame number (when to write) and the channel.
giuliomoro@179 92 *
giuliomoro@179 93 * This function sets the value of an audio output, at the time indicated by \c frame. Valid
giuliomoro@179 94 * values are between -1 and 1.
giuliomoro@179 95 *
giuliomoro@301 96 * \param context The I/O data structure which is passed by Bela to render().
giuliomoro@179 97 * \param frame Which frame (i.e. what time) to write the audio output. Valid values range
giuliomoro@179 98 * from 0 to (context->audioFrames - 1).
giuliomoro@179 99 * \param channel Which analog output to write. Valid values are between 0 and
giuliomoro@179 100 * (context->audioChannels - 1), typically 0 to 1 by default.
giuliomoro@179 101 * \param value Value to write to the output, range -1 to 1.
giuliomoro@179 102 */
giuliomoro@301 103 static inline void audioWriteFrame(BelaContext *context, int frame, int channel, float value);
giuliomoro@179 104
giuliomoro@179 105 /**
andrewm@68 106 * \brief Read an analog input, specifying the frame number (when to read) and the channel.
andrewm@68 107 *
andrewm@68 108 * This function returns the value of an analog input, at the time indicated by \c frame.
andrewm@68 109 * The returned value ranges from 0 to 1, corresponding to a voltage range of 0 to 4.096V.
andrewm@68 110 *
giuliomoro@301 111 * \param context The I/O data structure which is passed by Bela to render().
andrewm@68 112 * \param frame Which frame (i.e. what time) to read the analog input. Valid values range
andrewm@68 113 * from 0 to (context->analogFrames - 1).
andrewm@68 114 * \param channel Which analog input to read. Valid values are between 0 and
andrewm@68 115 * (context->analogChannels - 1), typically 0 to 7 by default.
andrewm@68 116 * \return Value of the analog input, range 0 to 1.
andrewm@68 117 */
giuliomoro@301 118 static inline float analogReadFrame(BelaContext *context, int frame, int channel);
andrewm@68 119
andrewm@68 120 /**
andrewm@68 121 * \brief Write an analog output, specifying the frame number (when to write) and the channel.
andrewm@68 122 *
andrewm@68 123 * This function sets the value of an analog output, at the time indicated by \c frame. Valid
andrewm@68 124 * values are between 0 and 1, corresponding to the range 0 to 5V.
andrewm@68 125 *
andrewm@68 126 * The value written will persist for all future frames if BEAGLERT_FLAG_ANALOG_OUTPUTS_PERSIST
andrewm@68 127 * is set in context->flags. This is the default behaviour.
andrewm@68 128 *
giuliomoro@301 129 * \param context The I/O data structure which is passed by Bela to render().
andrewm@68 130 * \param frame Which frame (i.e. what time) to write the analog output. Valid values range
andrewm@68 131 * from 0 to (context->analogFrames - 1).
andrewm@68 132 * \param channel Which analog output to write. Valid values are between 0 and
andrewm@68 133 * (context->analogChannels - 1), typically 0 to 7 by default.
andrewm@68 134 * \param value Value to write to the output, range 0 to 1.
andrewm@68 135 */
giuliomoro@301 136 static inline void analogWriteFrame(BelaContext *context, int frame, int channel, float value);
andrewm@68 137
andrewm@68 138 /**
andrewm@68 139 * \brief Write an analog output, specifying the frame number (when to write) and the channel.
andrewm@68 140 *
andrewm@68 141 * This function sets the value of an analog output, at the time indicated by \c frame. Valid
andrewm@68 142 * values are between 0 and 1, corresponding to the range 0 to 5V.
andrewm@68 143 *
andrewm@68 144 * Unlike analogWriteFrame(), the value written will affect \b only the frame specified, with
andrewm@72 145 * future values unchanged. This is faster than analogWriteFrame() so is better suited
andrewm@68 146 * to applications where every frame will be written to a different value. If
andrewm@68 147 * BEAGLERT_FLAG_ANALOG_OUTPUTS_PERSIST is not set within context->flags, then
andrewm@68 148 * analogWriteFrameOnce() and analogWriteFrame() are equivalent.
andrewm@68 149 *
giuliomoro@301 150 * \param context The I/O data structure which is passed by Bela to render().
andrewm@68 151 * \param frame Which frame (i.e. what time) to write the analog output. Valid values range
andrewm@68 152 * from 0 to (context->analogFrames - 1).
andrewm@68 153 * \param channel Which analog output to write. Valid values are between 0 and
andrewm@68 154 * (context->analogChannels - 1), typically 0 to 7 by default.
andrewm@68 155 * \param value Value to write to the output, range 0 to 1.
andrewm@68 156 */
giuliomoro@301 157 static inline void analogWriteFrameOnce(BelaContext *context, int frame, int channel, float value);
andrewm@45 158
andrewm@72 159 /**
andrewm@72 160 * \brief Read a digital input, specifying the frame number (when to read) and the pin.
andrewm@72 161 *
andrewm@72 162 * This function returns the value of a digital input, at the time indicated by \c frame.
andrewm@72 163 * The value is 0 if the pin is low, and nonzero if the pin is high (3.3V).
andrewm@72 164 *
giuliomoro@301 165 * \param context The I/O data structure which is passed by Bela to render().
andrewm@72 166 * \param frame Which frame (i.e. what time) to read the digital input. Valid values range
andrewm@72 167 * from 0 to (context->digitalFrames - 1).
andrewm@72 168 * \param channel Which digital pin to read. 16 pins across the P8 and P9 headers of the
andrewm@72 169 * BeagleBone Black are available. See the constants P8_xx and P9_xx defined in
andrewm@72 170 * digital_gpio_mapping.h.
andrewm@72 171 * \return Value of the digital input.
andrewm@72 172 */
giuliomoro@301 173 static inline int digitalReadFrame(BelaContext *context, int frame, int channel);
andrewm@72 174
andrewm@72 175 /**
andrewm@72 176 * \brief Write a digital output, specifying the frame number (when to write) and the pin.
andrewm@72 177 *
andrewm@72 178 * This function sets the value of a digital output, at the time indicated by \c frame.
andrewm@72 179 * A value of 0 sets the pin low; any other value sets the pin high (3.3V).
andrewm@72 180 *
andrewm@72 181 * The value written will persist for all future frames.
andrewm@72 182 *
giuliomoro@301 183 * \param context The I/O data structure which is passed by Bela to render().
andrewm@72 184 * \param frame Which frame (i.e. what time) to write the digital output. Valid values range
andrewm@72 185 * from 0 to (context->digitalFrames - 1).
andrewm@72 186 * \param channel Which digital output to write. 16 pins across the P8 and P9 headers of the
andrewm@72 187 * BeagleBone Black are available. See the constants P8_xx and P9_xx defined in
andrewm@72 188 * digital_gpio_mapping.h.
andrewm@72 189 * \param value Value to write to the output.
andrewm@72 190 */
giuliomoro@301 191 static inline void digitalWriteFrame(BelaContext *context, int frame, int channel, int value);
andrewm@72 192
andrewm@72 193 /**
andrewm@72 194 * \brief Write a digital output, specifying the frame number (when to write) and the pin.
andrewm@72 195 *
andrewm@72 196 * This function sets the value of a digital output, at the time indicated by \c frame.
andrewm@72 197 * A value of 0 sets the pin low; any other value sets the pin high (3.3V).
andrewm@72 198 *
andrewm@72 199 * Unlike digitalWriteFrame(), the value written will affect \b only the frame specified, with
andrewm@72 200 * future values unchanged. This is faster than digitalWriteFrame() so is better suited
andrewm@72 201 * to applications where every frame will be written to a different value.
andrewm@72 202 *
giuliomoro@301 203 * \param context The I/O data structure which is passed by Bela to render().
andrewm@72 204 * \param frame Which frame (i.e. what time) to write the digital output. Valid values range
andrewm@72 205 * from 0 to (context->digitalFrames - 1).
andrewm@72 206 * \param channel Which digital output to write. 16 pins across the P8 and P9 headers of the
andrewm@72 207 * BeagleBone Black are available. See the constants P8_xx and P9_xx defined in
andrewm@72 208 * digital_gpio_mapping.h.
andrewm@72 209 * \param value Value to write to the output.
andrewm@72 210 */
giuliomoro@301 211 static inline void digitalWriteFrameOnce(BelaContext *context, int frame, int channel, int value);
andrewm@45 212
andrewm@72 213 /**
andrewm@72 214 * \brief Set the direction of a digital pin to input or output.
andrewm@72 215 *
andrewm@72 216 * This function sets the direction of a digital pin, at the time indicated by \c frame.
andrewm@72 217 * Valid values are \c INPUT and \c OUTPUT. All pins begin as inputs by default.
andrewm@72 218 *
andrewm@72 219 * The value written will persist for all future frames.
andrewm@72 220 *
giuliomoro@301 221 * \param context The I/O data structure which is passed by Bela to render().
andrewm@72 222 * \param frame Which frame (i.e. what time) to set the pin direction. Valid values range
andrewm@72 223 * from 0 to (context->digitalFrames - 1).
andrewm@72 224 * \param channel Which digital output to write. 16 pins across the P8 and P9 headers of the
andrewm@72 225 * BeagleBone Black are available. See the constants P8_xx and P9_xx defined in
andrewm@72 226 * digital_gpio_mapping.h.
andrewm@72 227 * \param value Direction of the pin (\c INPUT or \c OUTPUT).
andrewm@72 228 */
giuliomoro@301 229 static inline void pinModeFrame(BelaContext *context, int frame, int channel, int mode);
andrewm@72 230
andrewm@72 231 /**
andrewm@72 232 * \brief Set the direction of a digital pin to input or output.
andrewm@72 233 *
andrewm@72 234 * This function sets the direction of a digital pin, at the time indicated by \c frame.
andrewm@72 235 * Valid values are \c INPUT and \c OUTPUT. All pins begin as inputs by default.
andrewm@72 236 *
andrewm@72 237 * The value written will affect only the specified frame.
andrewm@72 238 *
giuliomoro@301 239 * \param context The I/O data structure which is passed by Bela to render().
andrewm@72 240 * \param frame Which frame (i.e. what time) to set the pin direction. Valid values range
andrewm@72 241 * from 0 to (context->digitalFrames - 1).
andrewm@72 242 * \param channel Which digital output to write. 16 pins across the P8 and P9 headers of the
andrewm@72 243 * BeagleBone Black are available. See the constants P8_xx and P9_xx defined in
andrewm@72 244 * digital_gpio_mapping.h.
andrewm@72 245 * \param value Direction of the pin (\c INPUT or \c OUTPUT).
andrewm@72 246 */
giuliomoro@301 247 static inline void pinModeFrameOnce(BelaContext *context, int frame, int channel, int mode);
andrewm@45 248
andrewm@95 249 /** @} */
andrewm@95 250
andrewm@45 251 #else
andrewm@13 252
giuliomoro@19 253 // Macros for accessing the analog values: usable _only_ within render()
andrewm@5 254
giuliomoro@19 255 // Read an Analog input from input pin p at frame f
giuliomoro@23 256 #define analogRead(p, f) (analogIn[(f)*gNumAnalogChannels + (p)])
giuliomoro@19 257 // Write an Analog output frame at output pin p, frame f, to value v
giuliomoro@23 258 #define analogWriteFrame(p, f, v) (analogOut[(f)*gNumAnalogChannels + (p)] = (v))
giuliomoro@23 259 #define analogWrite(pin, frame, value) \
giuliomoro@18 260 (({do {\
giuliomoro@19 261 for (int _privateI=(frame); _privateI<numAnalogFrames; _privateI++){ \
giuliomoro@23 262 analogWriteFrame(pin,_privateI,value); \
giuliomoro@18 263 }\
giuliomoro@18 264 } while (0);}),(void)0)\
andrewm@5 265
andrewm@45 266
giuliomoro@19 267 //digital API:
giuliomoro@33 268 #define setDigitalDirectionFrame(pin,frame,direction) digital[(frame)]=changeBit(digital[(frame)],(pin),(direction)),void(0)
giuliomoro@33 269 #define setDigitalDirection(pin,frame,direction)\
giuliomoro@33 270 (({do {\
giuliomoro@33 271 for(int _privateI=(frame); _privateI<numDigitalFrames; _privateI++)\
giuliomoro@33 272 setDigitalDirectionFrame(pin,_privateI,direction);\
giuliomoro@33 273 } while (0);}), (void)0)
giuliomoro@19 274 #define digitalWriteAll(frame,value) digital[(frame)]=0xffff0000*(!(!value));
giuliomoro@16 275 //sets the bit in the high word, clears the bit in the low word (just in case the direction was not previously set)
giuliomoro@19 276 #define digitalWriteFrame(pin, frame, value) digital[(frame)]=( changeBit(digital[(frame)], (pin+16), (value)) & (0xffffffff-(1<<(pin))) ) //could have been done with two subsequent assignments
giuliomoro@18 277 #define digitalWrite(pin, frame, value) \
giuliomoro@18 278 (({do {\
giuliomoro@33 279 for (int _privateI=(frame); _privateI<numDigitalFrames; _privateI++) \
giuliomoro@18 280 digitalWriteFrame(pin,_privateI,value); \
giuliomoro@18 281 } while (0);}),(void)0)\
giuliomoro@18 282
giuliomoro@19 283 #define digitalRead(pin, frame) ( getBit(digital[(frame)], pin+16) )
giuliomoro@16 284
andrewm@45 285 #endif
andrewm@45 286
andrewm@66 287 /**
andrewm@95 288 * \defgroup wiring Wiring language support
andrewm@95 289 *
andrewm@95 290 * These are functions found in the Wiring (Arduino) language which are not directly
andrewm@95 291 * related to I/O but are provided as a convenience.
andrewm@95 292 *
andrewm@95 293 * @{
andrewm@95 294 */
andrewm@95 295
andrewm@95 296 /**
andrewm@66 297 * \brief Linearly rescale a number from one range of values to another.
andrewm@66 298 *
andrewm@66 299 * This function linearly scales values of \c x such that the range in_min to
andrewm@66 300 * in_max at the input corresponds to the range out_min to out_max
andrewm@66 301 * at the output. Values outside this range are extrapolated.
andrewm@66 302 *
andrewm@66 303 * This function behaves identically to the function of the same name in Processing. It
andrewm@66 304 * is also similar to the corresponding function in Arduino, except that it supports floating
andrewm@66 305 * point values.
andrewm@66 306 *
andrewm@66 307 * \param x Input value to be mapped.
andrewm@66 308 * \param in_min Lower bound of the input range.
andrewm@66 309 * \param in_max Upper bound of the input range.
andrewm@66 310 * \param out_min Lower bound of the output range.
andrewm@66 311 * \param out_max Upper bound of the output range.
andrewm@66 312 * \return Rescaled value.
andrewm@66 313 */
giuliomoro@187 314 static inline float map(float x, float in_min, float in_max, float out_min, float out_max);
andrewm@66 315
andrewm@66 316 /**
andrewm@66 317 * \brief Constrain a number to stay within a given range.
andrewm@66 318 *
andrewm@66 319 * This function constrains \c x to remain within the range min_val to
andrewm@66 320 * max_val. Values of \c x outside this range are clipped to the edges
andrewm@66 321 * of the range.
andrewm@66 322 *
andrewm@66 323 * This function behaves identically to the function of the same name in Processing. It
andrewm@66 324 * is also similar to the corresponding function in Arduino, except that it supports floating
andrewm@66 325 * point values.
andrewm@66 326 *
andrewm@66 327 * \param x Input value to be constrained.
andrewm@66 328 * \param min_val Minimum possible value.
andrewm@66 329 * \param max_val Maximum possible value.
andrewm@66 330 * \return Constrained value.
andrewm@66 331 */
giuliomoro@187 332 static inline float constrain(float x, float min_val, float max_val);
andrewm@0 333
andrewm@95 334 /** @} */
giuliomoro@187 335 // audioReadFrame()
giuliomoro@187 336 //
giuliomoro@187 337 // Returns the value of the given audio input at the given frame number.
giuliomoro@301 338 static inline float audioReadFrame(BelaContext *context, int frame, int channel) {
giuliomoro@187 339 return context->audioIn[frame * context->audioChannels + channel];
giuliomoro@187 340 }
giuliomoro@187 341
giuliomoro@187 342 // audioWriteFrame()
giuliomoro@187 343 //
giuliomoro@187 344 // Sets a given audio output channel to a value for the current frame
giuliomoro@301 345 static inline void audioWriteFrame(BelaContext *context, int frame, int channel, float value) {
giuliomoro@187 346 context->audioOut[frame * context->audioChannels + channel] = value;
giuliomoro@187 347 }
giuliomoro@187 348
giuliomoro@187 349 // analogReadFrame()
giuliomoro@187 350 //
giuliomoro@187 351 // Returns the value of the given analog input at the given frame number.
giuliomoro@301 352 static inline float analogReadFrame(BelaContext *context, int frame, int channel) {
giuliomoro@187 353 return context->analogIn[frame * context->analogChannels + channel];
giuliomoro@187 354 }
giuliomoro@187 355
giuliomoro@187 356 // analogWriteFrame()
giuliomoro@187 357 //
giuliomoro@187 358 // Sets a given analog output channel to a value for the current frame and, if persistent outputs are
giuliomoro@187 359 // enabled, for all subsequent frames
giuliomoro@301 360 static inline void analogWriteFrame(BelaContext *context, int frame, int channel, float value) {
giuliomoro@187 361 if(context->flags & BEAGLERT_FLAG_ANALOG_OUTPUTS_PERSIST) {
giuliomoro@187 362 for(unsigned int f = frame; f < context->analogFrames; f++)
giuliomoro@187 363 context->analogOut[frame * context->analogChannels + channel] = value;
giuliomoro@187 364 }
giuliomoro@187 365 else
giuliomoro@187 366 context->analogOut[frame * context->analogChannels + channel] = value;
giuliomoro@187 367 }
giuliomoro@187 368
giuliomoro@187 369 // analogWriteFrameOnce()
giuliomoro@187 370 //
giuliomoro@187 371 // Sets a given channel to a value for only the current frame
giuliomoro@301 372 static inline void analogWriteFrameOnce(BelaContext *context, int frame, int channel, float value) {
giuliomoro@187 373 context->analogOut[frame * context->analogChannels + channel] = value;
giuliomoro@187 374 }
giuliomoro@187 375
giuliomoro@187 376 // digitalReadFrame()
giuliomoro@187 377 //
giuliomoro@187 378 // Returns the value of a given digital input at the given frame number
giuliomoro@301 379 static inline int digitalReadFrame(BelaContext *context, int frame, int channel) {
giuliomoro@187 380 return getBit(context->digital[frame], channel + 16);
giuliomoro@187 381 }
giuliomoro@187 382
giuliomoro@187 383 // digitalWriteFrame()
giuliomoro@187 384 //
giuliomoro@187 385 // Sets a given digital output channel to a value for the current frame and all subsequent frames
giuliomoro@301 386 static inline void digitalWriteFrame(BelaContext *context, int frame, int channel, int value) {
giuliomoro@187 387 for(unsigned int f = frame; f < context->digitalFrames; f++) {
giuliomoro@187 388 if(value)
giuliomoro@187 389 context->digital[f] |= 1 << (channel + 16);
giuliomoro@187 390 else
giuliomoro@187 391 context->digital[f] &= ~(1 << (channel + 16));
giuliomoro@187 392 }
giuliomoro@187 393 }
giuliomoro@187 394
giuliomoro@187 395 // digitalWriteFrameOnce()
giuliomoro@187 396 //
giuliomoro@187 397 // Sets a given digital output channel to a value for the current frame only
giuliomoro@301 398 static inline void digitalWriteFrameOnce(BelaContext *context, int frame, int channel, int value) {
giuliomoro@187 399 if(value)
giuliomoro@187 400 context->digital[frame] |= 1 << (channel + 16);
giuliomoro@187 401 else
giuliomoro@187 402 context->digital[frame] &= ~(1 << (channel + 16));
giuliomoro@187 403 }
giuliomoro@187 404
giuliomoro@187 405 // pinModeFrame()
giuliomoro@187 406 //
giuliomoro@187 407 // Sets the direction of a digital pin for the current frame and all subsequent frames
giuliomoro@301 408 static inline void pinModeFrame(BelaContext *context, int frame, int channel, int mode) {
giuliomoro@187 409 for(unsigned int f = frame; f < context->digitalFrames; f++) {
giuliomoro@187 410 if(mode == INPUT)
giuliomoro@187 411 context->digital[f] |= (1 << channel);
giuliomoro@187 412 else
giuliomoro@187 413 context->digital[f] &= ~(1 << channel);
giuliomoro@187 414 }
giuliomoro@187 415 }
giuliomoro@187 416
giuliomoro@187 417 // pinModeFrameOnce()
giuliomoro@187 418 //
giuliomoro@187 419 // Sets the direction of a digital pin for the current frame only
giuliomoro@301 420 static inline void pinModeFrameOnce(BelaContext *context, int frame, int channel, int mode) {
giuliomoro@187 421 if(mode == INPUT)
giuliomoro@187 422 context->digital[frame] |= (1 << channel);
giuliomoro@187 423 else
giuliomoro@187 424 context->digital[frame] &= ~(1 << channel);
giuliomoro@187 425 }
giuliomoro@187 426
giuliomoro@187 427
giuliomoro@187 428
giuliomoro@187 429 // map()
giuliomoro@187 430 //
giuliomoro@187 431 // Scale an input value from one range to another. Works like its Wiring language equivalent.
giuliomoro@187 432 // x is the value to scale; in_min and in_max are the input range; out_min and out_max
giuliomoro@187 433 // are the output range.
giuliomoro@187 434
giuliomoro@187 435 static inline float map(float x, float in_min, float in_max, float out_min, float out_max)
giuliomoro@187 436 {
giuliomoro@187 437 return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
giuliomoro@187 438 }
giuliomoro@187 439
giuliomoro@187 440 // constrain()
giuliomoro@187 441 //
giuliomoro@187 442 // Clips an input value to be between two end points
giuliomoro@187 443 // x is the value to constrain; min_val and max_val are the range
giuliomoro@187 444
giuliomoro@187 445 static inline float constrain(float x, float min_val, float max_val)
giuliomoro@187 446 {
giuliomoro@187 447 if(x < min_val) return min_val;
giuliomoro@187 448 if(x > max_val) return max_val;
giuliomoro@187 449 return x;
giuliomoro@187 450 }
andrewm@95 451
andrewm@0 452 #endif /* UTILITIES_H_ */