pachet commited on
Commit
80af22a
·
1 Parent(s): b03b6c6

trying midi api

Browse files
Files changed (2) hide show
  1. app.py +148 -4
  2. app_basic.py +7 -0
app.py CHANGED
@@ -1,7 +1,151 @@
1
  import gradio as gr
 
 
 
2
 
3
- def greet(name):
4
- return "Hello " + name + "!!"
5
 
6
- demo = gr.Interface(fn=greet, inputs="text", outputs="text")
7
- demo.launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import gradio as gr
2
+ import json
3
+ from flask import Flask, request, jsonify
4
+ import threading
5
 
6
+ # Flask app for MIDI handling
7
+ from flask_cors import CORS
8
 
9
+ app = Flask(__name__)
10
+ CORS(app, resources={r"/*": {"origins": "*"}}) # Allow all origins
11
+
12
+
13
+ # Shared MIDI data with thread lock
14
+ midi_data = {"note": "-", "velocity": "-", "timestamp": "-"}
15
+ midi_lock = threading.Lock() # Lock for thread-safe access
16
+
17
+ @app.route("/midi_input", methods=["POST"])
18
+ def midi_input():
19
+ """Handles incoming MIDI data from JavaScript."""
20
+ global midi_data
21
+ data = request.json # Get MIDI data from JavaScript
22
+ with midi_lock: # Ensure thread-safe update
23
+ midi_data = {
24
+ "note": data.get("note", "-"),
25
+ "velocity": data.get("velocity", "-"),
26
+ "timestamp": data.get("timestamp", "-")
27
+ }
28
+ print(f"Received MIDI: {midi_data}")
29
+
30
+ # Example processing: Transpose note up by 2 semitones
31
+ processed_note = (int(midi_data["note"]) + 2) % 128
32
+
33
+ return jsonify({"processed_note": processed_note})
34
+
35
+
36
+ # Start Flask server in a separate thread
37
+ def run_flask():
38
+ app.run(port=5000, debug=False, use_reloader=False)
39
+
40
+
41
+ threading.Thread(target=run_flask, daemon=True).start()
42
+
43
+ # JavaScript Code for MIDI Handling (Embedded)
44
+ midi_js = """
45
+ <script>
46
+ let midiAccess;
47
+ let selectedInput = null;
48
+ let selectedOutput = null;
49
+
50
+ // Function to handle MIDI messages
51
+ function handleMIDIMessage(event) {
52
+ let data = {
53
+ note: event.data[1], // MIDI Note Number
54
+ velocity: event.data[2], // Note Velocity
55
+ timestamp: event.timeStamp
56
+ };
57
+
58
+ // Send MIDI data to Python backend
59
+ fetch("http://127.0.0.1:5000/midi_input", {
60
+ method: "POST",
61
+ body: JSON.stringify(data),
62
+ headers: { "Content-Type": "application/json" }
63
+ }).then(response => response.json())
64
+ .then(processed => console.log("Processed MIDI:", processed));
65
+ window.postMessage(data, "*");
66
+
67
+ }
68
+
69
+ // Function to update available MIDI devices
70
+ function updateMIDIDevices() {
71
+ let inputSelect = document.getElementById("midiInput");
72
+ let outputSelect = document.getElementById("midiOutput");
73
+
74
+ inputSelect.innerHTML = '<option value="">Select MIDI Input</option>';
75
+ outputSelect.innerHTML = '<option value="">Select MIDI Output</option>';
76
+
77
+ midiAccess.inputs.forEach((input, key) => {
78
+ let option = document.createElement("option");
79
+ option.value = key;
80
+ option.textContent = input.name;
81
+ inputSelect.appendChild(option);
82
+ });
83
+
84
+ midiAccess.outputs.forEach((output, key) => {
85
+ let option = document.createElement("option");
86
+ option.value = key;
87
+ option.textContent = output.name;
88
+ outputSelect.appendChild(option);
89
+ });
90
+ }
91
+
92
+ // Function to handle input selection
93
+ function selectMIDIInput() {
94
+ let inputSelect = document.getElementById("midiInput");
95
+ let inputId = inputSelect.value;
96
+
97
+ if (selectedInput) {
98
+ selectedInput.onmidimessage = null;
99
+ }
100
+
101
+ if (inputId && midiAccess.inputs.has(inputId)) {
102
+ selectedInput = midiAccess.inputs.get(inputId);
103
+ selectedInput.onmidimessage = handleMIDIMessage;
104
+ console.log(`MIDI Input selected: ${selectedInput.name}`);
105
+ }
106
+ }
107
+
108
+ // Function to handle output selection
109
+ function selectMIDIOutput() {
110
+ let outputSelect = document.getElementById("midiOutput");
111
+ let outputId = outputSelect.value;
112
+
113
+ if (outputId && midiAccess.outputs.has(outputId)) {
114
+ selectedOutput = midiAccess.outputs.get(outputId);
115
+ console.log(`MIDI Output selected: ${selectedOutput.name}`);
116
+ }
117
+ }
118
+
119
+ // Request MIDI Access
120
+ navigator.requestMIDIAccess()
121
+ .then(access => {
122
+ midiAccess = access;
123
+ updateMIDIDevices();
124
+ midiAccess.onstatechange = updateMIDIDevices;
125
+ })
126
+ .catch(err => console.log("MIDI API Error: ", err));
127
+ </script>
128
+
129
+ <!-- MIDI Input and Output Selection -->
130
+ <div>
131
+ <label for="midiInput">MIDI Input: </label>
132
+ <select id="midiInput" onchange="selectMIDIInput()"></select>
133
+
134
+ <label for="midiOutput">MIDI Output: </label>
135
+ <select id="midiOutput" onchange="selectMIDIOutput()"></select>
136
+ </div>
137
+ """
138
+
139
+
140
+ # Gradio UI
141
+ def display_midi():
142
+ """Returns real-time MIDI data for display in Gradio."""
143
+ return f"Note: {midi_data['note']}, Velocity: {midi_data['velocity']}"
144
+
145
+
146
+ with gr.Blocks() as demo:
147
+ gr.HTML(midi_js) # Inject JavaScript into the Gradio UI
148
+ gr.Interface(fn=display_midi, inputs=[], outputs="text", live=True)
149
+
150
+ # Launch Gradio
151
+ demo.launch(share=True, server_port=7860)
app_basic.py ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+
3
+ def greet(name):
4
+ return "Hello " + name + "!!"
5
+
6
+ demo = gr.Interface(fn=greet, inputs="text", outputs="text")
7
+ demo.launch()