gnosticdev commited on
Commit
12361b7
·
verified ·
1 Parent(s): a4dc2d6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +131 -74
app.py CHANGED
@@ -1,105 +1,162 @@
1
  import gradio as gr
2
- import whisper
3
- import torch
 
 
4
  import os
5
- import time
6
 
7
- MODEL_NAME = "tiny"
8
- device = "cuda" if torch.cuda.is_available() else "cpu"
9
- _model_cache = None
 
 
 
 
 
 
10
 
11
- def cargar_modelo():
12
- global _model_cache
13
- if _model_cache is None:
14
- print(f"🌀 Cargando modelo Whisper ({MODEL_NAME}) en {device}...")
15
- start = time.time()
16
- _model_cache = whisper.load_model(MODEL_NAME, device=device)
17
- end = time.time()
18
- print(f"✅ Modelo cargado en {end - start:.2f} segundos")
19
- return _model_cache
20
 
21
- def analizar_audio_evp(audio_path, progress=gr.Progress()):
22
- inicio_total = time.time()
23
-
24
- # 1. Verificar que el archivo existe
25
  if audio_path is None:
26
  return "⚠️ No se detectó audio."
27
 
28
  if not os.path.exists(audio_path):
29
- return f"❌ ERROR: El archivo no existe en {audio_path}"
30
-
31
- tamaño = os.path.getsize(audio_path)
32
- print(f"📁 Archivo recibido: {audio_path} ({tamaño} bytes)")
33
-
34
- # 2. Cargar modelo (con tiempo real)
35
- progress(0.1, desc="Cargando modelo de IA...")
36
- inicio_carga = time.time()
37
- model = cargar_modelo()
38
- tiempo_carga = time.time() - inicio_carga
39
- print(f"⏱️ Tiempo de carga del modelo: {tiempo_carga:.2f}s")
40
-
41
- if model is None:
42
- return "❌ Error: El modelo no se cargó correctamente."
43
-
44
- # 3. Transcribir (con tiempo real)
45
- progress(0.4, desc="Procesando audio...")
46
- inicio_transcripcion = time.time()
47
-
48
- options = {
49
- "language": "es",
50
- "fp16": False if device == "cpu" else True,
51
- "temperature": 0.8,
52
- "condition_on_previous_text": False,
53
- "verbose": False,
54
- "task": "transcribe"
55
- }
56
-
57
- result = model.transcribe(audio_path, **options)
58
- tiempo_transcripcion = time.time() - inicio_transcripcion
59
- print(f"⏱️ Tiempo de transcripción: {tiempo_transcripcion:.2f}s")
60
-
61
- texto = result["text"].strip()
62
- tiempo_total = time.time() - inicio_total
63
-
64
- progress(1.0, desc="Análisis completado")
65
 
66
- # 4. Retorno CON TIEMPOS REALES (para que veas si es fake)
67
- respuesta = f"⏱️ **TIEMPO TOTAL: {tiempo_total:.2f} segundos**\n\n"
68
-
69
- if texto:
70
- respuesta += f"👻 **PATRÓN DETECTADO:**\n\n{texto}"
71
- else:
72
- respuesta += "💤 **SIN PATRONES:**\n\nLa IA no encontró estructuras lingüísticas en este audio.\n\n"
73
- respuesta += f"📊 **DEBUG:**\n- Tamaño archivo: {tamaño} bytes\n- Tiempo transcripción: {tiempo_transcripcion:.2f}s\n- Device: {device}"
74
-
75
- return respuesta
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
 
77
  # --- Interfaz ---
78
  with gr.Blocks() as demo:
79
  gr.Markdown("""
80
- # 👻 Detector EVP - Audio a Texto
81
- ## Sube un MP3 de "silencio" o graba tu habitación.
82
- *Si el análisis es instantáneo (<5s), algo está mal.*
 
 
 
 
83
  """)
84
 
85
  with gr.Row():
86
  with gr.Column():
87
  audio_input = gr.Audio(
88
- label="🎙️ Fuente de Audio",
89
  type="filepath",
90
  sources=["upload", "microphone"]
91
  )
92
- btn_analizar = gr.Button("🔮 Analizar Ruido", variant="primary")
93
 
94
  with gr.Column():
95
  output_text = gr.Textbox(
96
- label="📜 Resultado del Análisis",
97
- lines=8,
98
- max_lines=15
99
  )
100
 
101
  btn_analizar.click(
102
- fn=analizar_audio_evp,
103
  inputs=audio_input,
104
  outputs=output_text
105
  )
 
1
  import gradio as gr
2
+ import numpy as np
3
+ import librosa
4
+ import scipy.signal as signal
5
+ from scipy.fft import fft, fftfreq
6
  import os
 
7
 
8
+ # --- Frecuencias EVP (según investigación paranormal) ---
9
+ # Las "voces" suelen aparecer en frecuencias específicas, no en rango vocal humano
10
+ EVP_BANDS = {
11
+ "Bajas (Entidades densas)": (80, 300),
12
+ "Medias-Bajas (Voces delgadas)": (300, 800),
13
+ "Medias (Rango EVP común)": (800, 2000),
14
+ "Altas (Entidades sutiles)": (2000, 4000),
15
+ "Muy Altas (Interferencia)": (4000, 8000)
16
+ }
17
 
18
+ # Diccionario fonético simplificado para mapear frecuencias a sonidos
19
+ FONEMAS_POR_FRECUENCIA = {
20
+ (100, 300): ["m", "n", "ng", "b", "d", "g"],
21
+ (300, 600): ["a", "o", "u", "r", "l"],
22
+ (600, 1000): ["e", "i", "s", "z", "v"],
23
+ (1000, 2000): ["f", "th", "sh", "ch", "j"],
24
+ (2000, 4000): ["t", "k", "p", "h"],
25
+ (4000, 8000): ["sibilantes", "clicks", "ruido"]
26
+ }
27
 
28
+ def analizar_espectro_evp(audio_path, progress=gr.Progress()):
29
+ """
30
+ Análisis espectral REAL para EVP - No usa Whisper, usa DSP
31
+ """
32
  if audio_path is None:
33
  return "⚠️ No se detectó audio."
34
 
35
  if not os.path.exists(audio_path):
36
+ return f"❌ ERROR: El archivo no existe."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
 
38
+ try:
39
+ progress(0.1, desc="Cargando audio...")
40
+ # Cargar audio con alta resolución
41
+ y, sr = librosa.load(audio_path, sr=None)
42
+ duracion = len(y) / sr
43
+ print(f"📁 Audio: {duracion:.2f}s, {sr}Hz, {len(y)} muestras")
44
+
45
+ progress(0.3, desc="Calculando FFT (Transformada de Frecuencias)...")
46
+ # FFT para descomponer frecuencias
47
+ n = len(y)
48
+ yf = fft(y)
49
+ xf = fftfreq(n, 1/sr)[:n//2]
50
+ magnitud = 2.0/n * np.abs(yf[0:n//2])
51
+
52
+ progress(0.5, desc="Analizando bandas EVP...")
53
+ resultados = []
54
+ fonemas_detectados = []
55
+
56
+ # Analizar cada banda de frecuencia EVP
57
+ for nombre_banda, (f_min, f_max) in EVP_BANDS.items():
58
+ # Encontrar índices de frecuencia en este rango
59
+ idx = np.where((xf >= f_min) & (xf <= f_max))[0]
60
+
61
+ if len(idx) > 0:
62
+ # Calcular energía en esta banda
63
+ energia = np.sum(magnitud[idx]**2)
64
+ energia_normalizada = energia / len(idx)
65
+
66
+ # Calcular frecuencia dominante en esta banda
67
+ if energia_normalizada > 0:
68
+ freq_dominante = xf[idx[np.argmax(magnitud[idx])]]
69
+ magnitud_max = magnitud[idx[np.argmax(magnitud[idx])]]
70
+
71
+ # Detectar si hay pico anómalo (posible patrón)
72
+ umbral_ruido = np.median(magnitud[idx]) * 3
73
+ es_anomalo = magnitud_max > umbral_ruido
74
+
75
+ # Mapear a fonema según frecuencia
76
+ fonema = "desconocido"
77
+ for (f_low, f_high), fonemas in FONEMAS_POR_FRECUENCIA.items():
78
+ if f_low <= freq_dominante <= f_high:
79
+ fonema = np.random.choice(fonemas)
80
+ fonemas_detectados.append(fonema)
81
+ break
82
+
83
+ resultados.append({
84
+ "banda": nombre_banda,
85
+ "freq": f"{freq_dominante:.1f}Hz",
86
+ "energia": f"{energia_normalizada:.4f}",
87
+ "anomalo": "⚠️ SÍ" if es_anomalo else "✓ NO",
88
+ "fonema": fonema
89
+ })
90
+
91
+ progress(0.7, desc="Generando patrón de palabras...")
92
+ # Construir "palabras" a partir de fonemas detectados
93
+ palabras_generadas = []
94
+ if len(fonemas_detectados) >= 3:
95
+ # Agrupar fonemas en sílabas/palabras
96
+ for i in range(0, len(fonemas_detectados)-2, 2):
97
+ if i+2 < len(fonemas_detectados):
98
+ silaba = fonemas_detectados[i] + fonemas_detectados[i+1]
99
+ palabras_generadas.append(silaba)
100
+
101
+ progress(0.9, desc="Completando análisis...")
102
+
103
+ # Construir reporte
104
+ reporte = "📊 **ANÁLISIS ESPECTRAL EVP**\n\n"
105
+ reporte += f"📁 Duración: {duracion:.2f}s | Frecuencia muestreo: {sr}Hz\n\n"
106
+
107
+ reporte += "🔍 **BANADAS ANALIZADAS:**\n"
108
+ anomalias = 0
109
+ for r in resultados:
110
+ reporte += f"- {r['banda']}: {r['freq']} | Energía: {r['energia']} | Anomalía: {r['anomalo']} | Fonema: `{r['fonema']}`\n"
111
+ if r['anomalo'] == "⚠️ SÍ":
112
+ anomalias += 1
113
+
114
+ reporte += f"\n⚠️ **ANOMALÍAS DETECTADAS: {anomalias}**\n\n"
115
+
116
+ if palabras_generadas:
117
+ reporte += "👻 **PATRONES FONÉTICOS GENERADOS:**\n\n"
118
+ reporte += f"`{' '.join(palabras_generadas)}`\n\n"
119
+ reporte += "*Estos patrones se derivan de frecuencias anómalas, no de voz humana.*"
120
+ else:
121
+ reporte += "💤 **SIN PATRONES FONÉTICOS CLAROS**\n\n"
122
+ reporte += "Las frecuencias analizadas no mostraron estructura fonética reconocible."
123
+
124
+ progress(1.0, desc="Análisis completado")
125
+ return reporte
126
+
127
+ except Exception as e:
128
+ return f"❌ **ERROR:**\n\n{type(e).__name__}: {str(e)}"
129
 
130
  # --- Interfaz ---
131
  with gr.Blocks() as demo:
132
  gr.Markdown("""
133
+ # 👻 ANALIZADOR ESPECTRAL EVP
134
+ ## Detecta patrones fonéticos en frecuencias no humanas
135
+
136
+ *Este sistema NO transcribe voz humana. Analiza el espectro de frecuencias
137
+ y genera patrones fonéticos basados en anomalías espectrales.*
138
+
139
+ **Bandas analizadas:** 80Hz - 8000Hz (más allá del rango vocal humano)
140
  """)
141
 
142
  with gr.Row():
143
  with gr.Column():
144
  audio_input = gr.Audio(
145
+ label="🎙️ Audio de Ambiente (Silencio/Ruido)",
146
  type="filepath",
147
  sources=["upload", "microphone"]
148
  )
149
+ btn_analizar = gr.Button("🔮 Analizar Espectro EVP", variant="primary")
150
 
151
  with gr.Column():
152
  output_text = gr.Textbox(
153
+ label="📊 Reporte Espectral",
154
+ lines=15,
155
+ max_lines=25
156
  )
157
 
158
  btn_analizar.click(
159
+ fn=analizar_espectro_evp,
160
  inputs=audio_input,
161
  outputs=output_text
162
  )