-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathphoscyon_to_pattern.py
93 lines (72 loc) · 2.39 KB
/
phoscyon_to_pattern.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
"""
Convert Phoscyon patterns to 303 style patterns.
Author: @samvanstroud
Usage:
- set paths at the end of the script.
- run `python phoscyon_to_pattern.py`
"""
import os
import math
from pathlib import Path
import xml.etree.ElementTree as ET
import pandas as pd
from common import (
note_value_to_char,
note_default,
gate_default,
accent_default,
tie_default,
slide_default
)
def get_empty_pattern_df(n_steps):
"""
Create a DataFrame representing a blank pattern with n_steps.
"""
empty_columns={
'note' : [note_default]*n_steps,
'gate' : [gate_default]*n_steps,
'accent': [accent_default]*n_steps,
'slide' : [slide_default]*n_steps,
}
index = pd.Index(range(1, n_steps+1), name='step')
df = pd.DataFrame(empty_columns, index=index)
return df
def process_phoscyon_pattern(phos):
pat = get_empty_pattern_df(len(phos))
for i, step in enumerate(phos):
note = int(step.attrib['note'])
down = int(step.attrib['octaveDown'])
up = int(step.attrib['octaveUp'])
if down == up:
down = up = 0
if note < 0:
n_oct = math.ceil(abs(note) / 12)
note += 12*n_oct
down += n_oct
elif note >= 12:
n_oct = math.floor(abs(note) / 12)
note -= 12*n_oct
up += 1
pat.loc[i+1, 'note'] = note_value_to_char[note]
pat.loc[i+1, 'down'] = int(down)
pat.loc[i+1, 'up'] = int(up)
pat.loc[i+1, 'gate'] = int(step.attrib['gate'])
pat.loc[i+1, 'slide'] = int(step.attrib['slide'])
pat.loc[i+1, 'accent'] = int(step.attrib['accent'])
pat['down'] = pat['down'].astype(int)
pat['up'] = pat['up'].astype(int)
pat = pat[['note', 'up', 'down', 'gate', 'slide', 'accent']]
return pat
def process_phoscyon_patterns(filename, out_path):
if not os.path.exists(out_path):
Path(out_path).mkdir(parents=True, exist_ok=True)
tree = ET.parse(filename)
root = tree.getroot()
for i, child in enumerate(root):
print('Processing pattern', i)
pat = process_phoscyon_pattern(child)
pat.to_csv(os.path.join(out_path, str(i) + '.csv'))
if __name__ == "__main__":
in_path = '../data/raw/phoscyon_default.phptrb'
out_path = '../data/processed/phoscyon/'
process_phoscyon_patterns(in_path, out_path)