PyAudio callback unterbrächen und neu starten

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
cR0N0s
User
Beiträge: 19
Registriert: Sonntag 15. März 2020, 15:45

Hi,
ich bastelte aktuell an einer Kleinigkeit und sammle mit jedem Schritt auch mehr Erfahrung im Umgang mit Python.
Dafür hab ich mich online informiert und auch genau das richtige für mein kleines Projekt zusammen gesucht.

Mit meinem Programm will ich in pyqt5 über einen Button das zuhören über ein Mikrophone einleiten.
Das Programm soll solange laufen und lauschen, bis der gewünschte Key von DeepSpeech übergeben wird. Darauf hin soll der Audiostream unterbrochen werden und die mit dem Key verbundene Aktion ausgeführt werden.
Im Anschluss soll der Audiostream jungfräulich neu aufgesetzt werden und genauso auch immer weiter laufen.

Mein Problem ist.
Den von PyAudio einmal eingeleiteten Audiostream bekomme ich wie gewünscht ohne Fehler angehalten, aber leider mach das erneute Starten Probleme und lässt das Programm ohne einen Fehlercode abstürzen.

Code: Alles auswählen

import PyQt5.QtWidgets as widgets
import PyQt5.uic as uic
import sys
import deepspeech
import numpy as np
import pyaudio

model = deepspeech.Model("deepspeech-0.9.3-models.pbmm")
model.enableExternalScorer("deepspeech-0.9.3-models.scorer")
model.setScorerAlphaBeta(0.75, 1.85)
model.setBeamWidth(500)
text_so_far = ''
start_stop = 1
ds_stream = model.createStream()

app = widgets.QApplication(sys.argv)
ds = uic.loadUi("DeepSpeech.ui")



def process_audio(in_data, frame_count, time_info, status):
    global text_so_far
    global start_stop
    data16 = np.frombuffer(in_data, dtype=np.int16)
    ds_stream.feedAudioContent(data16)
    text = ds_stream.intermediateDecode()
    if text != text_so_far:
        print('Interim text = {}'.format(text))
        if "stop" in text:
            start_stop = 0
            print("stop")
        elif "start" in text:
            start_stop = 0
            print("start")
        #und immer so weiter

        text_so_far = text
    return (in_data, pyaudio.paContinue)



def start_zuhoeren():
    global start_stop

    audio = pyaudio.PyAudio()
    stream = audio.open(
        format=pyaudio.paInt16,
        channels=1,
        rate=16000,
        input=True,
        frames_per_buffer=1024,
        stream_callback=process_audio
        )

    print('Please start speaking')
    stream.start_stream()

    while stream.is_active():
        
        if start_stop == 0:
            start_stop = 1
            stream.stop_stream()
    stream.close()
    audio.terminate()
    print('Finished recording.')




ds.pushButton.clicked.connect(start_zuhoeren)


ds.show()
sys.exit(app.exec_())

Danke schon mal im voraus, falls jemand mir weiter helfen kann. :)
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Warum? Es ist eine Sache, Buffer die angeliefert werden einfach zu ignorieren. Weil man damit gerade nichts anfangen kann.

Aber wegen jeder Kleinigkeit jedes Mal die gesamte Audio Infrastruktur abzureißen und wieder aufzubauen ist unnötig und teuer. Lässt man also am besten.
cR0N0s
User
Beiträge: 19
Registriert: Sonntag 15. März 2020, 15:45

Das hab ich mir auch schon überlegt, dass der erneute Aufbau des Audiostreams nicht besonders Ressourcenschonend sein könnte.

Trotzdem wäre es für mich praktisch, wenn das Programm nicht benutzt wird, dann auch der Audiostream nicht weiter Läuft und somit auch nicht weiter lauscht und Daten produziert, ohne gleich das ganze Programm zu schließen.

Aber alternative ist es praktisch zu erfahren, wie ich auch (für eine effizientere Ausnutzung der Ressourcen) den Audiostream entleert bekomme, damit das Programm sich nicht an diesem vorhanden Key im Stream aufhängt und in einer Dauerschleife weiter läuft.
Dann schau ich erst mal, ob ich wenigstens den Stream vom Inhalt befreien kann.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Was musst du denn da befreien? Wenn du die Daten nicht verwenden willst, benutze sie einfach nicht.

Was aber notwendig ist (und eh das standard Vorgehen darstellt) ist das callback basierte API zu benutzten. Sonst blockiert deine GUI sekundenlang.
cR0N0s
User
Beiträge: 19
Registriert: Sonntag 15. März 2020, 15:45

Problem gelöst bzw. eine Lösung endlich gefunden.
Das Problem war eine immer länger werden Zeichenkette.
Ich weiß nicht, was ich bei der Suche anders gemacht hatte, hier hab ich endlich genau das gefunden, wonach ich gesucht hatte.
https://tradokk.com/echtzeit-spracherke ... eepspeech/
Trotzdem Danke für den einen oder anderen Gedanken anstoße.
Antworten