import pyaudio
import struct
import math
import time

"""
Constants and definitions
"""
RATE = 44100
INPUT_BLOCK_TIME = 0.01 # seconds
INPUT_FRAMES_PER_BLOCK = int(RATE * INPUT_BLOCK_TIME)

PULSE_THRESHOLD = 0.6
MIN_SECONDS_BETWEEN_PULSES = 0.28

def get_rms(block):

    # RMS amplitude is defined as the square root of the 
    # mean over time of the square of the amplitude.
    # so we need to convert this string of bytes into 
    # a string of 16-bit samples...

    # we will get one short out for each 
    # two chars in the string.
    count = len(block)/2
    format = "%dh"%(count)
    shorts = struct.unpack( format, block )

    # iterate over the block.
    sum_squares = 0.0
    for sample in shorts:
    # sample is a signed short in +/- 32768. 
    # normalize it to 1.0
        n = sample * (1.0/32768.0)
        sum_squares += n*n

    return math.sqrt( sum_squares / count )


def is_pulse(pulse_block):
    global last_pulse_timestamp

    amplitude = get_rms(pulse_block)

    if amplitude > PULSE_THRESHOLD:
        if get_current_timestamp() - last_pulse_timestamp >= MIN_SECONDS_BETWEEN_PULSES:

            return True

    return False


def get_current_timestamp():
    return time.time();


def get_pulse_stream(pyaudio_instance):

    return pyaudio_instance.open(
                format = pyaudio.paInt16,
                channels = 2,
                rate = RATE,
                input = True,
                frames_per_buffer = INPUT_FRAMES_PER_BLOCK
            )

def listen_for_pulses(pulse_stream):
    global last_pulse_timestamp, pulse_counter

    while True:
        try:
            pulse_block = pulse_stream.read(INPUT_FRAMES_PER_BLOCK)

            if is_pulse(pulse_block):
                last_pulse_timestamp = get_current_timestamp()

                pulse_counter += 1

                print 'pulse: ', pulse_counter


        except IOError, e:
            print( "Error recording: ", e)


"""
Program
"""

pAudio = pyaudio.PyAudio()

pulse_stream = get_pulse_stream(pAudio)

last_pulse_timestamp = 0
pulse_counter = 0

listen_for_pulses(pulse_stream)




Add initial code for pulse counting
Add initial code for pulse counting

Brief intro: my stationary bicycle *had* a measurement monitor with
speed, traveled kms, etc. However, it broke down. As my stationary bike
is quite old, I was not able to find a replacement (a good thing). I
noticed that the cable going from the rotor to the monitoring device has
a 3.5mm jack ending. I put it into the microphone slot on my computer
and started pedalling. I noticed that after each finished circle (round,
or candence or how it's called), it made a beeping or *pulsing* sound.
Long story short, I made a simple Python program that monitors the
microphone and tries to detect the *pulses*. If it detect the pulse, it
simply prints out "pulse". When you know the distance you traveled in
each *pulse*, you can calculate almost anything (speed, distance, etc).
I'm going to create a simple React-based UI for stationary bicycles
based on this discovery.

In this commit, I'm adding a simple python program to detect the pulses
form the stationary bicycle.
