File size: 8,406 Bytes
009c9f3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
"""
Integration code for VibeVoice-PodcastCreator to use ACE-Music-Generator

Add this to your VibeVoice space to generate background music on demand.
"""

from gradio_client import Client
import numpy as np
from scipy.io import wavfile
import tempfile
import os


class MusicGenerator:
    """
    Music generator client for VibeVoice podcast creation
    """
    
    def __init__(self, space_name="ACloudCenter/ACE-Music-Generator"):
        """Initialize connection to music generator space"""
        try:
            self.client = Client(space_name)
            self.connected = True
        except:
            print("Warning: Could not connect to music generator. Music features disabled.")
            self.connected = False
    
    def generate_intro_music(self, duration=10):
        """Generate intro music for podcast"""
        if not self.connected:
            return None
            
        return self._generate(
            duration=duration,
            tags="podcast intro, upbeat, electronic, professional, 120 bpm, energetic",
            lyrics="[instrumental]"
        )
    
    def generate_outro_music(self, duration=10):
        """Generate outro music for podcast"""
        if not self.connected:
            return None
            
        return self._generate(
            duration=duration,
            tags="podcast outro, calm, ambient, soft, 80 bpm, fade out, peaceful",
            lyrics="[instrumental]"
        )
    
    def generate_background_music(self, style="ambient", duration=30):
        """
        Generate background music for podcast segments
        
        Styles:
        - ambient: Soft background music
        - news: Professional news-style background
        - dramatic: Intense, dramatic music
        - tech: Futuristic tech music
        - chill: Relaxed lofi music
        """
        styles = {
            "ambient": "ambient, soft, background, minimal, 70 bpm, atmospheric",
            "news": "news, professional, subtle, electronic, 90 bpm, serious",
            "dramatic": "dramatic, orchestral, cinematic, 100 bpm, intense",
            "tech": "electronic, futuristic, synth, 110 bpm, innovative",
            "chill": "lofi, relaxed, warm, 75 bpm, cozy, mellow"
        }
        
        if not self.connected:
            return None
            
        tags = styles.get(style, styles["ambient"])
        return self._generate(duration=duration, tags=tags, lyrics="[instrumental]")
    
    def generate_commercial_jingle(self, duration=5):
        """Generate a short commercial jingle"""
        if not self.connected:
            return None
            
        return self._generate(
            duration=duration,
            tags="jingle, commercial, catchy, upbeat, 140 bpm, happy, memorable",
            lyrics="[instrumental]"
        )
    
    def _generate(self, duration, tags, lyrics):
        """Internal method to generate music"""
        try:
            result = self.client.predict(
                duration,
                tags,
                lyrics,
                60,  # infer_steps
                15.0,  # guidance_scale
                api_name="/generate"
            )
            return result
        except Exception as e:
            print(f"Error generating music: {e}")
            return None
    
    def mix_with_podcast(self, podcast_audio_path, music_path, music_volume=0.2):
        """
        Mix background music with podcast audio
        
        Args:
            podcast_audio_path: Path to podcast audio file
            music_path: Path to music file
            music_volume: Volume of music (0-1, lower = quieter background)
        
        Returns:
            mixed_audio_path: Path to mixed audio file
        """
        try:
            # Load audio files
            podcast_rate, podcast_data = wavfile.read(podcast_audio_path)
            music_rate, music_data = wavfile.read(music_path)
            
            # Ensure same sample rate
            if podcast_rate != music_rate:
                # Simple resampling (you might want to use librosa for better quality)
                music_data = np.interp(
                    np.linspace(0, len(music_data), int(len(music_data) * podcast_rate / music_rate)),
                    np.arange(len(music_data)),
                    music_data
                )
            
            # Match lengths
            if len(music_data) < len(podcast_data):
                # Loop music if it's shorter
                music_data = np.tile(music_data, (len(podcast_data) // len(music_data) + 1))
            music_data = music_data[:len(podcast_data)]
            
            # Mix audio
            mixed = podcast_data + (music_data * music_volume)
            
            # Normalize to prevent clipping
            mixed = np.clip(mixed, -32768, 32767).astype(np.int16)
            
            # Save mixed audio
            output_path = tempfile.mktemp(suffix=".wav")
            wavfile.write(output_path, podcast_rate, mixed)
            
            return output_path
            
        except Exception as e:
            print(f"Error mixing audio: {e}")
            return podcast_audio_path  # Return original if mixing fails


# Example usage in VibeVoice generator
def enhance_podcast_with_music(podcast_generator):
    """
    Example of how to add this to your existing podcast generator
    """
    
    # Initialize music generator
    music_gen = MusicGenerator()
    
    # Your existing podcast generation code
    # podcast_audio = podcast_generator.generate_podcast(...)
    
    # Generate intro music
    intro_music = music_gen.generate_intro_music(duration=5)
    
    # Generate background music for main content
    background_music = music_gen.generate_background_music(
        style="ambient",
        duration=60  # Adjust based on your podcast length
    )
    
    # Generate outro music
    outro_music = music_gen.generate_outro_music(duration=5)
    
    # Mix background music with podcast (optional)
    # if background_music and podcast_audio:
    #     mixed_audio = music_gen.mix_with_podcast(
    #         podcast_audio,
    #         background_music,
    #         music_volume=0.1  # Keep it quiet in background
    #     )
    
    return {
        "intro": intro_music,
        "background": background_music,
        "outro": outro_music
    }


# Quick function to add to your VibeVoice app.py
def add_music_generation_to_vibevoice():
    """
    Add this to your VibeVoice app.py to integrate music generation
    """
    
    # In your create_demo() function, add:
    """
    # Add music generator
    music_gen = MusicGenerator()
    
    # Add checkbox for music generation
    with gr.Row():
        add_intro_music = gr.Checkbox(label="Add Intro Music", value=False)
        add_outro_music = gr.Checkbox(label="Add Outro Music", value=False)
        add_background_music = gr.Checkbox(label="Add Background Music", value=False)
        background_style = gr.Dropdown(
            choices=["ambient", "news", "dramatic", "tech", "chill"],
            value="ambient",
            label="Background Music Style"
        )
    
    # In your generation function:
    def generate_with_music(..., add_intro, add_outro, add_background, bg_style):
        # Your existing generation code
        podcast_audio = generate_podcast(...)
        
        # Add music if requested
        if add_intro:
            intro = music_gen.generate_intro_music(5)
            # Concatenate intro with podcast
        
        if add_background:
            bg_music = music_gen.generate_background_music(bg_style, duration=60)
            # Mix with podcast audio
        
        if add_outro:
            outro = music_gen.generate_outro_music(5)
            # Concatenate outro
        
        return final_audio
    """
    pass


if __name__ == "__main__":
    # Test the music generator
    print("Testing music generator...")
    music_gen = MusicGenerator()
    
    print("Generating intro music...")
    intro = music_gen.generate_intro_music(duration=5)
    if intro:
        print(f"Intro music saved to: {intro}")
    
    print("Generating background music...")
    background = music_gen.generate_background_music(style="ambient", duration=10)
    if background:
        print(f"Background music saved to: {background}")
    
    print("Done!")