Spaces:
Sleeping
Sleeping
File size: 6,462 Bytes
4f66327 12361b7 18404a6 f9619b4 12361b7 f9619b4 12361b7 f9619b4 12361b7 5859700 18404a6 12361b7 18404a6 12361b7 5859700 18404a6 5859700 12361b7 5859700 4f66327 5859700 12361b7 cfce041 18404a6 5859700 12361b7 5859700 12361b7 5859700 12361b7 5859700 f9619b4 5859700 e312a32 | 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 | 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() |