Getting stretch ratios for each step


In [14]:
# Imports
%matplotlib inline
import pardir; pardir.pardir() # Allow imports from parent directory
import fibonaccistretch as fib
import bjorklund

In [3]:
# Setting up basics
original_rhythm = [1,0,0,1,0,0,1,0]
target_rhythm = [1,0,0,0,0,1,0,0,0,0,1,0,0]

In [5]:
fib.calculate_pulse_ratios(original_rhythm, target_rhythm)


Out[5]:
array([ 0.6       ,  0.6       ,  0.66666667])

In [6]:
fib.calculate_pulse_lengths(original_rhythm)


Out[6]:
array([3, 3, 2])

In [10]:
fib.calculate_pulse_ratios([1]*len(original_rhythm), target_rhythm)


Out[10]:
array([ 0.2       ,  0.2       ,  0.33333333])

In [7]:
[1]*8


Out[7]:
[1, 1, 1, 1, 1, 1, 1, 1]

In [11]:
fib.calculate_pulse_lengths(target_rhythm)


Out[11]:
array([5, 5, 3])

In [18]:
# Original and target pulse lengths; just take the first one from each for now
opl = fib.calculate_pulse_lengths(original_rhythm)[0]
tpl = fib.calculate_pulse_lengths(target_rhythm)[0]

# Adapted from Euclidean stretch
opr = [1] * len(original_rhythm)

# Generate target pulse rhythm ("tpr")
tpr = bjorklund.bjorklund(pulses=opl, steps=tpl)
tpr_pulse_lengths = fib.calculate_pulse_lengths(tpr)
tpr_pulse_ratios = fib.calculate_pulse_ratios(opr, tpr)

tpr_pulse_ratios


Out[18]:
array([ 0.5,  0.5,  1. ])

In [21]:
# Format pulse ratios so there's one for each step
original_pulse_lengths = fib.calculate_pulse_lengths(original_rhythm)
pulse_ratios = fib.calculate_pulse_ratios(original_rhythm, target_rhythm)
pulse_ratios_by_step = []
for i,pulse_length in enumerate(original_pulse_lengths):
    for _ in range(pulse_length):
        pulse_ratios_by_step.append(pulse_ratios[i])
pulse_ratios_by_step


Out[21]:
[0.59999999999999998,
 0.59999999999999998,
 0.59999999999999998,
 0.59999999999999998,
 0.59999999999999998,
 0.59999999999999998,
 0.66666666666666663,
 0.66666666666666663]

Putting it all together!


In [88]:
def calculate_step_stretch_ratios(original_rhythm, target_rhythm):
    # Original and target pulse lengths
    original_pulse_lengths = fib.calculate_pulse_lengths(original_rhythm)
    target_pulse_lengths = fib.calculate_pulse_lengths(target_rhythm)

    # Pulse ratios
    # Format pulse ratios so there's one for each step
    pulse_ratios = fib.calculate_pulse_ratios(original_rhythm, target_rhythm)
    pulse_ratios_by_step = []
    for i,pulse_length in enumerate(original_pulse_lengths):
        for _ in range(pulse_length):
            pulse_ratios_by_step.append(pulse_ratios[i])

    # Calculate stretch ratios for each original step
    # Adapted from Euclidean stretch
    step_stretch_ratios = []
    for i in range(min(len(original_pulse_lengths), len(target_pulse_lengths))):
        # Pulse lengths
        opl = original_pulse_lengths[i]
        tpl = target_pulse_lengths[i]

        # Use steps as original pulse rhythm ("opr")
        opr = [1] * len(original_rhythm)

        # Generate target pulse rhythm ("tpr") using Bjorklund's algorithm
        tpr = bjorklund.bjorklund(pulses=opl, steps=tpl)
        tpr_pulse_lengths = fib.calculate_pulse_lengths(tpr)
        tpr_pulse_ratios = fib.calculate_pulse_ratios(opr, tpr)

        # Scale the tpr pulse ratios by the corresponding ratio from pulse_ratios_by_step
        tpr_pulse_ratios *= pulse_ratios_by_step[i]

        step_stretch_ratios.extend(tpr_pulse_ratios)
    
    return step_stretch_ratios

step_stretch_ratios = calculate_step_stretch_ratios(original_rhythm, target_rhythm)
step_stretch_ratios


Out[88]:
[0.29999999999999999,
 0.29999999999999999,
 0.59999999999999998,
 0.29999999999999999,
 0.29999999999999999,
 0.59999999999999998,
 0.59999999999999998,
 0.29999999999999999]

In [55]:
sum(step_stretch_ratios) / len(original_rhythm)


Out[55]:
0.41249999999999998

In [56]:
step_stretch_ratios = calculate_step_stretch_ratios(original_rhythm, original_rhythm)
step_stretch_ratios


Out[56]:
[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]

In [57]:
sum(step_stretch_ratios) / len(original_rhythm)


Out[57]:
1.0

The sum divided by length should add up to 1...

Maybe we need to subdivide it further?

Or oh there's the "stretch multiplier"


In [63]:



[ 0.5  0.5  1. ]
[ 0.5  0.5  1. ]
[ 1.   0.5]
Out[63]:
[0.29999999999999999,
 0.29999999999999999,
 0.59999999999999998,
 0.29999999999999999,
 0.29999999999999999,
 0.59999999999999998,
 0.59999999999999998,
 0.29999999999999999]

In [89]:
stretch_multiplier = 1.0 / (sum(step_stretch_ratios) / len(original_rhythm))
stretch_multiplier


Out[89]:
2.4242424242424243

In [90]:
step_stretch_ratios = [r * stretch_multiplier for r in step_stretch_ratios]
step_stretch_ratios


Out[90]:
[0.72727272727272729,
 0.72727272727272729,
 1.4545454545454546,
 0.72727272727272729,
 0.72727272727272729,
 1.4545454545454546,
 1.4545454545454546,
 0.72727272727272729]

In [91]:
sum(step_stretch_ratios) / len(original_rhythm)


Out[91]:
1.0

OK, so revised with stretch_multiplier:


In [137]:
def calculate_step_stretch_ratios(original_rhythm, target_rhythm):
    # Original and target pulse lengths
    original_pulse_lengths = list(fib.calculate_pulse_lengths(original_rhythm))
    target_pulse_lengths = list(fib.calculate_pulse_lengths(target_rhythm))

    # Pulse ratios
    # Format pulse ratios so there's one for each step
    pulse_ratios = list(fib.calculate_pulse_ratios(original_rhythm, target_rhythm))
    if len(pulse_ratios) < len(original_pulse_lengths):  # Add 0s to pulse ratios if there aren't enough
        for _ in range(len(original_pulse_lengths) - len(pulse_ratios)):
            pulse_ratios.append(0.0)
    assert(len(pulse_ratios) == len(original_pulse_lengths))
    pulse_ratios_by_step = []
    for i,pulse_length in enumerate(original_pulse_lengths):
        for _ in range(pulse_length):
            pulse_ratios_by_step.append(pulse_ratios[i])

    # Calculate stretch ratios for each original step
    # Adapted from Euclidean stretch
    step_stretch_ratios = []
    for i in range(min(len(original_pulse_lengths), len(target_pulse_lengths))):
        # Pulse lengths
        opl = original_pulse_lengths[i]
        tpl = target_pulse_lengths[i]
        
        # Adjust target pulse length if it's too small
        #if opl > tpl:
        #    tpl = opl
        while opl > tpl:
           tpl *= 2

        # Use steps as original pulse rhythm ("opr")
        opr = [1] * len(original_rhythm)

        # Generate target pulse rhythm ("tpr") using Bjorklund's algorithm
        tpr = bjorklund.bjorklund(pulses=opl, steps=tpl)
        tpr_pulse_lengths = fib.calculate_pulse_lengths(tpr)
        tpr_pulse_ratios = fib.calculate_pulse_ratios(opr, tpr)

        # Scale the tpr pulse ratios by the corresponding ratio from pulse_ratios_by_step
        tpr_pulse_ratios *= pulse_ratios_by_step[i]

        step_stretch_ratios.extend(tpr_pulse_ratios)
        
    # Multiply by stretch multiplier to make sure the length is the same as original
    stretch_multiplier = 1.0 / (sum(step_stretch_ratios) / len(original_rhythm))
    step_stretch_ratios = [r * stretch_multiplier for r in step_stretch_ratios]
    assert(round(sum(step_stretch_ratios) / len(original_rhythm), 5) == 1)  # Make sure it's *close enough* to original length.
    
    return step_stretch_ratios

step_stretch_ratios = calculate_step_stretch_ratios(original_rhythm, target_rhythm)
step_stretch_ratios


Out[137]:
[0.72727272727272729,
 0.72727272727272729,
 1.4545454545454546,
 0.72727272727272729,
 0.72727272727272729,
 1.4545454545454546,
 1.4545454545454546,
 0.72727272727272729]

In [138]:
calculate_step_stretch_ratios(original_rhythm, [1,0,1])
# fib.calculate_pulse_ratios(original_rhythm, [1,0,1])


Out[138]:
[1.6000000000000001,
 1.6000000000000001,
 0.80000000000000004,
 1.6000000000000001,
 1.6000000000000001,
 0.80000000000000004]

In [120]:
round?

In [139]:
reload(fib)


Out[139]:
<module 'fibonaccistretch' from '/Users/usdivad/Documents/tech/fibonacciswing/nbs/../fibonaccistretch.py'>

In [135]:
# import numpy as np
# a = np.array(original_rhythm)
# b = np.zeros(4)
# np.hstack((a, b))


Out[135]:
array([ 1.,  0.,  0.,  1.,  0.,  0.,  1.,  0.,  0.,  0.,  0.,  0.])

In [140]:
fib.calculate_step_stretch_ratios(original_rhythm, target_rhythm)


Out[140]:
[0.72727272727272729,
 0.72727272727272729,
 1.4545454545454546,
 0.72727272727272729,
 0.72727272727272729,
 1.4545454545454546,
 1.4545454545454546,
 0.72727272727272729]

In [ ]: