andrewm@0: /*
andrewm@0:  * Utilities.cpp
andrewm@0:  *
andrewm@0:  *  Created on: Oct 27, 2014
andrewm@0:  *      Author: parallels
andrewm@0:  */
andrewm@0: 
andrewm@0: #include "../include/Utilities.h"
andrewm@0: 
giuliomoro@179: // audioReadFrame()
giuliomoro@179: //
giuliomoro@179: // Returns the value of the given audio input at the given frame number.
giuliomoro@179: float audioReadFrame(BeagleRTContext *context, int frame, int channel) {
giuliomoro@179: 	return context->audioIn[frame * context->audioChannels + channel];
giuliomoro@179: }
giuliomoro@179: 
giuliomoro@179: // audioWriteFrame()
giuliomoro@179: //
giuliomoro@179: // Sets a given audio output channel to a value for the current frame
giuliomoro@179: void audioWriteFrame(BeagleRTContext *context, int frame, int channel, float value) {
giuliomoro@179: 	context->audioOut[frame * context->audioChannels + channel] = value;
giuliomoro@179: }
giuliomoro@179: 
andrewm@45: // analogReadFrame()
andrewm@45: //
andrewm@45: // Returns the value of the given analog input at the given frame number.
andrewm@52: float analogReadFrame(BeagleRTContext *context, int frame, int channel) {
andrewm@45: 	return context->analogIn[frame * context->analogChannels + channel];
andrewm@45: }
andrewm@45: 
andrewm@45: // analogWriteFrame()
andrewm@45: //
giuliomoro@179: // Sets a given analog output channel to a value for the current frame and, if persistent outputs are
andrewm@45: // enabled, for all subsequent frames
andrewm@52: void analogWriteFrame(BeagleRTContext *context, int frame, int channel, float value) {
andrewm@45: 	if(context->flags & BEAGLERT_FLAG_ANALOG_OUTPUTS_PERSIST) {
andrewm@45: 		for(unsigned int f = frame; f < context->analogFrames; f++)
andrewm@45: 			context->analogOut[frame * context->analogChannels + channel] = value;
andrewm@45: 	}
andrewm@45: 	else
andrewm@45: 		context->analogOut[frame * context->analogChannels + channel] = value;
andrewm@45: }
andrewm@45: 
andrewm@45: // analogWriteFrameOnce()
andrewm@45: //
andrewm@45: // Sets a given channel to a value for only the current frame
andrewm@52: void analogWriteFrameOnce(BeagleRTContext *context, int frame, int channel, float value) {
andrewm@45: 	context->analogOut[frame * context->analogChannels + channel] = value;
andrewm@45: }
andrewm@45: 
andrewm@45: // digitalReadFrame()
andrewm@45: //
andrewm@45: // Returns the value of a given digital input at the given frame number
andrewm@52: int digitalReadFrame(BeagleRTContext *context, int frame, int channel) {
andrewm@45: 	return getBit(context->digital[frame], channel + 16);
andrewm@45: }
andrewm@45: 
andrewm@45: // digitalWriteFrame()
andrewm@45: //
andrewm@45: // Sets a given digital output channel to a value for the current frame and all subsequent frames
andrewm@52: void digitalWriteFrame(BeagleRTContext *context, int frame, int channel, int value) {
andrewm@45: 	for(unsigned int f = frame; f < context->digitalFrames; f++) {
andrewm@45: 		if(value)
andrewm@45: 			context->digital[f] |= 1 << (channel + 16);
andrewm@45: 		else
andrewm@45: 			context->digital[f] &= ~(1 << (channel + 16));
andrewm@45: 	}
andrewm@45: }
andrewm@45: 
andrewm@45: // digitalWriteFrameOnce()
andrewm@45: //
andrewm@45: // Sets a given digital output channel to a value for the current frame only
andrewm@52: void digitalWriteFrameOnce(BeagleRTContext *context, int frame, int channel, int value) {
andrewm@45: 	if(value)
andrewm@45: 		context->digital[frame] |= 1 << (channel + 16);
andrewm@45: 	else
andrewm@45: 		context->digital[frame] &= ~(1 << (channel + 16));
andrewm@45: }
andrewm@45: 
andrewm@45: // pinModeFrame()
andrewm@45: //
andrewm@45: // Sets the direction of a digital pin for the current frame and all subsequent frames
andrewm@52: void pinModeFrame(BeagleRTContext *context, int frame, int channel, int mode) {
andrewm@45: 	for(unsigned int f = frame; f < context->digitalFrames; f++) {
giuliomoro@75: 		if(mode == INPUT)
andrewm@45: 			context->digital[f] |= (1 << channel);
andrewm@45: 		else
andrewm@45: 			context->digital[f] &= ~(1 << channel);
andrewm@45: 	}
andrewm@45: }
andrewm@45: 
andrewm@45: // pinModeFrameOnce()
andrewm@45: //
andrewm@45: // Sets the direction of a digital pin for the current frame only
andrewm@52: void pinModeFrameOnce(BeagleRTContext *context, int frame, int channel, int mode) {
giuliomoro@75: 	if(mode == INPUT)
andrewm@45: 		context->digital[frame] |= (1 << channel);
andrewm@45: 	else
andrewm@45: 		context->digital[frame] &= ~(1 << channel);
andrewm@45: }
andrewm@45: 
andrewm@0: // map()
andrewm@0: //
andrewm@0: // Scale an input value from one range to another. Works like its Wiring language equivalent.
andrewm@0: // x is the value to scale; in_min and in_max are the input range; out_min and out_max
andrewm@0: // are the output range.
andrewm@0: 
andrewm@52: float map(float x, float in_min, float in_max, float out_min, float out_max)
andrewm@0: {
andrewm@0: 	return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
andrewm@0: }
andrewm@0: 
andrewm@0: // constrain()
andrewm@0: //
andrewm@0: // Clips an input value to be between two end points
andrewm@0: // x is the value to constrain; min_val and max_val are the range
andrewm@0: 
andrewm@52: float constrain(float x, float min_val, float max_val)
andrewm@0: {
andrewm@0: 	if(x < min_val) return min_val;
andrewm@0: 	if(x > max_val) return max_val;
andrewm@0: 	return x;
andrewm@0: }