pyaudio - "Слушать", пока не будет обнаружен голос, а затем записать в файл.wav
У меня есть некоторые проблемы, и я не могу понять мою идею.
То, что я пытаюсь сделать, это:
Попросите микрофон "прослушать" вокализованный голос (выше определенного порога), а затем начните запись в файл.wav, пока человек не перестанет говорить, или сигнала больше не будет. Например:
begin:
listen() -> nothing is being said
listen() -> nothing is being said
listen() -> VOICED - _BEGIN RECORDING_
listen() -> VOICED - _BEGIN RECORDING_
listen() -> UNVOICED - _END RECORDING_
end
Я хочу сделать это также с использованием "потоков", чтобы создавался поток, который постоянно "слушал" файл, и другой поток начинался, когда озвучивались данные. Но я не могу на всю жизнь понять, как Я должен идти об этом.. Вот мой код до сих пор:
import wave
import sys
import threading
from array import array
from sys import byteorder
try:
import pyaudio
CHECK_PYLIB = True
except ImportError:
CHECK_PYLIB = False
class Audio:
_chunk = 0.0
_format = 0.0
_channels = 0.0
_rate = 0.0
record_for = 0.0
stream = None
p = None
sample_width = None
THRESHOLD = 500
# initial constructor to accept params
def __init__(self, chunk, format, channels, rate):
#### set data-types
self._chunk = chunk
self.format = pyaudio.paInt16,
self.channels = channels
self.rate = rate
self.p = pyaudio.PyAudio();
def open(self):
# print "opened"
self.stream = self.p.open(format=pyaudio.paInt16,
channels=2,
rate=44100,
input=True,
frames_per_buffer=1024);
return True
def record(self):
# create a new instance/thread to record the sound
threading.Thread(target=self.listen).start();
def is_silence(snd_data):
return max(snd_data) < THRESHOLD
def listen(self):
r = array('h')
while True:
snd_data = array('h', self.stream.read(self._chunk))
if byteorder == 'big':
snd_data.byteswap()
r.extend(snd_data)
return sample_width, r
Я предполагаю, что мог бы записать "5" вторых блоков, а затем, если блок считается "озвученным", тогда поток должен быть запущен до тех пор, пока не будут собраны все голосовые данные. Однако, потому что в настоящее время это в while True:
я не хочу записывать все аудио до тех пор, пока не будут озвучены команды, например, "нет голоса", "нет голоса", "голос", "голос", "нет голоса", "нет голоса", я просто хочу "голос" внутри файла WAV.. У кого-нибудь есть какие-либо предложения?
Спасибо
РЕДАКТИРОВАТЬ:
import wave
import sys
import time
import threading
from array import array
from sys import byteorder
from Queue import Queue, Full
import pyaudio
CHUNK_SIZE = 1024
MIN_VOLUME = 500
BUF_MAX_SIZE = 1024 * 10
process_g = 0
def main():
stopped = threading.Event()
q = Queue(maxsize=int(round(BUF_MAX_SIZE / CHUNK_SIZE)))
listen_t = threading.Thread(target=listen, args=(stopped, q))
listen_t.start()
process_g = threading.Thread(target=process, args=(stopped, q))
process_g.start()
try:
while True:
listen_t.join(0.1)
process_g.join(0.1)
except KeyboardInterrupt:
stopped.set()
listen_t.join()
process_g.join()
def process(stopped, q):
while True:
if stopped.wait(timeout = 0):
break
print "I'm processing.."
time.sleep(300)
def listen(stopped, q):
stream = pyaudio.PyAudio().open(
format = pyaudio.paInt16,
channels = 2,
rate = 44100,
input = True,
frames_per_buffer = 1024
)
while True:
if stopped and stopped.wait(timeout=0):
break
try:
print process_g
for i in range(0, int(44100 / 1024 * 5)):
data_chunk = array('h', stream.read(CHUNK_SIZE))
vol = max(data_chunk)
if(vol >= MIN_VOLUME):
print "WORDS.."
else:
print "Nothing.."
except Full:
pass
if __name__ == '__main__':
main()
Теперь, после каждых 5 секунд, мне нужно выполнить функцию "process", а затем обработать данные (time.delay(10), пока он это делает, и затем начать запись обратно…)
3 ответа
Смотри сюда:
https://github.com/jeysonmc/python-google-speech-scripts/blob/master/stt_google.py
Он даже конвертирует Wav во FLAC и отправляет его в API Google Speech, просто удалите функцию stt_google_wav, если она вам не нужна;)
Потратив некоторое время на это, я придумал следующий код, который, кажется, делает то, что вам нужно. Что он не делает, конечно, это записать аудио данные в .wav
(или эквивалентный) файл, но вы можете реализовать это самостоятельно:
import threading
from array import array
from Queue import Queue, Full
import pyaudio
CHUNK_SIZE = 1024
MIN_VOLUME = 500
# if the recording thread can't consume fast enough, the listener will start discarding
BUF_MAX_SIZE = CHUNK_SIZE * 10
def main():
stopped = threading.Event()
q = Queue(maxsize=int(round(BUF_MAX_SIZE / CHUNK_SIZE)))
listen_t = threading.Thread(target=listen, args=(stopped, q))
listen_t.start()
record_t = threading.Thread(target=record, args=(stopped, q))
record_t.start()
try:
while True:
listen_t.join(0.1)
record_t.join(0.1)
except KeyboardInterrupt:
stopped.set()
listen_t.join()
record_t.join()
def record(stopped, q):
while True:
if stopped.wait(timeout=0):
break
chunk = q.get()
vol = max(chunk)
if vol >= MIN_VOLUME:
# TODO: write to file
print "O",
else:
print "-",
def listen(stopped, q):
stream = pyaudio.PyAudio().open(
format=pyaudio.paInt16,
channels=2,
rate=44100,
input=True,
frames_per_buffer=1024,
)
while True:
if stopped.wait(timeout=0):
break
try:
q.put(array('h', stream.read(CHUNK_SIZE)))
except Full:
pass # discard
if __name__ == '__main__':
main()
Я нашел очень простое решение, связанное с длительностью, паузой и т. д.
with harvard as source:
audio = r.record(source, offset=4, duration=3)
r.recognize_google(audio)
См.: Полное руководство по распознаванию речи с помощью Python.