cbg342 commited on
Commit
ac09a98
1 Parent(s): 88bea0d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +39 -13
app.py CHANGED
@@ -13,7 +13,8 @@ if 'history' not in st.session_state:
13
  if 'downloadable' not in st.session_state:
14
  st.session_state['downloadable'] = False
15
  notes = [['C'], ['Db', 'C#'], ['D'], ['Eb', 'D#'], ['E'], ['F'], ['Gb', 'F#'], ['G'], ['Ab', 'G#'], ['A'], ['Bb', 'A#'], ['B']]
16
- monster = r'(?<![A-Za-z\d])([A-G](?:#|b)?\d(?:-\d+(?:\/\d+)?(?:-\d+(?:\.\d+)?)?)+)(?![A-Za-z\d])'
 
17
 
18
  def noteToInt(n):
19
  oct = int(n[-1])
@@ -25,7 +26,7 @@ def noteToInt(n):
25
  id = ix
26
  return id+oct*12+12
27
 
28
- def midiToStr(mPath):
29
  midIn = mido.MidiFile(os.path.expanduser(mPath))
30
  ticks = midIn.ticks_per_beat
31
  midOut = []
@@ -40,19 +41,23 @@ def midiToStr(mPath):
40
  noteTime = int(noteTime) if noteTime.is_integer() else noteTime
41
  noteDur = str(Fraction((globalT-noteTime)/4))
42
  noteDur = str(round((globalT-noteTime),3)) if len(noteDur)>=6 else noteDur
43
- midOut.append('-'.join([notes[msg.note%12][0]+str(msg.note//12-1), noteDur, str(round(noteTime,3))]))
 
 
 
44
  del opens[msg.note]
45
  if msg.type == 'note_on':
46
  opens[msg.note] = globalT
47
  return ', '.join(midOut)
48
 
49
  st.markdown('# GPT-4 2 Midi\n#### AI Generated Polyphonic Music\n##### plus conversion tools for use with Chat-GPT\napp by [d3nt](https://github.com/d3n7/)')
 
50
  main, m2t, t2m = st.tabs(['GPT4-To-Midi', 'Midi-2-Text', 'Text-2-Midi'])
51
 
52
  with main:
53
  userPrompt = st.text_input('Prompt', 'Full piece of sad music with multiple parts. Plan out the structure beforehand, including chords, parts (soprano, alto, tenor, bass), meter, etc.')
54
  with st.expander('System Prompt'):
55
- sysPrompt = st.text_input('', 'You are MusicGPT, a music creation and completion chat bot that. When a user gives you a prompt, you return them a song showing the notes, durations, and times that they occur. Respond with just the music.\n\nNotation looks like this:\n(Note-duration-time in beats)\nC4-1/4-0, Eb4-1/8-2.5, D4-1/4-3, F4-1/4-3 etc.')
56
  openaikey = st.text_input('OpenAI API Key', type='password')
57
  modelV = st.selectbox('Model', ('GPT-4', 'GPT-3.5-Turbo'))
58
  col1, col2 = st.columns(2)
@@ -65,8 +70,10 @@ with main:
65
  with col3:
66
  if st.button('Ask GPT'):
67
  if userPrompt != '' and sysPrompt != '' and openaikey != '':
 
 
68
  if newSession:
69
- st.session_state['history'] = [{'role': 'system', 'content': sysPrompt}]
70
 
71
  prompt = userPrompt
72
  if uploadMidi:
@@ -74,7 +81,7 @@ with main:
74
  midiPath = os.path.join(st.session_state['path'], filename)
75
  with open(midiPath, 'wb') as f:
76
  f.write(uploadMidi.getbuffer())
77
- prompt += '\n'+midiToStr(midiPath)
78
  os.remove(midiPath)
79
  st.session_state['history'].append({'role': 'user', 'content': prompt})
80
 
@@ -88,14 +95,23 @@ with main:
88
  st.session_state['history'].append({'role': 'assistant', 'content': response})
89
 
90
  noteInfo = []
91
- for i in re.findall(monster, response):
92
  n = i.split('-')
93
- noteInfo.append([noteToInt(n[0]), float(Fraction(n[1])) * 4, float(n[2])]) #note, duration, time
 
 
 
94
 
95
  song = MIDIFile(1, deinterleave=False)
 
96
  for i in noteInfo:
97
- pitch, dur, time = i
 
 
 
98
  song.addNote(0, 0, pitch, time, dur, 100)
 
 
99
  with open(os.path.join(st.session_state['path'], 'output.mid'), 'wb') as f:
100
  song.writeFile(f)
101
  if not st.session_state['downloadable']:
@@ -119,20 +135,30 @@ with m2t:
119
  midiPath = os.path.join(st.session_state['path'], filename)
120
  with open(midiPath, 'wb') as f:
121
  f.write(inMidi.getbuffer())
122
- st.text_area('Output', midiToStr(midiPath))
123
  os.remove(midiPath)
124
 
125
  with t2m:
126
  inText = st.text_input('Input')
127
  if st.button('Convert', key='2'):
 
128
  noteInfo = []
129
- for i in re.findall(monster, inText):
130
  n = i.split('-')
131
- noteInfo.append([noteToInt(n[0]), float(Fraction(n[1])) * 4, float(n[2])])
 
 
 
132
  song = MIDIFile(1, deinterleave=False)
 
133
  for i in noteInfo:
134
- pitch, dur, time = i
 
 
 
135
  song.addNote(0, 0, pitch, time, dur, 100)
 
 
136
  with open(os.path.join(st.session_state['path'], 't2m.mid'), 'wb') as f:
137
  song.writeFile(f)
138
  with open(os.path.join(st.session_state['path'], 't2m.mid'), 'rb') as f:
 
13
  if 'downloadable' not in st.session_state:
14
  st.session_state['downloadable'] = False
15
  notes = [['C'], ['Db', 'C#'], ['D'], ['Eb', 'D#'], ['E'], ['F'], ['Gb', 'F#'], ['G'], ['Ab', 'G#'], ['A'], ['Bb', 'A#'], ['B']]
16
+ monsters = [r'(?<![A-Za-z\d])([A-G](?:#|b)?\d-(?:\d+\/\d+|\d+))(?![A-Za-z\d])', r'(?<![A-Za-z\d])([A-G](?:#|b)?\d(?:-\d+(?:\/\d+)?(?:-\d+(?:\.\d+)?)?)+)(?![A-Za-z\d])']
17
+ examples = ['\n\nNotation looks like this:\n(Note-duration)\nC4-1/4, Eb4-1/4, D4-1/8, Eb4-1/8, C4-1/4', '\n\nNotation looks like this:\n(Note-duration-time in beats)\nC4-1/4-0, Eb4-1/8-2.5, D4-1/4-3, F4-1/4-3 etc.']
18
 
19
  def noteToInt(n):
20
  oct = int(n[-1])
 
26
  id = ix
27
  return id+oct*12+12
28
 
29
+ def midiToStr(mPath, nIndex):
30
  midIn = mido.MidiFile(os.path.expanduser(mPath))
31
  ticks = midIn.ticks_per_beat
32
  midOut = []
 
41
  noteTime = int(noteTime) if noteTime.is_integer() else noteTime
42
  noteDur = str(Fraction((globalT-noteTime)/4))
43
  noteDur = str(round((globalT-noteTime),3)) if len(noteDur)>=6 else noteDur
44
+ if nIndex:
45
+ midOut.append('-'.join([notes[msg.note%12][0]+str(msg.note//12-1), noteDur, str(round(noteTime,3))]))
46
+ else:
47
+ midOut.append('-'.join([notes[msg.note%12][0]+str(msg.note//12-1), noteDur]))
48
  del opens[msg.note]
49
  if msg.type == 'note_on':
50
  opens[msg.note] = globalT
51
  return ', '.join(midOut)
52
 
53
  st.markdown('# GPT-4 2 Midi\n#### AI Generated Polyphonic Music\n##### plus conversion tools for use with Chat-GPT\napp by [d3nt](https://github.com/d3n7/)')
54
+ notation = st.selectbox('Notation', ('Polyphonic', 'Monophonic'))
55
  main, m2t, t2m = st.tabs(['GPT4-To-Midi', 'Midi-2-Text', 'Text-2-Midi'])
56
 
57
  with main:
58
  userPrompt = st.text_input('Prompt', 'Full piece of sad music with multiple parts. Plan out the structure beforehand, including chords, parts (soprano, alto, tenor, bass), meter, etc.')
59
  with st.expander('System Prompt'):
60
+ sysPrompt = st.text_input('', 'You are MusicGPT, a music creation and completion chat bot that. When a user gives you a prompt, you return them a song showing the notes, durations, and times that they occur. Respond with just the music.')
61
  openaikey = st.text_input('OpenAI API Key', type='password')
62
  modelV = st.selectbox('Model', ('GPT-4', 'GPT-3.5-Turbo'))
63
  col1, col2 = st.columns(2)
 
70
  with col3:
71
  if st.button('Ask GPT'):
72
  if userPrompt != '' and sysPrompt != '' and openaikey != '':
73
+ notationIndex = int(notation=='Polyphonic')
74
+
75
  if newSession:
76
+ st.session_state['history'] = [{'role': 'system', 'content': sysPrompt+examples[notationIndex]}]
77
 
78
  prompt = userPrompt
79
  if uploadMidi:
 
81
  midiPath = os.path.join(st.session_state['path'], filename)
82
  with open(midiPath, 'wb') as f:
83
  f.write(uploadMidi.getbuffer())
84
+ prompt += '\n'+midiToStr(midiPath, notationIndex)
85
  os.remove(midiPath)
86
  st.session_state['history'].append({'role': 'user', 'content': prompt})
87
 
 
95
  st.session_state['history'].append({'role': 'assistant', 'content': response})
96
 
97
  noteInfo = []
98
+ for i in re.findall(monsters[notationIndex], response):
99
  n = i.split('-')
100
+ if notationIndex:
101
+ noteInfo.append([noteToInt(n[0]), float(Fraction(n[1]))*4, float(n[2])]) #note, duration, time
102
+ else:
103
+ noteInfo.append([noteToInt(n[0]), float(Fraction(n[1]))*4]) # note, duration
104
 
105
  song = MIDIFile(1, deinterleave=False)
106
+ time = 0
107
  for i in noteInfo:
108
+ if notationIndex:
109
+ pitch, dur, time = i
110
+ else:
111
+ pitch, dur = i
112
  song.addNote(0, 0, pitch, time, dur, 100)
113
+ if not notationIndex:
114
+ time += dur
115
  with open(os.path.join(st.session_state['path'], 'output.mid'), 'wb') as f:
116
  song.writeFile(f)
117
  if not st.session_state['downloadable']:
 
135
  midiPath = os.path.join(st.session_state['path'], filename)
136
  with open(midiPath, 'wb') as f:
137
  f.write(inMidi.getbuffer())
138
+ st.text_area('Output', midiToStr(midiPath, notation=='Polyphonic'))
139
  os.remove(midiPath)
140
 
141
  with t2m:
142
  inText = st.text_input('Input')
143
  if st.button('Convert', key='2'):
144
+ notationIndex = int(notation=='Polyphonic')
145
  noteInfo = []
146
+ for i in re.findall(monsters[notationIndex], inText):
147
  n = i.split('-')
148
+ if notationIndex:
149
+ noteInfo.append([noteToInt(n[0]), float(Fraction(n[1])) * 4, float(n[2])]) # note, duration, time
150
+ else:
151
+ noteInfo.append([noteToInt(n[0]), float(Fraction(n[1])) * 4]) # note, duration
152
  song = MIDIFile(1, deinterleave=False)
153
+ time = 0
154
  for i in noteInfo:
155
+ if notationIndex:
156
+ pitch, dur, time = i
157
+ else:
158
+ pitch, dur = i
159
  song.addNote(0, 0, pitch, time, dur, 100)
160
+ if not notationIndex:
161
+ time += dur
162
  with open(os.path.join(st.session_state['path'], 't2m.mid'), 'wb') as f:
163
  song.writeFile(f)
164
  with open(os.path.join(st.session_state['path'], 't2m.mid'), 'rb') as f: