naotokui commited on
Commit
51a05e3
1 Parent(s): c7024d9

initial import

Browse files
Files changed (1) hide show
  1. app.py +132 -0
app.py ADDED
@@ -0,0 +1,132 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #%%
2
+ import openai
3
+ import numpy as np
4
+ import pretty_midi
5
+ import re
6
+ import numpy as np
7
+
8
+ # sample data
9
+ markdown_table_sample = """4
10
+
11
+ | | 1 | 2 | 3 | 4 |
12
+ |----|---|---|---|---|
13
+ | BD | | | x | |
14
+ | SD | | | | x |
15
+ | CH | x | | x | |
16
+ | OH | | | | x |
17
+ | LT | | | | |
18
+ | MT | | x | | |
19
+ | HT | x | | | x |
20
+ """
21
+
22
+ markdown_table_sample2 = """8
23
+
24
+ | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
25
+ |----|---|---|---|---|---|---|---|---|
26
+ | BD | | | x | | | | x | |
27
+ | SD | | | | x | | | | x |
28
+ | CH | x | | x | | x | | x | |
29
+ | OH | | | | x | | | x | |
30
+ | LT | | | | | | x | | |
31
+ | MT | | x | | | x | | | |
32
+ | HT | x | | | x | | | | |
33
+ """
34
+
35
+ MIDI_NOTENUM = {
36
+ "BD": 36,
37
+ "SD": 38,
38
+ "CH": 42,
39
+ "HH": 42,
40
+ "OH": 46,
41
+ "LT": 48,
42
+ "MT": 48,
43
+ "HT": 50,
44
+ "CP": 50,
45
+ }
46
+ SR = 44100
47
+
48
+ count = 0
49
+ MAX_QUERY = 100
50
+
51
+ def convert_table_to_audio(markdown_table, resolution=8, bpm = 120.0):
52
+ # convert table to array
53
+ rhythm_pattern = []
54
+ for line in markdown_table.split('\n')[2:]:
55
+ rhythm_pattern.append(line.split('|')[1:-1])
56
+ print(rhythm_pattern)
57
+
58
+ # table to MIDI
59
+ pm = pretty_midi.PrettyMIDI(initial_tempo=bpm) # midi object
60
+ pm_inst = pretty_midi.Instrument(0, is_drum=True) # midi instrument
61
+ pm.instruments.append(pm_inst)
62
+
63
+ note_length = (60. / bpm) * (4.0 / resolution) # ノートの長さ(ミリ秒)
64
+
65
+ for i in range(len(rhythm_pattern)):
66
+ for j in range(1, len(rhythm_pattern[i])):
67
+ inst = rhythm_pattern[i][0].strip().upper()
68
+ if 'x' == rhythm_pattern[i][j].strip():
69
+ if inst in MIDI_NOTENUM.keys():
70
+ midinote = MIDI_NOTENUM[inst]
71
+ note = pretty_midi.Note(velocity=80, pitch=midinote, start=note_length * (j-1)+0.05, end=note_length * j)
72
+ pm_inst.notes.append(note)
73
+
74
+ # convert to audio
75
+ audio_data = pm.fluidsynth()
76
+
77
+ # cut off the reverb section
78
+ audio_data = audio_data[:int(SR*note_length*resolution)]
79
+ return audio_data
80
+
81
+ def get_answer(question):
82
+ response = openai.ChatCompletion.create(
83
+ model="gpt-3.5-turbo",
84
+ messages=[
85
+ {"role": "system", "content": "You are a rhythm generator. You generate rhythm patterns with the resolution of the 8th note"},
86
+ {"role": "user", "content": "Please generate a rhythm pattern. You use the following drums. Kick drum:BD, Snare drum:SD, Closed-hihat:CH, Open-hihat:OH, Low-tom:LT, Mid-tom:MT, High-tom:HT。You need to write the time resolution first."},
87
+ {"role": "assistant", "content": markdown_table_sample2},
88
+ # {"role": "user", "content": "4分音符単位で生成して下さい. ドラムはBD, SD, CH, OH, LT, MT, HTを使います。最初に時間解像度の逆数を書いて下さい"},
89
+ # {"role": "assistant", "content": markdown_table_sample},
90
+ {"role": "user", "content": question}
91
+ ]
92
+ )
93
+ return response["choices"][0]["message"]["content"]
94
+
95
+ def generate_rhythm(query):
96
+ global count
97
+ count += 1
98
+ if count > MAX_QUERY:
99
+ return [None, "Now you can try up to %d times" % MAX_QUERY]
100
+
101
+ # get respance from ChatGPT
102
+ text_output = get_answer(query)
103
+
104
+ # Try to use the first row as time resolution
105
+ resolution_text = text_output.split('|')[0]
106
+ try:
107
+ resolution_text = re.findall(r'\d+', resolution_text)[0]
108
+ resolution = int(resolution_text)
109
+ except:
110
+ resolution = 8 # default
111
+
112
+ # Extract rhythm table
113
+ table = "|" + "|".join(text_output.split('|')[1:-1]) + "|"
114
+ audio_data = convert_table_to_audio(table, resolution)
115
+
116
+ # loop x2
117
+ audio_data = np.tile(audio_data, 4)
118
+
119
+ return [(SR, audio_data), text_output]
120
+ # %%
121
+
122
+ import gradio as gr
123
+
124
+ demo = gr.Interface(
125
+ fn=generate_rhythm,
126
+ inputs=gr.Textbox(label="command",show_label=True, placeholder="Generate a typical 8-beat rhythm!", visible=True).style(container=False),
127
+ outputs=["audio", "text"]
128
+ )
129
+ demo.launch()
130
+ # %%
131
+
132
+ # %%