# simplified_meter_finding.py

## Greatly simplified version of Temperley's meter-finding model

`from music21 import converter`

Upper-level beats

`U = 0.95`

Tactus

`T = 0.74`

Lower-level beats

`L = 0.38`

dictionary of meter: (name, prior probability)

```meters = {(U, L, T, L): ('simple duple', 0.76 * 0.78),
(U, L, T, L, T, L): ('simple triple', 0.24 * 0.78),
(U, L, L, T, L, L): ('compound duple', 0.76 * 0.22)}```

Test rhythms given explicitly

```rhythm1 = [1, 0, 0, 1, 1, 0, 1, 0]
rhythm2 = [0, 1, 0, 0, 1, 1, 0, 1]
rhythm3 = [1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0,
1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]
rhythm4 = [1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0]```

Test rhythm derived from folksong

```url = 'http://kern.humdrum.org/cgi-bin/ksdata?file=magyar28.krn&l=' \
'essen/europa/magyar&format=kern'
song = converter.parse(url).flat.notes
total_duration = song.highestOffset + song[-1].quarterLength
rhythm5 = [0] * int(total_duration) * 2
for n in song:
rhythm5[int(n.offset * 2)] = 1```

Given a `meter` (in the dictionary `meters`), `offset`, and

`def meter_prob(meter, rhythm, offset, prior_prob=1):`

prior probability (`prior_prob`) of the meter, return probability of the `rhythm`.

```    total_prob = 1
for i, pulse in enumerate(rhythm):
prob = meter[(i + offset) % len(meter)]
if not pulse:
prob = 1 - prob
total_prob *= prob

Test model against all meters given above in all possible offsets

```rhythm = rhythm5 # try all six of the meters defined above
for meter in meters:
for offset in range(len(meter)):
print(meters[meter][0], 'offset= ', offset)
print(meter_prob(meter, rhythm, offset, prior_prob=meters[meter][1]))
print()```

Highest probabilities for the rhythms defined are:
`rhythm1`: simple duple, offset = 0
`rhythm2`: simple duple, offset = 3
`rhythm3`: simple triple, offset = 0
`rhythm4`: tied between simple duple, offset = 3 and compound duple, offset = 2 or 5
`rhythm5`: simple triple, offset = 5