giuliomoro@193
|
1 /*
|
giuliomoro@193
|
2 * PulseIn.h
|
giuliomoro@193
|
3 *
|
giuliomoro@193
|
4 * Created on: 4 Feb 2016
|
giuliomoro@193
|
5 * Author: giulio
|
giuliomoro@193
|
6 */
|
giuliomoro@193
|
7
|
giuliomoro@193
|
8 #ifndef PULSEIN_H_
|
giuliomoro@193
|
9 #define PULSEIN_H_
|
giuliomoro@193
|
10
|
giuliomoro@193
|
11 #include <BeagleRT.h>
|
giuliomoro@193
|
12 #include <vector>
|
giuliomoro@193
|
13 class PulseIn {
|
giuliomoro@193
|
14 private:
|
giuliomoro@193
|
15 std::vector<int> _array;
|
giuliomoro@193
|
16 int _pulseOnState;
|
giuliomoro@193
|
17 int _digitalInput;
|
giuliomoro@193
|
18 bool _pulseIsOn;
|
giuliomoro@193
|
19 uint64_t _pulseStart;
|
giuliomoro@193
|
20 uint64_t _lastContext;
|
giuliomoro@193
|
21 public:
|
giuliomoro@193
|
22 PulseIn(){
|
giuliomoro@193
|
23 _digitalInput = -1;
|
giuliomoro@193
|
24 };
|
giuliomoro@193
|
25
|
giuliomoro@193
|
26 PulseIn(BeagleRTContext* context, unsigned int digitalInput, int direction=1){
|
giuliomoro@193
|
27 init(context, digitalInput, direction);
|
giuliomoro@193
|
28 };
|
giuliomoro@193
|
29 /**
|
giuliomoro@193
|
30 * Initializes the PulseIn object. Also takes care of initializing the digital pin as input.
|
giuliomoro@193
|
31 *
|
giuliomoro@193
|
32 * If the object has been created with the default constructor, the user will
|
giuliomoro@193
|
33 * need to call init() before calling check() or hasPulsed().
|
giuliomoro@193
|
34 * @param digitalInput the digital input where to activate a pulse detector
|
giuliomoro@193
|
35 * @param direction the direction of the pulse,
|
giuliomoro@193
|
36 * can be 1 to detect positive pulses, e.g.:( 0 0 0 0 1 1 0 0 0 0 0)
|
giuliomoro@193
|
37 * or -1 to detect negative pulses, e.g.: ( 1 1 1 1 0 0 1 1 1 1)
|
giuliomoro@193
|
38 */
|
giuliomoro@193
|
39 void init(BeagleRTContext* context, unsigned int digitalInput, int direction=1);
|
giuliomoro@193
|
40
|
giuliomoro@193
|
41 /**
|
giuliomoro@193
|
42 * Detects pulses.
|
giuliomoro@193
|
43 *
|
giuliomoro@193
|
44 * The user does not need to call this method as long as they call hasPulsed() at least once per context.
|
giuliomoro@193
|
45 * The rationale why we check() for pulses in a different method
|
giuliomoro@193
|
46 * than hasPulsed() is because user might not query for hasPulsed() every sample,
|
giuliomoro@193
|
47 * so we are safe so long as they call hasPulsed() or check() at least once per buffer.
|
giuliomoro@193
|
48 * Also, results are cached (i.e.: we do not check() for pulses twice for the same context.
|
giuliomoro@193
|
49 * context->audioSampleCount is used as an identifier.
|
giuliomoro@193
|
50 */
|
giuliomoro@193
|
51 void check(BeagleRTContext* context);
|
giuliomoro@193
|
52
|
giuliomoro@193
|
53 /**
|
giuliomoro@193
|
54 * Looks for the end of a pulse.
|
giuliomoro@193
|
55 *
|
giuliomoro@193
|
56 * @param context the current BeagleRTContext
|
giuliomoro@193
|
57 * @param frame the frame at which to check if a pulse was detected.
|
giuliomoro@193
|
58 * @return the length of the pulse if a pulse ending was detected at sample n, zero otherwise.
|
giuliomoro@193
|
59 */
|
giuliomoro@193
|
60 int hasPulsed(BeagleRTContext* context, int frame){//let's leave this in PulseIn.h to allow the compiler to optimize out the call.
|
giuliomoro@193
|
61 if(_lastContext != context->audioSampleCount){ // check for pulses in the whole context and cache the result
|
giuliomoro@193
|
62 check(context);
|
giuliomoro@193
|
63 }
|
giuliomoro@193
|
64 return _array[frame];
|
giuliomoro@193
|
65 }
|
giuliomoro@193
|
66 virtual ~PulseIn();
|
giuliomoro@193
|
67 };
|
giuliomoro@193
|
68
|
giuliomoro@193
|
69 #endif /* PULSEIN_H_ */
|