giuliomoro@193: /* giuliomoro@193: * PulseIn.h giuliomoro@193: * giuliomoro@193: * Created on: 4 Feb 2016 giuliomoro@193: * Author: giulio giuliomoro@193: */ giuliomoro@193: giuliomoro@193: #ifndef PULSEIN_H_ giuliomoro@193: #define PULSEIN_H_ giuliomoro@193: giuliomoro@301: #include giuliomoro@193: #include giuliomoro@193: class PulseIn { giuliomoro@193: private: giuliomoro@193: std::vector _array; giuliomoro@193: int _pulseOnState; giuliomoro@193: int _digitalInput; giuliomoro@193: bool _pulseIsOn; giuliomoro@193: uint64_t _pulseStart; giuliomoro@193: uint64_t _lastContext; giuliomoro@193: public: giuliomoro@193: PulseIn(){ giuliomoro@193: _digitalInput = -1; giuliomoro@193: }; giuliomoro@193: giuliomoro@301: PulseIn(BelaContext* context, unsigned int digitalInput, int direction=1){ giuliomoro@193: init(context, digitalInput, direction); giuliomoro@193: }; giuliomoro@193: /** giuliomoro@193: * Initializes the PulseIn object. Also takes care of initializing the digital pin as input. giuliomoro@193: * giuliomoro@193: * If the object has been created with the default constructor, the user will giuliomoro@193: * need to call init() before calling check() or hasPulsed(). giuliomoro@193: * @param digitalInput the digital input where to activate a pulse detector giuliomoro@193: * @param direction the direction of the pulse, giuliomoro@193: * can be 1 to detect positive pulses, e.g.:( 0 0 0 0 1 1 0 0 0 0 0) giuliomoro@193: * or -1 to detect negative pulses, e.g.: ( 1 1 1 1 0 0 1 1 1 1) giuliomoro@193: */ giuliomoro@301: void init(BelaContext* context, unsigned int digitalInput, int direction=1); giuliomoro@193: giuliomoro@193: /** giuliomoro@193: * Detects pulses. giuliomoro@193: * giuliomoro@193: * The user does not need to call this method as long as they call hasPulsed() at least once per context. giuliomoro@193: * The rationale why we check() for pulses in a different method giuliomoro@193: * than hasPulsed() is because user might not query for hasPulsed() every sample, giuliomoro@193: * so we are safe so long as they call hasPulsed() or check() at least once per buffer. giuliomoro@193: * Also, results are cached (i.e.: we do not check() for pulses twice for the same context. andrewm@311: * context->audioFramesElapsed is used as an identifier. giuliomoro@193: */ giuliomoro@301: void check(BelaContext* context); giuliomoro@193: giuliomoro@193: /** giuliomoro@193: * Looks for the end of a pulse. giuliomoro@193: * giuliomoro@301: * @param context the current BelaContext giuliomoro@193: * @param frame the frame at which to check if a pulse was detected. giuliomoro@193: * @return the length of the pulse if a pulse ending was detected at sample n, zero otherwise. giuliomoro@193: */ giuliomoro@301: int hasPulsed(BelaContext* context, int frame){//let's leave this in PulseIn.h to allow the compiler to optimize out the call. andrewm@311: if(_lastContext != context->audioFramesElapsed){ // check for pulses in the whole context and cache the result giuliomoro@193: check(context); giuliomoro@193: } giuliomoro@193: return _array[frame]; giuliomoro@193: } giuliomoro@193: virtual ~PulseIn(); giuliomoro@193: }; giuliomoro@193: giuliomoro@193: #endif /* PULSEIN_H_ */