File size: 7,271 Bytes
0cd3557
 
 
2ef73c9
d2204e0
38fdeae
ec04778
38fdeae
579ca65
38fdeae
 
 
 
 
 
 
87378e6
493199d
38fdeae
579ca65
38fdeae
 
83491f0
bfe5859
2ef73c9
38fdeae
 
bfe5859
d2204e0
579ca65
d2204e0
 
 
 
 
 
 
da2b151
38fdeae
 
da2b151
38fdeae
579ca65
38fdeae
 
 
da2b151
38fdeae
da2b151
 
628f902
4dae5c6
38fdeae
493199d
579ca65
38fdeae
 
 
 
579ca65
38fdeae
 
 
 
 
da2b151
579ca65
87378e6
 
38fdeae
 
 
628f902
38fdeae
da2b151
579ca65
 
da2b151
83491f0
38fdeae
579ca65
38fdeae
da2b151
38fdeae
83491f0
 
38fdeae
d2204e0
 
 
38fdeae
 
 
d2204e0
38fdeae
 
 
 
 
 
 
 
b3d8b8d
38fdeae
 
 
 
 
83491f0
38fdeae
 
83491f0
628f902
83491f0
b3d8b8d
43e523b
83491f0
628f902
d2204e0
38fdeae
 
83491f0
87378e6
38fdeae
 
 
 
579ca65
628f902
38fdeae
83491f0
38fdeae
83491f0
 
 
 
 
 
 
 
 
579ca65
d2204e0
579ca65
38fdeae
 
83491f0
 
38fdeae
 
83491f0
 
38fdeae
 
83491f0
 
38fdeae
579ca65
0cd3557
43e523b
83491f0
da2b151
43e523b
628f902
83491f0
 
 
d2204e0
 
 
 
83491f0
 
 
 
87378e6
38fdeae
83491f0
 
38fdeae
 
83491f0
 
 
38fdeae
 
 
d2204e0
 
38fdeae
 
d2204e0
 
 
 
 
 
38fdeae
 
 
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
import gradio as gr
import librosa
import numpy as np
from pydub import AudioSegment
from pydub.effects import compress_dynamic_range
import os

# Titan Intelligence Core
ghost_titan = {
    "key": "--", 
    "bpm": 0, 
    "crest": 0, 
    "phase": "Mono Compatible",
    "harmonics": [], 
    "spectral_density": {}, 
    "analyzed": False
}

def engine_v28_titan(input_audio, ref_audio, pressure, active_fix, active_master):
    global ghost_titan
    
    if input_audio is None:
        return None, "STATUS: OFFLINE", "--", "0"
    
    try:
        # 1. SONIC DNA SCAN (120 sec limit)
        y, sr = librosa.load(input_audio, duration=120)
        
        # BPM Detection - FIX: Removed non-existent .rhythm attribute
        onset_env = librosa.onset.onset_strength(y=y, sr=sr)
        
        # Version-agnostic Librosa tempo extraction
        if hasattr(librosa.feature, 'tempo'):
            tempo = librosa.feature.tempo(onset_envelope=onset_env, sr=sr)
        else:
            tempo = librosa.beat.tempo(onset_envelope=onset_env, sr=sr)
            
        bpm = int(np.atleast_1d(tempo)[0])
        if bpm < 115: 
            bpm *= 2  # DnB/Techno optimizer
        
        # KEY Detection via FFT Chromatography
        chroma = librosa.feature.chroma_stft(y=y, sr=sr, n_fft=4096)
        notes = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
        detected_key = notes[np.argmax(np.mean(chroma, axis=1))]
        fund_freq = librosa.note_to_hz(detected_key + '1')
        
        # Phase and Crest Factor Analysis (Punch)
        rms = librosa.feature.rms(y=y)
        crest = 20 * np.log10(np.max(np.abs(y)) / (np.mean(rms) + 1e-6))
        
        S = np.abs(librosa.stft(y))
        freq = librosa.fft_frequencies(sr=sr)
        
        ghost_titan.update({
            "key": detected_key, 
            "bpm": bpm, 
            "crest": crest,
            "harmonics": [round(fund_freq * i, 1) for i in range(1, 6)],
            "spectral_density": {
                "sub": np.mean(S[freq < 60]),
                "punch": np.mean(S[(freq >= 100) & (freq < 250)]),
                "mud": np.mean(S[(freq >= 250) & (freq < 500)]),
                "harsh": np.mean(S[(freq >= 3000) & (freq < 5000)]),
                "air": np.mean(S[freq > 12000])
            },
            "analyzed": True
        })

        # Load audio for processing
        audio = AudioSegment.from_file(input_audio)
        log = "--- GHOST TITAN V28 SYSTEM LOG ---\n\n"
        
        # ADAPTIVE MIX REPAIR
        if active_fix:
            audio = audio.high_pass_filter(34)
            if ghost_titan["spectral_density"]["mud"] > ghost_titan["spectral_density"]["punch"] * 1.3:
                audio = audio.low_pass_filter(4500)
                log += "[!] Mud resonance detected. Adaptive filter applied.\n"
            log += "[+] MIX REPAIR: High-pass filter @ 34Hz applied.\n"
        
        # TITAN MASTERING CHAIN
        if active_master:
            audio = audio.normalize(headroom=0.5)
            target_lufs = -14 + ((pressure / 100) * 8)
            gain_db = target_lufs - (-20)
            
            # FIX: Explicitly call compress_dynamic_range and remove invalid 'window' argument
            audio = compress_dynamic_range(
                audio,
                threshold=-20.0,
                ratio=4.0,
                attack=12.0,
                release=100.0
            )
            
            optimal_gain = min(gain_db, pressure / 10)
            audio = audio.apply_gain(optimal_gain)
            audio = audio.normalize(headroom=0.1)
            
            log += f"[+] MASTER: Titan chain activated (Target: {round(target_lufs, 1)} LUFS).\n"
            log += f"[+] Applied +{round(optimal_gain, 1)}dB gain with soft limiting.\n"

        # Export processed audio
        output_path = "/tmp/ghost_titan_v28_mastered.wav"
        audio.export(output_path, format="wav", parameters=["-ar", str(sr), "-ac", "2"])
        
        log += f"\n▶ DIAGNOSIS: Key {detected_key} | BPM {bpm} | Crest {round(crest, 1)}dB\n"
        log += f"▶ RECOMMENDATION: Clean {ghost_titan['harmonics'][2]}Hz for vocal space."
        
        if active_master:
            log += "\n\n✅ MASTERING COMPLETE - Download below!"

        return output_path, log, detected_key, str(bpm)

    except Exception as e:
        return None, f"ERROR: {str(e)}", "!", "0"


def titan_mentor_ai(question):
    if not ghost_titan["analyzed"]: 
        return "Upload a track first."
    
    msg = question.lower()
    k = ghost_titan["key"]
    b = ghost_titan["bpm"]
    sd = ghost_titan["spectral_density"]
    h = ghost_titan["harmonics"]
    
    if "bass" in msg or "sub" in msg:
        return f"Sub at {h[0]}Hz. Punch zone ({h[1]}Hz) is strong. Use sidechain at {h[0]}Hz."
    if "punch" in msg or "transient" in msg:
        ms = round(60000 / b / 2, 1)
        return f"Set Attack 30ms, Release {ms}ms at {b} BPM."
    if "mud" in msg or "clean" in msg:
        return f"Cut -3dB at {h[3]}Hz (4th harmonic of {k})."
    if "key" in msg:
        return f"Key: {k} | Fundamentals: {h[:2]}"
    if "bpm" in msg:
        return f"BPM: {b} (DnB range 160-180)"
    return f"Status: {k} @ {b} BPM | Crest: {round(ghost_titan['crest'], 1)}dB"


css = """
body, .gradio-container {
    background: #020202 !important; 
    color: #00e5ff !important;
    font-family: monospace;
}
.gr-box {
    border: 2px solid #00e5ff !important;
    background: #080808 !important;
}
.gr-button-primary {
    background: linear-gradient(180deg, #00e5ff, #007cff) !important;
    color: #000 !important;
}
"""

with gr.Blocks(theme=gr.themes.Monochrome(), css=css) as demo:
    gr.HTML("<h1 style='text-align:center;color:#00e5ff'>👻 GHOST TITAN v28</h1>")
    
    with gr.Row():
        with gr.Column(scale=1):
            out_key = gr.Label(label="KEY")
            out_bpm = gr.Label(label="BPM")
            in_audio = gr.Audio(label="🎵 UPLOAD TRACK", type="filepath")
            
            # FIX: Restored reference audio block mapping to 'ref_audio' in engine_v28_titan
            in_ref = gr.Audio(label="MASTER REFERENCE (Optional)", type="filepath")
            
            fix_btn = gr.Checkbox(label="🔧 MIX REPAIR", value=False)
            mst_btn = gr.Checkbox(label="🔥 AUTO MASTER", value=False)
            in_pwr = gr.Slider(0, 100, label="GAIN PRESSURE", value=85)
            exec_btn = gr.Button("🚀 PROCESS", variant="primary")

        with gr.Column(scale=2):
            out_audio = gr.Audio(label="OUTPUT WAV", type="filepath")
            out_diag = gr.Textbox(label="LOG", lines=8)
    
    with gr.Group():
        user_msg = gr.Textbox(placeholder="Ask about bass, punch, mud...", label="Question")
        chat_btn = gr.Button("ASK AI")
        chat_out = gr.Textbox(label="ANSWER", lines=3)

    exec_btn.click(
        fn=engine_v28_titan, 
        # FIX: Replaced duplicate 'in_audio' with 'in_ref' 
        inputs=[in_audio, in_ref, in_pwr, fix_btn, mst_btn], 
        outputs=[out_audio, out_diag, out_key, out_bpm]
    )
    
    chat_btn.click(
        fn=titan_mentor_ai, 
        inputs=[user_msg], 
        outputs=[chat_out]
    )

if __name__ == "__main__":
    demo.launch()