Refactor audio recognition script and add new functionality for continuous listening
This commit is contained in:
@@ -5,6 +5,9 @@ from vosk import Model, KaldiRecognizer
|
|||||||
import ctypes
|
import ctypes
|
||||||
import time
|
import time
|
||||||
import keyboard
|
import keyboard
|
||||||
|
import winsound
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BUFFER = 2000 # Tamaño del buffer de audio
|
BUFFER = 2000 # Tamaño del buffer de audio
|
||||||
RECOGNITION_ACTIVE = False # Estado inicial del reconocimiento
|
RECOGNITION_ACTIVE = False # Estado inicial del reconocimiento
|
||||||
@@ -19,7 +22,10 @@ def is_key_pressed(key_code):
|
|||||||
|
|
||||||
# Carga el modelo de Vosk (español)
|
# Carga el modelo de Vosk (español)
|
||||||
def load_model(model_path="vosk-model-es-0.42"):
|
def load_model(model_path="vosk-model-es-0.42"):
|
||||||
return Model(model_path)
|
print("Cargando modelo de reconocimiento de voz, por favor espera...")
|
||||||
|
model = Model(model_path)
|
||||||
|
print("Modelo cargado exitosamente.")
|
||||||
|
return model
|
||||||
|
|
||||||
# Inicializa PyAudio
|
# Inicializa PyAudio
|
||||||
def initialize_audio():
|
def initialize_audio():
|
||||||
@@ -41,15 +47,18 @@ def toggle_recognition_state():
|
|||||||
state = "activado" if RECOGNITION_ACTIVE else "desactivado"
|
state = "activado" if RECOGNITION_ACTIVE else "desactivado"
|
||||||
print(f"Reconocimiento de voz {state}.")
|
print(f"Reconocimiento de voz {state}.")
|
||||||
|
|
||||||
|
|
||||||
|
# Escucha el audio del stream
|
||||||
|
def listen_audio(stream):
|
||||||
|
return stream.read(BUFFER, exception_on_overflow=False)
|
||||||
|
|
||||||
# Procesa el audio y realiza la transcripción
|
# Procesa el audio y realiza la transcripción
|
||||||
def process_audio(stream, recognizer):
|
def process_audio(data, recognizer):
|
||||||
data = stream.read(BUFFER, exception_on_overflow=False) # Lee el flujo de audio
|
|
||||||
if recognizer.AcceptWaveform(data):
|
if recognizer.AcceptWaveform(data):
|
||||||
result = recognizer.Result() # Obtiene la transcripción
|
result = recognizer.Result() # Obtiene la transcripción
|
||||||
text = eval(result)['text'].encode('utf-8').decode('utf-8')
|
text = eval(result)['text'].encode('utf-8').decode('utf-8')
|
||||||
if text.strip():
|
if text.strip():
|
||||||
text += ' '
|
print(text) # Muestra la transcripción en consola
|
||||||
print(text) # Agrega un espacio al final
|
|
||||||
keyboard.write(text) # Escribe el texto donde esté el cursor
|
keyboard.write(text) # Escribe el texto donde esté el cursor
|
||||||
|
|
||||||
# Cierra los recursos de audio
|
# Cierra los recursos de audio
|
||||||
@@ -62,24 +71,34 @@ def close_audio_resources(p, stream):
|
|||||||
def main():
|
def main():
|
||||||
global RECOGNITION_ACTIVE
|
global RECOGNITION_ACTIVE
|
||||||
|
|
||||||
print("Presiona 'AltGr' + 'P' para activar/desactivar el reconocimiento de voz...")
|
|
||||||
|
|
||||||
# Inicializa el modelo y los recursos de audio
|
# Inicializa el modelo y los recursos de audio
|
||||||
model = load_model()
|
model = load_model()
|
||||||
|
|
||||||
|
|
||||||
|
print("Presiona 'AltGr' + 'P' para activar/desactivar el reconocimiento de voz...")
|
||||||
|
|
||||||
|
|
||||||
p, stream = initialize_audio()
|
p, stream = initialize_audio()
|
||||||
recognizer = KaldiRecognizer(model, 16000)
|
recognizer = KaldiRecognizer(model, 16000)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
while True:
|
while True:
|
||||||
# Detecta si 'AltGr' y 'Ñ' están presionadas
|
# Detecta si 'AltGr' y 'P' están presionadas
|
||||||
if is_key_pressed(VK_ALTGR) and is_key_pressed(VK_AUX):
|
if is_key_pressed(VK_ALTGR) and is_key_pressed(VK_AUX):
|
||||||
toggle_recognition_state()
|
toggle_recognition_state()
|
||||||
while is_key_pressed(VK_ALTGR) or is_key_pressed(VK_AUX):
|
while is_key_pressed(VK_ALTGR) or is_key_pressed(VK_AUX):
|
||||||
time.sleep(0.1) # Espera a que se suelten las teclas para evitar múltiples activaciones
|
time.sleep(0.1) # Espera a que se suelten las teclas para evitar múltiples activaciones
|
||||||
|
|
||||||
# Procesa el audio si el reconocimiento está activado
|
# Leer audio continuamente
|
||||||
|
audio_data = listen_audio(stream)
|
||||||
|
|
||||||
|
# Procesar el audio según el estado del reconocimiento
|
||||||
if RECOGNITION_ACTIVE:
|
if RECOGNITION_ACTIVE:
|
||||||
process_audio(stream, recognizer)
|
process_audio(audio_data, recognizer)
|
||||||
|
else:
|
||||||
|
# Solo evalúa si hay un resultado válido, pero no lo usa
|
||||||
|
if recognizer.AcceptWaveform(audio_data):
|
||||||
|
recognizer.Result()
|
||||||
|
|
||||||
time.sleep(0.05) # Pequeña pausa para reducir la carga de la CPU
|
time.sleep(0.05) # Pequeña pausa para reducir la carga de la CPU
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,91 @@
|
|||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import pyaudio
|
||||||
|
from vosk import Model, KaldiRecognizer
|
||||||
|
import ctypes
|
||||||
|
import time
|
||||||
|
import keyboard
|
||||||
|
|
||||||
|
BUFFER = 2000 # Tamaño del buffer de audio
|
||||||
|
|
||||||
|
# Códigos virtuales para las teclas
|
||||||
|
VK_ALTGR = 0xA5 # AltGr (Right Alt)
|
||||||
|
VK_AUX = 0x50 # P (corresponde al código de tecla en el teclado español)
|
||||||
|
|
||||||
|
# Función para verificar si una tecla está presionada
|
||||||
|
def is_key_pressed(key_code):
|
||||||
|
return ctypes.windll.user32.GetAsyncKeyState(key_code) & 0x8000 != 0
|
||||||
|
|
||||||
|
# Carga el modelo de Vosk (español)
|
||||||
|
def load_model(model_path="vosk-model-es-0.42"):
|
||||||
|
return Model(model_path)
|
||||||
|
|
||||||
|
# Inicializa PyAudio
|
||||||
|
def initialize_audio():
|
||||||
|
p = pyaudio.PyAudio()
|
||||||
|
stream = p.open(
|
||||||
|
format=pyaudio.paInt16,
|
||||||
|
channels=1,
|
||||||
|
rate=16000,
|
||||||
|
input=True,
|
||||||
|
frames_per_buffer=BUFFER
|
||||||
|
)
|
||||||
|
stream.start_stream()
|
||||||
|
return p, stream
|
||||||
|
|
||||||
|
|
||||||
|
# Escucha el audio del stream
|
||||||
|
def listen_audio(stream):
|
||||||
|
return stream.read(BUFFER, exception_on_overflow=False)
|
||||||
|
|
||||||
|
# Procesa el audio y realiza la transcripción
|
||||||
|
def process_audio(data, recognizer):
|
||||||
|
if recognizer.AcceptWaveform(data):
|
||||||
|
result = recognizer.Result() # Obtiene la transcripción
|
||||||
|
text = eval(result)['text'].encode('utf-8').decode('utf-8')
|
||||||
|
if text.strip():
|
||||||
|
print(text) # Muestra la transcripción en consola
|
||||||
|
keyboard.write(text) # Escribe el texto donde esté el cursor
|
||||||
|
|
||||||
|
|
||||||
|
# Cierra los recursos de audio
|
||||||
|
def close_audio_resources(p, stream):
|
||||||
|
stream.stop_stream()
|
||||||
|
stream.close()
|
||||||
|
p.terminate()
|
||||||
|
|
||||||
|
# Función principal del programa
|
||||||
|
def main():
|
||||||
|
print("Mantén presionado 'AltGr' + 'P' para activar el reconocimiento de voz...")
|
||||||
|
|
||||||
|
# Inicializa el modelo y los recursos de audio
|
||||||
|
model = load_model()
|
||||||
|
p, stream = initialize_audio()
|
||||||
|
recognizer = KaldiRecognizer(model, 16000)
|
||||||
|
|
||||||
|
accumulated_audio = b"" # Variable para almacenar el audio acumulado
|
||||||
|
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
# Detecta si 'AltGr' y 'P' están presionadas
|
||||||
|
if is_key_pressed(VK_ALTGR) and is_key_pressed(VK_AUX):
|
||||||
|
print("Reconocimiento activado. Habla ahora...")
|
||||||
|
while is_key_pressed(VK_ALTGR) and is_key_pressed(VK_AUX):
|
||||||
|
audio_data = listen_audio(stream) # Escucha el audio
|
||||||
|
accumulated_audio += audio_data # Acumula el audio mientras las teclas estén presionadas
|
||||||
|
print("Reconocimiento desactivado.")
|
||||||
|
|
||||||
|
# Procesa el audio acumulado cuando se sueltan las teclas
|
||||||
|
if accumulated_audio:
|
||||||
|
process_audio(accumulated_audio, recognizer)
|
||||||
|
accumulated_audio = b"" # Limpia el buffer de audio acumulado
|
||||||
|
|
||||||
|
time.sleep(0.05) # Pausa para reducir la carga de la CPU
|
||||||
|
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("\nPrograma terminado por el usuario.")
|
||||||
|
finally:
|
||||||
|
close_audio_resources(p, stream)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user