harrytarlton commited on
Commit
837e6b5
·
1 Parent(s): 98069a3
Files changed (2) hide show
  1. app.py +355 -56
  2. requirements.txt +3 -0
app.py CHANGED
@@ -1,70 +1,369 @@
1
  import gradio as gr
2
- from huggingface_hub import InferenceClient
3
-
4
-
5
- def respond(
6
- message,
7
- history: list[dict[str, str]],
8
- system_message,
9
- max_tokens,
10
- temperature,
11
- top_p,
12
- hf_token: gr.OAuthToken,
13
- ):
14
- """
15
- For more information on `huggingface_hub` Inference API support, please check the docs: https://huggingface.co/docs/huggingface_hub/v0.22.2/en/guides/inference
16
- """
17
- client = InferenceClient(token=hf_token.token, model="openai/gpt-oss-20b")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
 
19
- messages = [{"role": "system", "content": system_message}]
 
 
 
20
 
21
- messages.extend(history)
 
 
 
 
22
 
23
- messages.append({"role": "user", "content": message})
 
 
 
 
 
 
 
24
 
25
- response = ""
 
 
 
 
 
 
 
 
 
26
 
27
- for message in client.chat_completion(
28
- messages,
29
- max_tokens=max_tokens,
30
- stream=True,
31
- temperature=temperature,
32
- top_p=top_p,
33
- ):
34
- choices = message.choices
35
- token = ""
36
- if len(choices) and choices[0].delta.content:
37
- token = choices[0].delta.content
38
 
39
- response += token
40
- yield response
 
 
41
 
 
 
 
 
 
42
 
 
 
 
 
 
 
 
 
 
 
 
43
  """
44
- For information on how to customize the ChatInterface, peruse the gradio docs: https://www.gradio.app/docs/chatinterface
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  """
46
- chatbot = gr.ChatInterface(
47
- respond,
48
- type="messages",
49
- additional_inputs=[
50
- gr.Textbox(value="You are a friendly Chatbot.", label="System message"),
51
- gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Max new tokens"),
52
- gr.Slider(minimum=0.1, maximum=4.0, value=0.7, step=0.1, label="Temperature"),
53
- gr.Slider(
54
- minimum=0.1,
55
- maximum=1.0,
56
- value=0.95,
57
- step=0.05,
58
- label="Top-p (nucleus sampling)",
59
- ),
60
- ],
61
- )
62
-
63
- with gr.Blocks() as demo:
64
- with gr.Sidebar():
65
- gr.LoginButton()
66
- chatbot.render()
67
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
 
69
  if __name__ == "__main__":
70
- demo.launch()
 
1
  import gradio as gr
2
+ import json
3
+ from datetime import datetime
4
+ from pathlib import Path
5
+
6
+ # Clean, simple CSS
7
+ custom_css = """
8
+ /* Clean modern design */
9
+ .gradio-container {
10
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
11
+ background: #1a1a2e;
12
+ color: #eee;
13
+ }
14
+
15
+ /* File panel styling */
16
+ .file-panel {
17
+ background: #16213e !important;
18
+ border-right: 1px solid #0f3460;
19
+ height: 100vh;
20
+ overflow: hidden;
21
+ display: flex;
22
+ flex-direction: column;
23
+ }
24
+
25
+ /* File panel header */
26
+ .file-panel-header {
27
+ background: #0f3460;
28
+ padding: 15px;
29
+ border-bottom: 2px solid #e94560;
30
+ display: flex;
31
+ align-items: center;
32
+ gap: 10px;
33
+ }
34
+
35
+ /* File list styling */
36
+ .file-list {
37
+ flex: 1;
38
+ overflow-y: auto;
39
+ padding: 10px;
40
+ }
41
+
42
+ .file-item {
43
+ background: #0f3460;
44
+ margin: 5px 0;
45
+ padding: 12px;
46
+ border-radius: 6px;
47
+ cursor: pointer;
48
+ transition: all 0.2s;
49
+ display: flex;
50
+ align-items: center;
51
+ gap: 10px;
52
+ }
53
+
54
+ .file-item:hover {
55
+ background: #e94560;
56
+ transform: translateX(5px);
57
+ }
58
 
59
+ .file-item.selected {
60
+ background: #e94560;
61
+ border-left: 4px solid #f47068;
62
+ }
63
 
64
+ /* Main content area */
65
+ .main-content {
66
+ padding: 30px;
67
+ background: #1a1a2e;
68
+ }
69
 
70
+ /* Control styling */
71
+ .control-group {
72
+ background: #16213e;
73
+ padding: 20px;
74
+ border-radius: 10px;
75
+ margin: 20px 0;
76
+ border: 1px solid #0f3460;
77
+ }
78
 
79
+ /* Simple button styling */
80
+ .gr-button {
81
+ background: #e94560 !important;
82
+ border: none !important;
83
+ color: white !important;
84
+ padding: 10px 20px !important;
85
+ border-radius: 6px !important;
86
+ font-weight: 600 !important;
87
+ transition: all 0.2s !important;
88
+ }
89
 
90
+ .gr-button:hover {
91
+ background: #f47068 !important;
92
+ transform: translateY(-2px) !important;
93
+ box-shadow: 0 5px 15px rgba(233, 69, 96, 0.3) !important;
94
+ }
 
 
 
 
 
 
95
 
96
+ /* Slider styling */
97
+ .gr-slider input {
98
+ accent-color: #e94560 !important;
99
+ }
100
 
101
+ /* Hide default Gradio label styling */
102
+ .gr-form {
103
+ background: transparent !important;
104
+ border: none !important;
105
+ }
106
 
107
+ .gr-box {
108
+ background: transparent !important;
109
+ border: none !important;
110
+ }
111
+
112
+ /* Dropdown styling */
113
+ .gr-dropdown {
114
+ background: #0f3460 !important;
115
+ border: 1px solid #e94560 !important;
116
+ color: #eee !important;
117
+ }
118
  """
119
+
120
+ # Simple JavaScript for file management
121
+ file_panel_js = """
122
+ <script>
123
+ let selectedFile = null;
124
+
125
+ function selectFile(index) {
126
+ // Remove previous selection
127
+ document.querySelectorAll('.file-item').forEach(item => {
128
+ item.classList.remove('selected');
129
+ });
130
+
131
+ // Add selection to clicked item
132
+ const selectedItem = document.getElementById(`file-${index}`);
133
+ if (selectedItem) {
134
+ selectedItem.classList.add('selected');
135
+ selectedFile = index;
136
+ }
137
+ }
138
+
139
+ function refreshFileList() {
140
+ // This would refresh the file list from the backend
141
+ console.log('Refreshing file list...');
142
+ }
143
+ </script>
144
  """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
145
 
146
+ def create_file_panel_html(files):
147
+ """Create HTML for the file panel"""
148
+
149
+ if not files:
150
+ file_items_html = """
151
+ <div style='text-align: center; padding: 40px 20px; color: #666;'>
152
+ <div style='font-size: 48px; opacity: 0.3; margin-bottom: 10px;'>📁</div>
153
+ <div>No files loaded</div>
154
+ <div style='font-size: 12px; margin-top: 10px;'>Click "Import Audio" to add files</div>
155
+ </div>
156
+ """
157
+ else:
158
+ file_items_html = ""
159
+ for i, file in enumerate(files):
160
+ file_items_html += f"""
161
+ <div class='file-item' id='file-{i}' onclick='selectFile({i})'>
162
+ <span style='font-size: 20px;'>🎵</span>
163
+ <div style='flex: 1;'>
164
+ <div style='font-weight: 500;'>{file['name']}</div>
165
+ <div style='font-size: 11px; opacity: 0.7;'>{file['size']} • {file['duration']}</div>
166
+ </div>
167
+ </div>
168
+ """
169
+
170
+ return f"""
171
+ <div class='file-panel'>
172
+ <div class='file-panel-header'>
173
+ <span style='font-size: 20px; font-weight: 600;'>Files</span>
174
+ <button onclick='document.getElementById("import-btn").click()' style='
175
+ margin-left: auto;
176
+ background: #e94560;
177
+ border: none;
178
+ color: white;
179
+ padding: 8px 16px;
180
+ border-radius: 6px;
181
+ cursor: pointer;
182
+ font-weight: 500;
183
+ '>+ Import Audio</button>
184
+ </div>
185
+ <div class='file-list'>
186
+ {file_items_html}
187
+ </div>
188
+ </div>
189
+ {file_panel_js}
190
+ """
191
+
192
+ def process_audio(audio_files, model, input_gain, output_gain, mix):
193
+ """Process audio with selected settings"""
194
+ if not audio_files:
195
+ return None, "No audio file selected"
196
+
197
+ # Your NAM processing here
198
+ return audio_files, f"Processed with {model}"
199
+
200
+ def import_audio_files(files):
201
+ """Handle imported audio files"""
202
+ if not files:
203
+ return create_file_panel_html([]), "No files imported"
204
+
205
+ file_list = []
206
+ for file in files:
207
+ file_info = {
208
+ 'name': Path(file.name).name if hasattr(file, 'name') else 'Unknown',
209
+ 'size': '2.3 MB', # Would calculate actual size
210
+ 'duration': '3:45' # Would get actual duration
211
+ }
212
+ file_list.append(file_info)
213
+
214
+ return create_file_panel_html(file_list), f"Imported {len(files)} file(s)"
215
+
216
+ # Build the interface
217
+ with gr.Blocks(css=custom_css, theme=gr.themes.Base()) as demo:
218
+
219
+ # Hidden file input
220
+ file_input = gr.File(
221
+ visible=False,
222
+ file_count="multiple",
223
+ file_types=["audio"],
224
+ elem_id="import-btn"
225
+ )
226
+
227
+ with gr.Row():
228
+ # Left panel - File browser (1/4 width)
229
+ with gr.Column(scale=1, min_width=250):
230
+ file_panel = gr.HTML(
231
+ value=create_file_panel_html([]),
232
+ elem_classes="file-panel-container"
233
+ )
234
+
235
+ # Right side - Main content (3/4 width)
236
+ with gr.Column(scale=3, elem_classes="main-content"):
237
+
238
+ # Header
239
+ gr.Markdown("# 🎸 NAM Garden Audio Processor")
240
+
241
+ # Model Selection
242
+ with gr.Group(elem_classes="control-group"):
243
+ gr.Markdown("### Neural Amp Model")
244
+ model_dropdown = gr.Dropdown(
245
+ choices=[
246
+ "Marshall JCM800",
247
+ "Fender Twin Reverb",
248
+ "Mesa Boogie Rectifier",
249
+ "Vox AC30",
250
+ "Orange Rockerverb"
251
+ ],
252
+ value="Marshall JCM800",
253
+ label="Select Model",
254
+ container=False
255
+ )
256
+
257
+ # Audio Controls
258
+ with gr.Group(elem_classes="control-group"):
259
+ gr.Markdown("### Audio Controls")
260
+
261
+ with gr.Row():
262
+ input_gain = gr.Slider(
263
+ minimum=-20,
264
+ maximum=20,
265
+ value=0,
266
+ label="Input Gain (dB)",
267
+ container=True
268
+ )
269
+ output_gain = gr.Slider(
270
+ minimum=-20,
271
+ maximum=20,
272
+ value=0,
273
+ label="Output Gain (dB)",
274
+ container=True
275
+ )
276
+ mix = gr.Slider(
277
+ minimum=0,
278
+ maximum=100,
279
+ value=100,
280
+ label="Mix (%)",
281
+ container=True
282
+ )
283
+
284
+ # Waveform Display
285
+ with gr.Group(elem_classes="control-group"):
286
+ gr.Markdown("### Waveform")
287
+ gr.HTML("""
288
+ <div style='
289
+ height: 150px;
290
+ background: #0f3460;
291
+ border-radius: 8px;
292
+ display: flex;
293
+ align-items: center;
294
+ justify-content: center;
295
+ color: #666;
296
+ font-size: 14px;
297
+ '>
298
+ <canvas id='waveform' style='width: 100%; height: 100%;'></canvas>
299
+ </div>
300
+ """)
301
+
302
+ # Output
303
+ with gr.Group(elem_classes="control-group"):
304
+ gr.Markdown("### Output")
305
+ audio_output = gr.Audio(
306
+ label="Processed Audio",
307
+ container=True,
308
+ elem_classes="audio-output"
309
+ )
310
+
311
+ # Process Button
312
+ with gr.Row():
313
+ process_btn = gr.Button(
314
+ "Process Audio",
315
+ variant="primary",
316
+ size="lg"
317
+ )
318
+
319
+ # Status
320
+ status = gr.Textbox(
321
+ label="Status",
322
+ value="Ready",
323
+ interactive=False,
324
+ container=True
325
+ )
326
+
327
+ # Event handlers
328
+ file_input.change(
329
+ fn=import_audio_files,
330
+ inputs=[file_input],
331
+ outputs=[file_panel, status]
332
+ )
333
+
334
+ process_btn.click(
335
+ fn=process_audio,
336
+ inputs=[file_input, model_dropdown, input_gain, output_gain, mix],
337
+ outputs=[audio_output, status]
338
+ )
339
+
340
+ # Add waveform drawing script
341
+ demo.load(None, None, None, js="""
342
+ () => {
343
+ const canvas = document.getElementById('waveform');
344
+ if (canvas) {
345
+ const ctx = canvas.getContext('2d');
346
+ canvas.width = canvas.offsetWidth;
347
+ canvas.height = canvas.offsetHeight;
348
+
349
+ // Draw placeholder waveform
350
+ ctx.strokeStyle = '#e94560';
351
+ ctx.lineWidth = 2;
352
+ ctx.beginPath();
353
+
354
+ const width = canvas.width;
355
+ const height = canvas.height;
356
+ const centerY = height / 2;
357
+
358
+ for (let x = 0; x < width; x++) {
359
+ const y = centerY + Math.sin(x * 0.02) * 30 * Math.sin(x * 0.001);
360
+ if (x === 0) ctx.moveTo(x, y);
361
+ else ctx.lineTo(x, y);
362
+ }
363
+ ctx.stroke();
364
+ }
365
+ }
366
+ """)
367
 
368
  if __name__ == "__main__":
369
+ demo.launch()
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ gradio==4.44.0
2
+ numpy
3
+ pathlib