File size: 3,820 Bytes
7934ac3
aaabe15
 
 
2a97206
 
aaabe15
 
 
31fce29
2a97206
 
31fce29
aaabe15
 
 
31fce29
aaabe15
 
 
 
 
 
 
31fce29
aaabe15
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31fce29
aaabe15
 
 
2a97206
31fce29
aaabe15
 
2a97206
ad41790
 
aaabe15
 
537071d
aaabe15
31fce29
aaabe15
2a97206
 
aaabe15
 
ad41790
 
aaabe15
 
ad41790
aaabe15
 
 
31fce29
aaabe15
 
 
 
2a97206
aaabe15
 
ad41790
aaabe15
ad41790
aaabe15
 
 
 
ad41790
aaabe15
 
31fce29
 
 
 
 
aaabe15
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import gradio as gr
import asyncio
import wave
import os
import numpy as np
import nest_asyncio
from google import genai
from google.genai import types

# Enable nested async for environments like Gradio/Jupyter
nest_asyncio.apply()

# Load Google API key from environment
GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY")
client = genai.Client(http_options={'api_version': 'v1alpha'}, api_key=GOOGLE_API_KEY)

# Helper to save PCM as .wav
def save_wave_file(filename, pcm, channels=1, rate=24000, sample_width=2):
    with wave.open(filename, "wb") as wf:
        wf.setnchannels(channels)
        wf.setsampwidth(sample_width)
        wf.setframerate(rate)
        wf.writeframes(pcm)

# Async music generation logic
async def generate_music(prompt, bpm, temperature):
    audio_chunks = []

    async def receive_audio(session):
        async for message in session.receive():
            chunk = message.server_content.audio_chunks[0].data
            audio_chunks.append(chunk)

    try:
        async with (
            client.aio.live.music.connect(model='models/lyria-realtime-exp') as session,
            asyncio.TaskGroup() as tg,
        ):
            tg.create_task(receive_audio(session))

            await session.set_weighted_prompts([
                types.WeightedPrompt(text=prompt, weight=1.0)
            ])
            await session.set_music_generation_config(
                types.LiveMusicGenerationConfig(bpm=int(bpm), temperature=float(temperature))
            )

            await session.play()
            await asyncio.sleep(5)  # Generation duration
            await session.pause()

        all_pcm = b"".join(audio_chunks)

        # Save to WAV file for download
        output_path = "generated_music.wav"
        save_wave_file(output_path, all_pcm)

        # Return file path for both playback and download
        return output_path, output_path, "Music generated successfully!"

    except Exception as e:
        return None, None, f"Error: {str(e)}"

# Sync wrapper for Gradio (uses event loop)
def generate_music_gradio(prompt, bpm, temperature):
    loop = asyncio.get_event_loop()
    return loop.run_until_complete(generate_music(prompt, bpm, temperature))

# Gradio UI
with gr.Blocks(title="Gemini Lyria Music Generator") as demo:
    gr.Markdown("## Gemini Lyria Music Generator")

    with gr.Group():
        gr.Markdown("### Prompt & Controls")
        with gr.Row():
            prompt_input = gr.Textbox(
                label="Music Style / Prompt",
                placeholder="e.g., ambient synth, classical piano, lo-fi chill"
            )
        with gr.Row():
            bpm_input = gr.Slider(label="BPM", minimum=60, maximum=180, value=90)
            temp_input = gr.Slider(label="Temperature", minimum=0.1, maximum=2.0, step=0.1, value=1.0)
        generate_btn = gr.Button("🎧 Generate Music")

    with gr.Group():
        gr.Markdown("### Output")
        with gr.Row():
            output_audio = gr.Audio(label="Generated Audio", type="filepath")
            download_file = gr.File(label="Download WAV")
        status_output = gr.Textbox(label="Status", interactive=False)

    with gr.Group():
        gr.Markdown("### Try These Examples")
        examples = gr.Examples(
            examples=[
                ["ambient synth in a forest", 100, 1.2],
                ["classical piano with raindrops", 70, 0.8],
                ["lo-fi chillhop vibe", 85, 1.0],
                ["orchestral film music", 110, 1.5],
                ["spacey techno beats", 125, 1.3],
            ],
            inputs=[prompt_input, bpm_input, temp_input]
        )

    generate_btn.click(
        fn=generate_music_gradio,
        inputs=[prompt_input, bpm_input, temp_input],
        outputs=[output_audio, download_file, status_output]
    )

demo.launch()