b2bomber commited on
Commit
4a55d40
·
verified ·
1 Parent(s): 7d5c676

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +62 -15
  2. musicgen_utils.py +89 -9
app.py CHANGED
@@ -1,16 +1,63 @@
1
- import gradio as gr
2
- from musicgen_utils import generate_music_prompt
3
-
4
- with gr.Blocks(title="🎼 AI Music & Tone Generator") as demo:
5
- gr.Markdown("""
6
- # 🎵 AI Tone & Music Generator
7
- *Generated using real instrument‑like audio from a lightweight model*
8
- """)
9
- with gr.Tab("🎧 Music by Prompt"):
10
- prompt = gr.Textbox(label="Describe your sound", placeholder="e.g. flute melody, bird chirping in forest, drum beat")
11
- mood = gr.Radio(["Happy", "Calm", "Energetic", "Relaxed"], value="Calm", label="Mood")
12
- tempo = gr.Slider(30, 200, value=120, step=5, label="Tempo (BPM)")
13
- btn = gr.Button("Generate Audio 🎶")
14
- audio_out = gr.Audio(label="Generated Sound", type="filepath")
15
- btn.click(fn=generate_music_prompt, inputs=[prompt, mood, tempo], outputs=audio_out)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  demo.launch()
 
1
+
2
+ import gradio as gr
3
+ from musicgen_utils import (
4
+ generate_music_prompt,
5
+ remix_music,
6
+ generate_random,
7
+ category_to_text,
8
+ generate_tone,
9
+ export_midi_file
10
+ )
11
+
12
+ categories = [
13
+ "Bird Chirping", "Flute Solo", "Guitar Riff", "Drum Loop",
14
+ "Harmonium Chant", "Piano Arpeggio", "Violin Ambient",
15
+ "Bass Groove", "Ambient Forest", "Temple Bells"
16
+ ]
17
+
18
+ with gr.Blocks(title="🎼 AI Music & Tone Generator") as demo:
19
+ gr.Markdown("# 🎵 AI Music Generator
20
+ _Easy, beginner-friendly audio & tone creation_")
21
+
22
+ with gr.Tabs():
23
+ with gr.Tab("🎧 Music from Prompt"):
24
+ with gr.Row():
25
+ category = gr.Dropdown(choices=categories, label="🎼 Choose Instrument Category")
26
+ prompt = gr.Textbox(lines=2, placeholder="Describe your music...", label="Prompt")
27
+ with gr.Row():
28
+ mood = gr.Radio(["Happy", "Sad", "Calm", "Epic"], label="Mood", value="Calm")
29
+ tempo = gr.Slider(60, 180, step=5, value=100, label="Tempo (BPM)")
30
+ duration = gr.Slider(5, 30, step=1, value=10, label="Duration (seconds)")
31
+ remix_strength = gr.Slider(0.5, 1.5, step=0.1, value=1.0, label="Remix Intensity")
32
+
33
+ with gr.Row():
34
+ btn_gen = gr.Button("🎶 Generate Music")
35
+ btn_remix = gr.Button("🪄 AI Remix")
36
+ btn_rand = gr.Button("🎲 Randomize")
37
+
38
+ output_audio = gr.Audio(label="Output Music")
39
+ category.change(fn=category_to_text, inputs=category, outputs=prompt)
40
+ btn_gen.click(fn=generate_music_prompt, inputs=[prompt, mood, tempo, duration, remix_strength], outputs=output_audio)
41
+ btn_remix.click(fn=remix_music, inputs=[prompt, mood, tempo], outputs=output_audio)
42
+ btn_rand.click(fn=generate_random, outputs=output_audio)
43
+
44
+ with gr.Tab("🎹 Tone Synth (Fallback)"):
45
+ with gr.Row():
46
+ wave = gr.Radio(["Sine", "Square", "Saw", "Triangle"], label="Waveform", value="Sine")
47
+ freq = gr.Slider(100, 2000, value=440, step=10, label="Frequency (Hz)")
48
+ duration2 = gr.Slider(1, 10, value=3, step=1, label="Duration (sec)")
49
+ volume = gr.Slider(0.1, 1.0, value=0.5, step=0.1, label="Volume")
50
+
51
+ with gr.Row():
52
+ bass = gr.Slider(-10, 10, value=0, label="Bass")
53
+ mid = gr.Slider(-10, 10, value=0, label="Mid")
54
+ treble = gr.Slider(-10, 10, value=0, label="Treble")
55
+
56
+ btn_tone = gr.Button("🎼 Generate Tone")
57
+ audio_out = gr.Audio(label="Tone Output")
58
+ midi_out = gr.File(label="Download MIDI")
59
+
60
+ btn_tone.click(fn=generate_tone, inputs=[wave, freq, duration2, volume, bass, mid, treble], outputs=audio_out)
61
+ btn_tone.click(fn=export_midi_file, inputs=[freq, duration2], outputs=midi_out)
62
+
63
  demo.launch()
musicgen_utils.py CHANGED
@@ -1,17 +1,97 @@
 
1
  import torch
 
2
  from transformers import pipeline
3
  import tempfile
4
- import numpy as np
5
  from scipy.io import wavfile
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
 
7
- # load once
8
- synth = pipeline("text-to-audio", model="facebook/musicgen-small", torch_dtype=torch.float32)
 
 
 
 
 
9
 
10
- def generate_music_prompt(prompt, mood, tempo):
11
- text = f"{mood} {prompt} at {tempo} bpm"
12
- out = synth(text, forward_params={"do_sample": True, "max_new_tokens": 500})
13
- rate = out["sampling_rate"]
14
- data = np.array(out["audio"])
 
 
 
 
 
 
 
15
  tmp = tempfile.NamedTemporaryFile(delete=False, suffix=".wav")
16
- wavfile.write(tmp.name, rate, data)
17
  return tmp.name
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
  import torch
3
+ import numpy as np
4
  from transformers import pipeline
5
  import tempfile
 
6
  from scipy.io import wavfile
7
+ import random
8
+ import math
9
+
10
+ category_to_prompt = {
11
+ "Bird Chirping": "a forest with birds chirping",
12
+ "Flute Solo": "a calm flute solo in a forest",
13
+ "Guitar Riff": "a funky electric guitar riff",
14
+ "Drum Loop": "a groovy drum loop",
15
+ "Harmonium Chant": "indian harmonium prayer music",
16
+ "Piano Arpeggio": "beautiful piano arpeggios",
17
+ "Violin Ambient": "slow ambient violin",
18
+ "Bass Groove": "funky electric bass groove",
19
+ "Ambient Forest": "peaceful nature forest ambient",
20
+ "Temple Bells": "indian temple bells ringing"
21
+ }
22
 
23
+ # Try loading model
24
+ try:
25
+ musicgen = pipeline("text-to-audio", model="facebook/musicgen-small", torch_dtype=torch.float32)
26
+ model_available = True
27
+ except:
28
+ musicgen = None
29
+ model_available = False
30
 
31
+ def generate_music_prompt(prompt, mood, tempo, duration, remix_strength):
32
+ if not model_available:
33
+ return None
34
+ full_prompt = f"{mood} {prompt} at {tempo} bpm"
35
+ audio = musicgen(full_prompt, forward_params={
36
+ "do_sample": True,
37
+ "top_k": 250,
38
+ "temperature": remix_strength,
39
+ "max_new_tokens": int(duration * 50)
40
+ })
41
+ sr = audio["sampling_rate"]
42
+ data = np.array(audio["audio"])
43
  tmp = tempfile.NamedTemporaryFile(delete=False, suffix=".wav")
44
+ wavfile.write(tmp.name, sr, data)
45
  return tmp.name
46
+
47
+ def remix_music(prompt, mood, tempo):
48
+ return generate_music_prompt(prompt, mood, tempo, duration=10, remix_strength=random.uniform(0.7, 1.0))
49
+
50
+ def generate_random():
51
+ category = random.choice(list(category_to_prompt.keys()))
52
+ prompt = category_to_prompt[category]
53
+ mood = random.choice(["Happy", "Sad", "Calm", "Epic"])
54
+ return generate_music_prompt(prompt, mood, 100, 10, 1.0)
55
+
56
+ def category_to_text(category):
57
+ return category_to_prompt.get(category, "")
58
+
59
+ # Fallback waveform tone generation
60
+ def generate_tone(waveform, freq, duration, volume, bass, mid, treble):
61
+ rate = 44100
62
+ t = np.linspace(0, duration, int(rate * duration), endpoint=False)
63
+ if waveform == "Sine":
64
+ wave = np.sin(2 * np.pi * freq * t)
65
+ elif waveform == "Square":
66
+ wave = np.sign(np.sin(2 * np.pi * freq * t))
67
+ elif waveform == "Saw":
68
+ wave = 2 * (t * freq - np.floor(0.5 + t * freq))
69
+ elif waveform == "Triangle":
70
+ wave = 2 * np.abs(2 * (t * freq - np.floor(t * freq + 0.5))) - 1
71
+ else:
72
+ wave = np.zeros_like(t)
73
+
74
+ # Apply EQ (simple gain)
75
+ wave = wave * volume
76
+ eq_gain = (1 + bass/10 + mid/10 + treble/10) / 3
77
+ wave *= eq_gain
78
+
79
+ wave = np.int16(wave * 32767)
80
+ tmp = tempfile.NamedTemporaryFile(delete=False, suffix=".wav")
81
+ wavfile.write(tmp.name, rate, wave)
82
+ return tmp.name
83
+
84
+ def export_midi_file(freq, duration):
85
+ try:
86
+ import mido
87
+ mid = mido.MidiFile()
88
+ track = mido.MidiTrack()
89
+ mid.tracks.append(track)
90
+ note = int(69 + 12 * math.log2(freq / 440))
91
+ track.append(mido.Message("note_on", note=note, velocity=64, time=0))
92
+ track.append(mido.Message("note_off", note=note, velocity=64, time=int(duration * 480)))
93
+ tmp = tempfile.NamedTemporaryFile(delete=False, suffix=".mid")
94
+ mid.save(tmp.name)
95
+ return tmp.name
96
+ except:
97
+ return None