Skip to content

Pass python BytesIO() stream to Precise Runner? #221

Open
@ScottMonaghan

Description

@ScottMonaghan

Hello,

I’ve been testing Precise as a wake-word engine for my companion robot project (GitHub - ScottMonaghan/robud: Loveable Accessible Autonomous Robot).

If I create a stream object using pyaudio.open, I’m able to specify my input device, pass it into the precise runner in python and it works great!

The problem is, I can’t allow the precise python script to take full control of my audio card because it’s used by several other processes.

The way that I handle this is that I publish the raw input bytestream with the Moquitto MQTT messaging system.

With other tools I’m able to subscribe to that stream and then use it the audio however I wish, but with precise I’ve been having trouble.

I’m able to subscribe and write the stream to a BytesIO object, and I can specify the BytesIO object as the stream when initializing my runner.

But when I start the runner, I get an error stating there are 0 frames.

Can anyone offer any advice on how to achieve this?

Here are the related python snippets:

def on_message_audio_input_data(client:mqtt.Client, userdata, message):
#print("audio recieived")
audio_buffer:BytesIO = userdata["audio_buffer"]
audio_buffer.write(message.payload)

#Create audio buffer
audio_buffer = BytesIO()

client_userdata = {"audio_buffer":audio_buffer}
mqtt_client = mqtt.Client(client_id=MQTT_CLIENT_NAME,userdata=client_userdata)
mqtt_client.connect(MQTT_BROKER_ADDRESS)
logger.info('MQTT Client Connected')
mqtt_client.subscribe(TOPIC_AUDIO_INPUT_DATA)
mqtt_client.message_callback_add(TOPIC_AUDIO_INPUT_DATA, on_message_audio_input_data)
logger.info('Subscribed to ' + TOPIC_AUDIO_INPUT_DATA)
#stream.start_stream()
logger.info('Waiting for messages...')
mqtt_client.loop_start()

#Create audio buffer
#audio_buffer = BytesIO()

engine = PreciseEngine('/home/robud/Downloads/precise-engine/precise-engine', '/home/robud/src/precise-data/hey-mycroft.pb')

runner = PreciseRunner(engine=engine, stream=audio_buffer, on_activation=lambda: print('activated!'))
#runner.start()

# Sleep forever
from time import sleep
while True:
    if audio_buffer.getbuffer().nbytes > CHUNK and not(runner.running): #2 bytes for each 16bit frame
        logger.info('runner started')
        runner.start()
    sleep(0.1)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions