Spaces:
Sleeping
Sleeping
Add app.py
Browse files- app.py +11 -6
- hexachords.py +1 -1
app.py
CHANGED
|
@@ -13,6 +13,7 @@ from pydub import AudioSegment
|
|
| 13 |
|
| 14 |
import hexachords
|
| 15 |
|
|
|
|
| 16 |
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
| 17 |
# configure.run()
|
| 18 |
|
|
@@ -27,11 +28,14 @@ def is_fsynth_installed():
|
|
| 27 |
print('fluidsynth is NOT installed')
|
| 28 |
return False
|
| 29 |
|
| 30 |
-
def generate_chords(midi_pitches):
|
| 31 |
# Placeholder for your actual chord generation function
|
| 32 |
# Assuming hexachord is a list of MIDI note numbers
|
| 33 |
hexa = hexachords.Hexachord()
|
| 34 |
-
|
|
|
|
|
|
|
|
|
|
| 35 |
return cs1
|
| 36 |
|
| 37 |
def create_midi(chords):
|
|
@@ -54,6 +58,7 @@ def create_midi(chords):
|
|
| 54 |
mid.save(midi_path)
|
| 55 |
return midi_path
|
| 56 |
|
|
|
|
| 57 |
def convert_midi_to_audio(midi_path):
|
| 58 |
if not shutil.which("fluidsynth"):
|
| 59 |
try:
|
|
@@ -77,7 +82,6 @@ def convert_midi_to_audio(midi_path):
|
|
| 77 |
except Exception as e:
|
| 78 |
return f"Error converting MIDI to audio: {str(e)}"
|
| 79 |
|
| 80 |
-
|
| 81 |
def generate_piano_roll(chords):
|
| 82 |
fig, ax = plt.subplots(figsize=(8, 4))
|
| 83 |
|
|
@@ -112,7 +116,7 @@ def launch_score_editor(midi_path):
|
|
| 112 |
except Exception as e:
|
| 113 |
return f"Error opening score editor: {str(e)}"
|
| 114 |
|
| 115 |
-
def process_hexachord(hexachord_str):
|
| 116 |
try:
|
| 117 |
notes = [int(n) for n in hexachord_str.split()]
|
| 118 |
if len(notes) != 6 or len(set(notes)) != 6:
|
|
@@ -120,7 +124,7 @@ def process_hexachord(hexachord_str):
|
|
| 120 |
except ValueError:
|
| 121 |
return "Invalid input. Enter 6 MIDI note numbers separated by spaces."
|
| 122 |
|
| 123 |
-
chords = generate_chords(notes)
|
| 124 |
midi_path = create_midi(chords)
|
| 125 |
piano_roll_path = generate_piano_roll(chords)
|
| 126 |
audio_path = convert_midi_to_audio(midi_path)
|
|
@@ -132,6 +136,7 @@ with gr.Blocks() as ui:
|
|
| 132 |
gr.Markdown("# Hexachord-based Chord Generator")
|
| 133 |
|
| 134 |
hexachord_input = gr.Textbox(label="Enter 6 MIDI note numbers (separated by spaces)", value="60 62 64 65 67 69")
|
|
|
|
| 135 |
generate_button = gr.Button("Generate Chords")
|
| 136 |
midi_output = gr.File(label="Download MIDI File")
|
| 137 |
piano_roll_output = gr.Image(label="Piano Roll Visualization")
|
|
@@ -139,7 +144,7 @@ with gr.Blocks() as ui:
|
|
| 139 |
|
| 140 |
generate_button.click(
|
| 141 |
fn=process_hexachord,
|
| 142 |
-
inputs=[hexachord_input],
|
| 143 |
outputs=[midi_output, piano_roll_output, audio_output]
|
| 144 |
)
|
| 145 |
|
|
|
|
| 13 |
|
| 14 |
import hexachords
|
| 15 |
|
| 16 |
+
|
| 17 |
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
| 18 |
# configure.run()
|
| 19 |
|
|
|
|
| 28 |
print('fluidsynth is NOT installed')
|
| 29 |
return False
|
| 30 |
|
| 31 |
+
def generate_chords(midi_pitches, itvl):
|
| 32 |
# Placeholder for your actual chord generation function
|
| 33 |
# Assuming hexachord is a list of MIDI note numbers
|
| 34 |
hexa = hexachords.Hexachord()
|
| 35 |
+
interval_21 = 'P5'
|
| 36 |
+
if itvl == 'fourth':
|
| 37 |
+
interval_21 = 'P4'
|
| 38 |
+
cs1 = hexa.generate_chord_sequence_from_midi_pitches(midi_pitches, intrvl=interval_21)
|
| 39 |
return cs1
|
| 40 |
|
| 41 |
def create_midi(chords):
|
|
|
|
| 58 |
mid.save(midi_path)
|
| 59 |
return midi_path
|
| 60 |
|
| 61 |
+
|
| 62 |
def convert_midi_to_audio(midi_path):
|
| 63 |
if not shutil.which("fluidsynth"):
|
| 64 |
try:
|
|
|
|
| 82 |
except Exception as e:
|
| 83 |
return f"Error converting MIDI to audio: {str(e)}"
|
| 84 |
|
|
|
|
| 85 |
def generate_piano_roll(chords):
|
| 86 |
fig, ax = plt.subplots(figsize=(8, 4))
|
| 87 |
|
|
|
|
| 116 |
except Exception as e:
|
| 117 |
return f"Error opening score editor: {str(e)}"
|
| 118 |
|
| 119 |
+
def process_hexachord(hexachord_str, itvl):
|
| 120 |
try:
|
| 121 |
notes = [int(n) for n in hexachord_str.split()]
|
| 122 |
if len(notes) != 6 or len(set(notes)) != 6:
|
|
|
|
| 124 |
except ValueError:
|
| 125 |
return "Invalid input. Enter 6 MIDI note numbers separated by spaces."
|
| 126 |
|
| 127 |
+
chords = generate_chords(notes, itvl)
|
| 128 |
midi_path = create_midi(chords)
|
| 129 |
piano_roll_path = generate_piano_roll(chords)
|
| 130 |
audio_path = convert_midi_to_audio(midi_path)
|
|
|
|
| 136 |
gr.Markdown("# Hexachord-based Chord Generator")
|
| 137 |
|
| 138 |
hexachord_input = gr.Textbox(label="Enter 6 MIDI note numbers (separated by spaces)", value="60 62 64 65 67 69")
|
| 139 |
+
interval_switch = gr.Radio(choices=["fourth", "fifth"], label="Select Interval", value="fifth")
|
| 140 |
generate_button = gr.Button("Generate Chords")
|
| 141 |
midi_output = gr.File(label="Download MIDI File")
|
| 142 |
piano_roll_output = gr.Image(label="Piano Roll Visualization")
|
|
|
|
| 144 |
|
| 145 |
generate_button.click(
|
| 146 |
fn=process_hexachord,
|
| 147 |
+
inputs=[hexachord_input, interval_switch],
|
| 148 |
outputs=[midi_output, piano_roll_output, audio_output]
|
| 149 |
)
|
| 150 |
|
hexachords.py
CHANGED
|
@@ -4,7 +4,7 @@ from ortools.sat.python import cp_model
|
|
| 4 |
class Hexachord:
|
| 5 |
|
| 6 |
def generate_chord_sequence_from_midi_pitches(self, list_of_mp, intrvl="P5"):
|
| 7 |
-
return self.generate_chord_sequence([note.Note(mp).nameWithOctave for mp in list_of_mp])
|
| 8 |
|
| 9 |
def generate_chord_sequence(self, list_of_notes, intrvl="P5"):
|
| 10 |
|
|
|
|
| 4 |
class Hexachord:
|
| 5 |
|
| 6 |
def generate_chord_sequence_from_midi_pitches(self, list_of_mp, intrvl="P5"):
|
| 7 |
+
return self.generate_chord_sequence([note.Note(mp).nameWithOctave for mp in list_of_mp], intrvl=intrvl)
|
| 8 |
|
| 9 |
def generate_chord_sequence(self, list_of_notes, intrvl="P5"):
|
| 10 |
|