fractal / app.py
gnosticdev's picture
Update app.py
12361b7 verified
Raw
History Blame Contribute Delete
6.46 kB
import gradio as gr
import numpy as np
import librosa
import scipy.signal as signal
from scipy.fft import fft, fftfreq
import os
# --- Frecuencias EVP (según investigación paranormal) ---
# Las "voces" suelen aparecer en frecuencias específicas, no en rango vocal humano
EVP_BANDS = {
"Bajas (Entidades densas)": (80, 300),
"Medias-Bajas (Voces delgadas)": (300, 800),
"Medias (Rango EVP común)": (800, 2000),
"Altas (Entidades sutiles)": (2000, 4000),
"Muy Altas (Interferencia)": (4000, 8000)
}
# Diccionario fonético simplificado para mapear frecuencias a sonidos
FONEMAS_POR_FRECUENCIA = {
(100, 300): ["m", "n", "ng", "b", "d", "g"],
(300, 600): ["a", "o", "u", "r", "l"],
(600, 1000): ["e", "i", "s", "z", "v"],
(1000, 2000): ["f", "th", "sh", "ch", "j"],
(2000, 4000): ["t", "k", "p", "h"],
(4000, 8000): ["sibilantes", "clicks", "ruido"]
}
def analizar_espectro_evp(audio_path, progress=gr.Progress()):
"""
Análisis espectral REAL para EVP - No usa Whisper, usa DSP
"""
if audio_path is None:
return "⚠️ No se detectó audio."
if not os.path.exists(audio_path):
return f"❌ ERROR: El archivo no existe."
try:
progress(0.1, desc="Cargando audio...")
# Cargar audio con alta resolución
y, sr = librosa.load(audio_path, sr=None)
duracion = len(y) / sr
print(f"📁 Audio: {duracion:.2f}s, {sr}Hz, {len(y)} muestras")
progress(0.3, desc="Calculando FFT (Transformada de Frecuencias)...")
# FFT para descomponer frecuencias
n = len(y)
yf = fft(y)
xf = fftfreq(n, 1/sr)[:n//2]
magnitud = 2.0/n * np.abs(yf[0:n//2])
progress(0.5, desc="Analizando bandas EVP...")
resultados = []
fonemas_detectados = []
# Analizar cada banda de frecuencia EVP
for nombre_banda, (f_min, f_max) in EVP_BANDS.items():
# Encontrar índices de frecuencia en este rango
idx = np.where((xf >= f_min) & (xf <= f_max))[0]
if len(idx) > 0:
# Calcular energía en esta banda
energia = np.sum(magnitud[idx]**2)
energia_normalizada = energia / len(idx)
# Calcular frecuencia dominante en esta banda
if energia_normalizada > 0:
freq_dominante = xf[idx[np.argmax(magnitud[idx])]]
magnitud_max = magnitud[idx[np.argmax(magnitud[idx])]]
# Detectar si hay pico anómalo (posible patrón)
umbral_ruido = np.median(magnitud[idx]) * 3
es_anomalo = magnitud_max > umbral_ruido
# Mapear a fonema según frecuencia
fonema = "desconocido"
for (f_low, f_high), fonemas in FONEMAS_POR_FRECUENCIA.items():
if f_low <= freq_dominante <= f_high:
fonema = np.random.choice(fonemas)
fonemas_detectados.append(fonema)
break
resultados.append({
"banda": nombre_banda,
"freq": f"{freq_dominante:.1f}Hz",
"energia": f"{energia_normalizada:.4f}",
"anomalo": "⚠️ SÍ" if es_anomalo else "✓ NO",
"fonema": fonema
})
progress(0.7, desc="Generando patrón de palabras...")
# Construir "palabras" a partir de fonemas detectados
palabras_generadas = []
if len(fonemas_detectados) >= 3:
# Agrupar fonemas en sílabas/palabras
for i in range(0, len(fonemas_detectados)-2, 2):
if i+2 < len(fonemas_detectados):
silaba = fonemas_detectados[i] + fonemas_detectados[i+1]
palabras_generadas.append(silaba)
progress(0.9, desc="Completando análisis...")
# Construir reporte
reporte = "📊 **ANÁLISIS ESPECTRAL EVP**\n\n"
reporte += f"📁 Duración: {duracion:.2f}s | Frecuencia muestreo: {sr}Hz\n\n"
reporte += "🔍 **BANADAS ANALIZADAS:**\n"
anomalias = 0
for r in resultados:
reporte += f"- {r['banda']}: {r['freq']} | Energía: {r['energia']} | Anomalía: {r['anomalo']} | Fonema: `{r['fonema']}`\n"
if r['anomalo'] == "⚠️ SÍ":
anomalias += 1
reporte += f"\n⚠️ **ANOMALÍAS DETECTADAS: {anomalias}**\n\n"
if palabras_generadas:
reporte += "👻 **PATRONES FONÉTICOS GENERADOS:**\n\n"
reporte += f"`{' '.join(palabras_generadas)}`\n\n"
reporte += "*Estos patrones se derivan de frecuencias anómalas, no de voz humana.*"
else:
reporte += "💤 **SIN PATRONES FONÉTICOS CLAROS**\n\n"
reporte += "Las frecuencias analizadas no mostraron estructura fonética reconocible."
progress(1.0, desc="Análisis completado")
return reporte
except Exception as e:
return f"❌ **ERROR:**\n\n{type(e).__name__}: {str(e)}"
# --- Interfaz ---
with gr.Blocks() as demo:
gr.Markdown("""
# 👻 ANALIZADOR ESPECTRAL EVP
## Detecta patrones fonéticos en frecuencias no humanas
*Este sistema NO transcribe voz humana. Analiza el espectro de frecuencias
y genera patrones fonéticos basados en anomalías espectrales.*
**Bandas analizadas:** 80Hz - 8000Hz (más allá del rango vocal humano)
""")
with gr.Row():
with gr.Column():
audio_input = gr.Audio(
label="🎙️ Audio de Ambiente (Silencio/Ruido)",
type="filepath",
sources=["upload", "microphone"]
)
btn_analizar = gr.Button("🔮 Analizar Espectro EVP", variant="primary")
with gr.Column():
output_text = gr.Textbox(
label="📊 Reporte Espectral",
lines=15,
max_lines=25
)
btn_analizar.click(
fn=analizar_espectro_evp,
inputs=audio_input,
outputs=output_text
)
if __name__ == "__main__":
demo.launch()