File size: 3,831 Bytes
79c3d22
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""
Reusable UI components
"""
import gradio as gr
from typing import List, Dict, Any
import plotly.graph_objects as go
import numpy as np

class UIComponents:
    @staticmethod
    def create_audio_player(label: str = "Audio Player") -> gr.Audio:
        """Create styled audio player"""
        return gr.Audio(
            label=label,
            type="filepath",
            show_download_button=True,
            show_share_button=True
        )
    
    @staticmethod
    def create_model_dropdown() -> gr.Dropdown:
        """Create model selection dropdown"""
        from config import MODELS
        choices = [(config.name, key) for key, config in MODELS.items()]
        return gr.Dropdown(
            choices=choices,
            value="musicgen_small",
            label="Model",
            info="Select AI model for generation"
        )
    
    @staticmethod
    def create_duration_slider(min_val: int = 5, max_val: int = 30) -> gr.Slider:
        """Create duration slider"""
        return gr.Slider(
            minimum=min_val,
            maximum=max_val,
            value=10,
            step=1,
            label="Duration (seconds)",
            info="Length of generated music"
        )
    
    @staticmethod
    def create_guidance_slider() -> gr.Slider:
        """Create guidance scale slider"""
        return gr.Slider(
            minimum=1,
            maximum=10,
            value=3,
            step=0.5,
            label="Guidance Scale",
            info="How closely to follow the prompt"
        )
    
    @staticmethod
    def create_preset_dropdown() -> gr.Dropdown:
        """Create preset selection dropdown"""
        from config import PRESETS
        choices = [(name, name) for name in PRESETS.keys()]
        return gr.Dropdown(
            choices=choices,
            label="Presets",
            info="Quick style selection"
        )
    
    @staticmethod
    def create_audio_visualization(audio_array: np.ndarray) -> go.Figure:
        """Create audio waveform visualization"""
        fig = go.Figure()
        
        # Waveform
        fig.add_trace(go.Scatter(
            y=audio_array,
            mode='lines',
            name='Waveform',
            line=dict(color='blue', width=1)
        ))
        
        fig.update_layout(
            title="Audio Waveform",
            xaxis_title="Sample",
            yaxis_title="Amplitude",
            height=200,
            showlegend=False
        )
        
        return fig
    
    @staticmethod
    def create_spectrogram_visualization(audio_array: np.ndarray, sample_rate: int = 16000) -> go.Figure:
        """Create spectrogram visualization"""
        import librosa
        
        # Compute spectrogram
        D = librosa.stft(audio_array)
        S_db = librosa.amplitude_to_db(np.abs(D), ref=np.max)
        
        fig = go.Figure(data=go.Heatmap(
            z=S_db,
            colorscale='Viridis'
        ))
        
        fig.update_layout(
            title="Spectrogram",
            xaxis_title="Time",
            yaxis_title="Frequency",
            height=300
        )
        
        return fig
    
    @staticmethod
    def create_progress_info(current: int, total: int, status: str = "Processing") -> str:
        """Create progress information text"""
        percentage = (current / total) * 100
        return f"""
        <div style='text-align: center; padding: 10px; background-color: #f0f0f0; border-radius: 5px;'>
            <h4>{status}</h4>
            <p>Progress: {current}/{total} ({percentage:.1f}%)</p>
            <div style='width: 100%; background-color: #ddd; border-radius: 10px;'>
                <div style='width: {percentage}%; height: 20px; background-color: #4CAF50; border-radius: 10px;'></div>
            </div>
        </div>
        """