changeset 193:3c3d14654b7f

Added PulseIn.
author Giulio Moro <giuliomoro@yahoo.it>
date Thu, 04 Feb 2016 18:02:52 +0000
parents 1402f22fc99a
children 3c3496ff26e0
files .cproject core/PulseIn.cpp include/PulseIn.h
diffstat 3 files changed, 116 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/.cproject	Wed Feb 03 01:21:41 2016 +0000
+++ b/.cproject	Thu Feb 04 18:02:52 2016 +0000
@@ -93,7 +93,7 @@
 					<sourceEntries>
 						<entry excluding="audio_routines_old.S" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="core"/>
 						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="include"/>
-						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="projects/basic_midi"/>
+						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="projects/basic_pulseIn"/>
 						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="source"/>
 					</sourceEntries>
 				</configuration>
@@ -186,7 +186,7 @@
 					<sourceEntries>
 						<entry excluding="audio_routines_old.S" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="core"/>
 						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="include"/>
-						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="projects/basic_midi"/>
+						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="projects/basic_pulseIn"/>
 						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="source"/>
 					</sourceEntries>
 				</configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/PulseIn.cpp	Thu Feb 04 18:02:52 2016 +0000
@@ -0,0 +1,45 @@
+/*
+* PulseIn.cpp
+*
+*  Created on: 4 Feb 2016
+*      Author: giulio
+*/
+
+#include "../include/PulseIn.h"
+
+void PulseIn::init(BeagleRTContext* context, unsigned int digitalInput, int direction){
+	_digitalInput = digitalInput;
+	_pulseIsOn = false;
+	_pulseOnState = direction == 1 ? 1 : 0;
+	_array.resize(context->digitalFrames);
+	_lastContext = (uint64_t)-1;
+	pinModeFrame(context, 0, digitalInput, INPUT); //context is used to allocate the number of elements in the array
+}
+
+void PulseIn::check(BeagleRTContext* context){
+	if(_digitalInput == -1){ //must be init'ed before calling check();
+		throw(1);
+	}
+	for(unsigned int n = 0; n < context->digitalFrames; n++){
+		_array[n] = 0; //maybe a few of these will be overwritten below
+	}
+	for(unsigned int n = 0; n < context->digitalFrames; n++){
+		if(_pulseIsOn == false){ // look for start edge
+			if(digitalReadFrame(context, n, _digitalInput) == _pulseOnState){
+				_pulseStart = context->audioSampleCount + n; // store location of start edge
+				_pulseIsOn = true;
+			}
+		} else { // _pulseIsOn == true;
+			if(digitalReadFrame(context, n, _digitalInput) == !_pulseOnState){ // look for stop edge
+				_array[n] = context->audioSampleCount + n - _pulseStart; // compute and store pulse duration
+				_pulseIsOn = false;
+			}
+		}
+	}
+	_lastContext = context->audioSampleCount;
+};
+
+PulseIn::~PulseIn() {
+// TODO Auto-generated destructor stub
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/PulseIn.h	Thu Feb 04 18:02:52 2016 +0000
@@ -0,0 +1,69 @@
+/*
+ * PulseIn.h
+ *
+ *  Created on: 4 Feb 2016
+ *      Author: giulio
+ */
+
+#ifndef PULSEIN_H_
+#define PULSEIN_H_
+
+#include <BeagleRT.h>
+#include <vector>
+class PulseIn {
+private:
+	std::vector<int> _array;
+	int _pulseOnState;
+	int _digitalInput;
+	bool _pulseIsOn;
+	uint64_t _pulseStart;
+	uint64_t _lastContext;
+public:
+	PulseIn(){
+		_digitalInput = -1;
+	};
+
+	PulseIn(BeagleRTContext* context, unsigned int digitalInput, int direction=1){
+		init(context, digitalInput, direction);
+	};
+	/**
+	 * Initializes the PulseIn object. Also takes care of initializing the digital pin as input.
+	 *
+	 * If the object has been created with the default constructor, the user will
+	 * need to call init() before calling check() or hasPulsed().
+	 * @param digitalInput the digital input where to activate a pulse detector
+	 * @param direction the direction of the pulse,
+	 *  can be 1 to detect positive pulses, e.g.:( 0 0 0 0 1 1 0 0 0 0 0)
+	 *  or -1 to detect negative pulses, e.g.: ( 1 1 1 1 0 0 1 1 1 1)
+	 */
+	void init(BeagleRTContext* context, unsigned int digitalInput, int direction=1);
+
+	/**
+	 * Detects pulses.
+	 *
+	 * The user does not need to call this method as long as they call hasPulsed() at least once per context.
+	 * The rationale why we check() for pulses in a different method
+	 * than hasPulsed() is because user might not query for hasPulsed() every sample,
+	 * so we are safe so long as they call hasPulsed() or check() at least once per buffer.
+	 * Also, results are cached (i.e.: we do not check() for pulses twice for the same context.
+	 * context->audioSampleCount is used as an identifier.
+	 */
+	void check(BeagleRTContext* context);
+
+	/**
+	 * Looks for the end of a pulse.
+	 *
+	 * @param context the current BeagleRTContext
+	 * @param frame the frame at which to check if a pulse was detected.
+	 * @return the length of the pulse if a pulse ending was detected at sample n, zero otherwise.
+	 */
+	int hasPulsed(BeagleRTContext* context, int frame){//let's leave this in PulseIn.h to allow the compiler to optimize out the call.
+		if(_lastContext != context->audioSampleCount){ // check for pulses in the whole context and cache the result
+			check(context);
+		}
+		return _array[frame];
+	}
+	virtual ~PulseIn();
+};
+
+#endif /* PULSEIN_H_ */