0

I'm using webrtcvad to detect whether speech is present in audio from a microphone. I want to start the input stream after a specific event which happens in a thread. When I try to start the stream from a thread I get this error.

File "C:\Python32\lib\site-packages\sounddevice.py", line 2745, in _check
 raise PortAudioError(errormsg, err, hosterror_info)
sounddevice.PortAudioError: Error starting stream: 
Unanticipated host error [PaErrorCode -9999]: 'WdmSyncIoctl: DeviceIoControl GLE = 0x00000492 
(prop_set = {1464EDA5-6A8F-11D1-9AA7-00A0C9223196}, prop_id = 0)' [Windows WDM-KS error 0]

My test code is below, if I start the stream outside the thread with start_stream() it works fine but if I try and start it from the thread I get the error.

import numpy as np
import webrtcvad
import threading

def voice_activity_detection(audio_data):
    return vad.is_speech(audio_data, sample_rate)


def audio_callback(indata, frames, time, status):
    assert frames == block_size
    audio_data = indata[::downsample, mapping]        # possibly downsample, in a naive way
    audio_data = map(lambda x: (x+1)/2, audio_data)   # normalize from [-1,+1] to [0,1], you might not need it with different microphones/drivers
    audio_data = np.fromiter(audio_data, np.float16)  # adapt to expected float type
    audio_data = audio_data.tobytes()
    detection = voice_activity_detection(audio_data)
    print(detection)

        
channels = [1]
mapping  = [c - 1 for c in channels]
device_info = sd.query_devices(16, 'input')
sample_rate = int(device_info['default_samplerate'])
interval_size = 10 
downsample = 1
block_size = sample_rate * interval_size / 1000
vad = webrtcvad.Vad(1)

stream = sd.InputStream(
    device=16,  # mic is device 16
    channels=max(channels),
    samplerate=sample_rate,
    blocksize=int(block_size),
    callback=audio_callback)

def start_stream():
    stream.start()

class Threader(threading.Thread):
    def __init__(self, *args, **kwargs):
        threading.Thread.__init__(self, *args, **kwargs)
        self.start()

    def run(self):
        if self.name == 'mythread':
            print("Started mythread")
            start_stream()
            
Threader(name='mythread')    
Andrew Smith
  • 117
  • 9

0 Answers0