Project

General

Profile

Funciones en el codigo » History » Version 1

Version 1/7 - Next » - Current version
fernanda ventura, 12/29/2023 12:39 PM


Funciones en el codigo

# Clase que representa la pantalla del usuario asistido
class AsistidoScreen(Screen):
    recording = False  # Indica si se está grabando
    frames = []  # Almacena fragmentos de audio
    audio_stream = None  # Flujo de entrada de audio
    sound = None  # Objeto para reproducir sonido
    file_name = "grabacion.wav"  # Nombre del archivo de audio

    # Inicia la grabación de audio en un hilo separado
    def iniciar_grabacion(self):
        if not self.recording:
            self.recording = True
            threading.Thread(target=self._grabar_audio).start()

    # Detiene la grabación de audio y reproduce el audio grabado en un hilo separado
    def detener_grabacion(self):
        if self.recording:
            self.recording = False
            threading.Thread(target=self._reproducir_audio).start()

    # Método privado que realiza la grabación de audio
    def _grabar_audio(self):
        CHUNK = 1024
        FORMAT = pyaudio.paInt16
        CHANNELS = 2
        RATE = 44100

        p = pyaudio.PyAudio()

        # Crea o sobrescribe el archivo de audio
        with open(self.file_name, 'wb'):
            pass

        # Abre el flujo de entrada de audio
        self.audio_stream = p.open(format=FORMAT,
                                   channels=CHANNELS,
                                   rate=RATE,
                                   input=True,
                                   frames_per_buffer=CHUNK)

        # Bucle de grabación
        while self.recording:
            data = self.audio_stream.read(CHUNK)
            self.frames.append(data)

        # Detiene y cierra el flujo de entrada de audio
        self.audio_stream.stop_stream()
        self.audio_stream.close()
        p.terminate()

        # Guarda los frames grabados en un archivo WAV
        with wave.open(self.file_name, 'wb') as wf:
            wf.setnchannels(CHANNELS)
            wf.setsampwidth(pyaudio.PyAudio().get_sample_size(FORMAT))
            wf.setframerate(RATE)
            wf.writeframes(b''.join(self.frames))

        # Reproduce el audio grabado
        self._reproducir_audio()

        # Limpia los frames grabados
        self.frames = []

    # Método privado que reproduce el audio grabado
    def _reproducir_audio(self):
        if self.frames:
            sound_data = b''.join(self.frames)

            # Carga el sonido y lo reproduce
            sound = SoundLoader.load(self.file_name)
            if sound:
                sound.play()

    # Se llama al abandonar la pantalla para detener el sonido y cerrar el flujo de audio
    def on_leave(self):
        if self.sound:
            self.sound.stop()
        if self.audio_stream:
            self.audio_stream.stop_stream()
            self.audio_stream.close()

    # Muestra un teclado en una ventana emergente
    def show_keyboard(self):
        self.keyboard_popup = Popup(title='Teclado',
                                    content=self._build_keyboard_layout(),
                                    size_hint=(None, None),
                                    size=(400, 300),
                                    auto_dismiss=True)
        self.keyboard_popup.open()

    # Construye el diseño del teclado en la ventana emergente
    def _build_keyboard_layout(self):
        layout = BoxLayout(orientation='vertical', spacing=10, padding=10)

        text_input = TextInput(multiline=False, readonly=True, halign='center', font_size=24)
        layout.add_widget(text_input)

        buttons_layout = GridLayout(cols=10, spacing=5, size_hint_y=None, height=150)

        # Diseño del teclado QWERTY
        qwerty_layout = [
            'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P',
            'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L',
            'Z', 'X', 'C', 'V', 'B', 'N', 'M',
            'Space', 'Borrar', 'Enter'
        ]

        # Agrega botones al diseño
        for button_text in qwerty_layout:
            buttons_layout.add_widget(Button(text=button_text, on_press=self._on_button_press))

        layout.add_widget(buttons_layout)

        return layout

    # Maneja el evento de presionar un botón en el teclado
    def _on_button_press(self, instance):
        current_text_input = self.find_text_input(self.keyboard_popup.content)

        # Acciones según el botón presionado
        if instance.text == 'Enter':
            self.reproducir_texto(current_text_input.text)
            current_text_input.text = ''
        elif instance.text == 'Space':
            current_text_input.text += ' '
        elif instance.text == 'Borrar':
            current_text_input.text = ''
        else:
            current_text_input.text += instance.text

    # Encuentra el TextInput entre los hijos de un layout
    def find_text_input(self, layout):
        for child in layout.children:
            if isinstance(child, TextInput):
                return child
            elif len(child.children) > 0:
                text_input = self.find_text_input(child)
                if text_input:
                    return text_input
        return None

    # Inicia la reproducción de texto en un hilo separado
    def reproducir_texto(self, texto):
        threading.Thread(target=self._reproducir_voz, args=(texto,)).start()

    # Método privado que reproduce el texto utilizando la biblioteca pyttsx3
    def _reproducir_voz(self, texto):
        engine = pyttsx3.init()
        engine.say(texto)
        engine.runAndWait()