gnosticdev commited on
Commit
f8bd245
verified
1 Parent(s): acd4ace

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +59 -99
app.py CHANGED
@@ -1,94 +1,71 @@
1
  import gradio as gr
2
  import numpy as np
3
  import librosa
4
- from scipy.signal import find_peaks
5
- from sklearn.cluster import KMeans
6
- import torch
7
  from transformers import AutoModelForCausalLM, AutoTokenizer
 
 
 
 
 
 
 
 
 
8
 
9
- # ---- Modelo GPT-2 ----
 
 
 
10
  MODEL_NAME = "gpt2"
11
  tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)
12
  model = AutoModelForCausalLM.from_pretrained(MODEL_NAME)
13
 
14
- # ---- Decodificador de Tonos ----
15
- class DigitalToneDecoder:
16
- def __init__(self, frame_ms=40, min_freq=300, max_freq=4000, peak_threshold=0.2, symbols=16):
17
- self.frame_ms = frame_ms
18
- self.min_freq = min_freq
19
- self.max_freq = max_freq
20
- self.peak_threshold = peak_threshold
21
- self.symbols = symbols
22
- self.sr = None
23
- self.y = None
24
 
25
- def cargar_audio(self, path):
26
- y, sr = librosa.load(path, sr=None, mono=True)
27
- self.sr = sr
28
- self.y = y
29
- return y, sr
30
 
31
- def calcular_stft(self):
32
- n_fft = int(self.sr * 0.05)
33
- n_fft = 2 ** int(np.ceil(np.log2(n_fft)))
34
- hop_length = int(self.sr * self.frame_ms / 1000)
35
- stft = np.abs(librosa.stft(self.y, n_fft=n_fft, hop_length=hop_length, window="hann"))
36
- freqs = librosa.fft_frequencies(sr=self.sr, n_fft=n_fft)
37
- return stft, freqs
38
 
39
- def detectar_tonos(self, stft, freqs):
40
- tonos = []
41
- media_global = np.mean(stft)
42
- for frame in stft.T:
43
- if np.mean(frame) < media_global * 0.5:
44
- continue
45
- frame_norm = frame / np.max(frame)
46
- peaks, _ = find_peaks(frame_norm, height=self.peak_threshold)
47
- if len(peaks) == 0:
48
- continue
49
- peak = peaks[np.argmax(frame_norm[peaks])]
50
- freq = freqs[peak]
51
- if self.min_freq <= freq <= self.max_freq:
52
- tonos.append(freq)
53
- return np.array(tonos)
54
 
55
- def crear_simbolos(self, tonos):
56
- if len(tonos) == 0:
57
- return []
58
- if len(tonos) < self.symbols:
59
- return sorted(np.unique(tonos))
60
- tonos_2d = tonos.reshape(-1,1)
61
- kmeans = KMeans(n_clusters=self.symbols, n_init=10, random_state=42)
62
- kmeans.fit(tonos_2d)
63
- return sorted(kmeans.cluster_centers_.flatten())
64
 
65
- def decodificar(self, tonos, centros):
66
- letras = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
67
- out=""
68
- if len(centros)==0:
69
- return out
70
- for f in tonos:
71
- dist = [abs(f-c) for c in centros]
72
- idx = dist.index(min(dist))
73
- out += letras[idx % len(letras)]
74
- return out
75
 
76
- # ---- Preprocesamiento de letras ----
77
- def limpiar_repeticiones(texto, max_len=30):
78
- resultado = ""
79
  prev = None
80
- for c in texto:
81
  if c != prev:
82
- resultado += c
83
  prev = c
84
- return resultado[:max_len]
85
 
86
- # ---- Generador de palabras/frases con IA ----
87
- def generar_texto_ia(letras):
88
- letras = limpiar_repeticiones(letras)
89
- prompt = f"""Secuencia de letras: {letras}
90
- Interpreta estas letras como posibles palabras inventadas y combina en frases legibles.
91
- Genera solo palabras y frases cortas, sin URLs, ni texto irrelevante:\n"""
 
92
  input_ids = tokenizer(prompt, return_tensors="pt").input_ids
93
  out = model.generate(
94
  input_ids,
@@ -98,39 +75,22 @@ Genera solo palabras y frases cortas, sin URLs, ni texto irrelevante:\n"""
98
  top_p=0.92,
99
  top_k=50
100
  )
101
- texto = tokenizer.decode(out[0], skip_special_tokens=True)
102
- return texto
103
-
104
- # ---- Funci贸n principal ----
105
- def analizar(audio_path, progress=gr.Progress()):
106
- if audio_path is None:
107
- return "Sin audio"
108
-
109
- decoder = DigitalToneDecoder()
110
- progress(0.2)
111
- decoder.cargar_audio(audio_path)
112
- progress(0.4)
113
- stft, freqs = decoder.calcular_stft()
114
- progress(0.6)
115
- tonos = decoder.detectar_tonos(stft, freqs)
116
- progress(0.8)
117
- centros = decoder.crear_simbolos(tonos)
118
- seq = decoder.decodificar(tonos, centros)
119
- ia_text = generar_texto_ia(seq)
120
 
121
- reporte = ""
122
- reporte += "SECUENCIA DETECTADA\n"
123
- reporte += seq + "\n\n"
124
- reporte += "TEXTO GENERADO POR IA\n"
125
- reporte += ia_text
 
126
  return reporte
127
 
128
  # ---- Interfaz Gradio ----
129
  with gr.Blocks() as demo:
130
- gr.Markdown("# Decodificador + Generador de Palabras/Frases con GPT-2")
131
  audio = gr.Audio(type="filepath", sources=["upload","microphone"])
132
- boton = gr.Button("Procesar")
133
  salida = gr.Textbox(lines=15)
134
- boton.click(analizar, inputs=audio, outputs=salida)
135
 
136
  demo.launch()
 
1
  import gradio as gr
2
  import numpy as np
3
  import librosa
4
+ from scipy.fft import fft, fftfreq
 
 
5
  from transformers import AutoModelForCausalLM, AutoTokenizer
6
+ import torch
7
+
8
+ # ---- ABECEDARIO DE FRECUENCIAS ----
9
+ ABECEDARIO = {
10
+ 'A': 300,'B': 400,'C': 500,'D': 600,'E': 700,'F': 800,'G': 900,'H': 1000,
11
+ 'I': 1100,'J': 1200,'K': 1300,'L': 1400,'M': 1500,'N': 1600,'O': 1700,
12
+ 'P': 1800,'Q': 1900,'R': 2000,'S': 2100,'T': 2200,'U': 2300,'V': 2400,
13
+ 'W': 2500,'X': 2600,'Y': 2700,'Z': 2800,' ': 0
14
+ }
15
 
16
+ FRECUENCIAS = np.array(list(ABECEDARIO.values()))
17
+ LETRAS = list(ABECEDARIO.keys())
18
+
19
+ # ---- IA GPT-2 ----
20
  MODEL_NAME = "gpt2"
21
  tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)
22
  model = AutoModelForCausalLM.from_pretrained(MODEL_NAME)
23
 
24
+ # ---- DSP: Decodificaci贸n de audio ----
25
+ def decodificar_audio(audio_path, progress=gr.Progress()):
26
+ if audio_path is None:
27
+ return "鈿狅笍 Sin audio"
 
 
 
 
 
 
28
 
29
+ y, sr = librosa.load(audio_path, sr=None, mono=True)
30
+ n = len(y)
31
+ yf = fft(y)
32
+ xf = fftfreq(n, 1/sr)[:n//2]
33
+ magnitud = np.abs(yf[0:n//2])
34
 
35
+ secuencia = ""
36
+ ventana_ms = 50
37
+ ventana_len = int(sr * ventana_ms / 1000)
 
 
 
 
38
 
39
+ for start in range(0, n, ventana_len):
40
+ frame = y[start:start+ventana_len]
41
+ if len(frame) == 0:
42
+ continue
43
+ yf_frame = fft(frame)
44
+ magn = np.abs(yf_frame[:len(frame)//2])
45
+ freqs = fftfreq(len(frame), 1/sr)[:len(frame)//2]
 
 
 
 
 
 
 
 
46
 
47
+ idx_max = np.argmax(magn)
48
+ freq_max = freqs[idx_max]
 
 
 
 
 
 
 
49
 
50
+ idx_letra = (np.abs(FRECUENCIAS - freq_max)).argmin()
51
+ letra = LETRAS[idx_letra]
52
+ secuencia += letra
 
 
 
 
 
 
 
53
 
54
+ # Eliminar repeticiones consecutivas
55
+ secuencia_limpia = ""
 
56
  prev = None
57
+ for c in secuencia:
58
  if c != prev:
59
+ secuencia_limpia += c
60
  prev = c
 
61
 
62
+ # Limitar longitud para IA
63
+ seq_ia = secuencia_limpia[:30]
64
+
65
+ # ---- Generar palabras y frases con IA ----
66
+ prompt = f"""Secuencia de letras: {seq_ia}
67
+ Usa solo estas letras para formar palabras y luego frases coherentes.
68
+ No agregues letras nuevas, solo combina las detectadas. Devuelve palabras y frases legibles:\n"""
69
  input_ids = tokenizer(prompt, return_tensors="pt").input_ids
70
  out = model.generate(
71
  input_ids,
 
75
  top_p=0.92,
76
  top_k=50
77
  )
78
+ texto_ia = tokenizer.decode(out[0], skip_special_tokens=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
 
80
+ reporte = "SECUENCIA DETECTADA\n"
81
+ reporte += secuencia + "\n\n"
82
+ reporte += "SECUENCIA LIMPIA\n"
83
+ reporte += secuencia_limpia + "\n\n"
84
+ reporte += "PALABRAS Y FRASES GENERADAS\n"
85
+ reporte += texto_ia
86
  return reporte
87
 
88
  # ---- Interfaz Gradio ----
89
  with gr.Blocks() as demo:
90
+ gr.Markdown("# Decodificador de Frecuencias + IA de Palabras")
91
  audio = gr.Audio(type="filepath", sources=["upload","microphone"])
92
+ btn = gr.Button("Procesar")
93
  salida = gr.Textbox(lines=15)
94
+ btn.click(decodificar_audio, inputs=audio, outputs=salida)
95
 
96
  demo.launch()