Search code examples
pythonsubprocessspeech-to-text

Get variable data from subprocess continuously


I have a subprocess that constantly listens to the microphone, converts the audio to text and stores the result. The code for this is

from os import environ, path
import pyaudio
from utils import micStream
from pocketsphinx.pocketsphinx import *
from sphinxbase.sphinxbase import *

MODELDIR = "PATH TO MODEL"

config = Decoder.default_config()
config.set_string('-hmm', path.join(MODELDIR, 'en-us/acoustic-model'))
config.set_string('-lm', path.join(MODELDIR, 'en-us/language-model.lm.bin'))
config.set_string('-dict', path.join(MODELDIR, 'en-us/language-dictionary.dict'))
config.set_string('-logfn', 'nul')
decoder = Decoder(config)

p = pyaudio.PyAudio()
stream = p.open(format=pyaudio.paInt16, channels=1, rate=16000, input=True, frames_per_buffer=1024)
stream.start_stream() 

in_speech_bf = False
decoder.start_utt()
while True:
    buf = stream.read(1024)
    if buf:
        decoder.process_raw(buf, False, False)
        if decoder.get_in_speech() != in_speech_bf:
            in_speech_bf = decoder.get_in_speech()
            if not in_speech_bf:
                decoder.end_utt()
                print(decoder.hyp().hypstr.lower())

                decoder.start_utt()
    else:
        break
decoder.end_utt()

I am trying to run this as a subprocess and have the parent read the string decoder.hyp().hypstr.lower() continuously without blocking the rest of the main process. I've tried

subprocess.check_output() and listener=subprocess.Popen([sys.executable,'file_name'])

But both seem to block my code. Is there a way to do this?


Solution

  • You can try something like this:

    
    from multiprocessing import Process, Queue          # ADD IMPORT
    
    from os import environ, path
    import pyaudio
    from utils import micStream
    from pocketsphinx.pocketsphinx import *
    from sphinxbase.sphinxbase import *
    
    
    def get_audio(q):
        MODELDIR = "PATH TO MODEL"
    
        config = Decoder.default_config()
        config.set_string('-hmm', path.join(MODELDIR, 'en-us/acoustic-model'))
        config.set_string('-lm', path.join(MODELDIR, 'en-us/language-model.lm.bin'))
        config.set_string('-dict', path.join(MODELDIR, 'en-us/language-dictionary.dict'))
        config.set_string('-logfn', 'nul')
        decoder = Decoder(config)
    
        p = pyaudio.PyAudio()
        stream = p.open(format=pyaudio.paInt16, channels=1, rate=16000, input=True, frames_per_buffer=1024)
        stream.start_stream()
    
        in_speech_bf = False
        decoder.start_utt()
        while True:
            buf = stream.read(1024)
            if buf:
                decoder.process_raw(buf, False, False)
                if decoder.get_in_speech() != in_speech_bf:
                    in_speech_bf = decoder.get_in_speech()
                    if not in_speech_bf:
                        decoder.end_utt()
                        q.put(decoder.hyp().hypstr.lower())    # PUT THE OUTPUT INTO QUEUE
                        decoder.start_utt()
            else:
                break
        decoder.end_utt()
    
    out_q = Queue()
    audio_p = Process(target=get_audio, args=(out_q,))
    audio_p.start()
    
    while True:
        # If data has been received process it
        if not out_q.empty():
            res = out_q.get()
            # Perform whatever needs to happen when the parent receives the output here
        # After processing the data, or if no data has been received
        # Put the code that needs to run in the main process here