def in_recording(self, message: Any, sender: RhasspyActor) -> None: """Handle messages in recording state.""" if isinstance(message, AudioData): # Forward to subscribers for receiver in self.receivers: self.send(receiver, message) # Append to buffers for buffer_name in self.buffers: self.buffers[buffer_name] += message.data elif isinstance(message, StartStreaming): self.receivers.append(message.receiver or sender) elif isinstance(message, StartRecordingToBuffer): self.buffers[message.buffer_name] = bytes() elif isinstance(message, StopStreaming): if message.receiver is None: # Clear all receivers self.receivers.clear() else: self.receivers.remove(message.receiver) elif isinstance(message, StopRecordingToBuffer): if message.buffer_name is None: # Clear all buffers self.buffers.clear() else: # Respond with buffer buffer = self.buffers.pop(message.buffer_name, bytes()) self.send(message.receiver or sender, AudioData(buffer)) # Check to see if anyone is still listening if not self.receivers and not self.buffers: # Terminate audio recording self.is_recording = False self.transition("started") self._logger.debug("Stopped recording from microphone (stdin)")
def process_data(self): """Forward single audio chunk.""" while True: data = sys.stdin.buffer.read(self.chunk_size) if self.is_recording and data: # Actor will forward self.send(self.myAddress, AudioData(data))
def gstreamer_thread_proc(): try: self._logger.debug(self.command) self.gstreamer_proc = subprocess.Popen( self.command, stdout=subprocess.PIPE ) first_audio = True while True: chunk = self.gstreamer_proc.stdout.read(self.chunk_size) if chunk: if first_audio: self._logger.debug("Receiving audio") first_audio = False message = AudioData(chunk) # Forward to subscribers for receiver in self.receivers: self.send(receiver, message) # Append to buffers for buffer_name in self.buffers: self.buffers[buffer_name] += message.data else: # Avoid 100% CPU time.sleep(0.01) except Exception: if self.gstreamer_proc is not None: self._logger.exception( "gstreamer_thread:Optional[threading.Thread]" )
def in_recording(self, message: Any, sender: RhasspyActor) -> None: """Handle messages in recording state.""" if isinstance(message, MqttMessage): if message.topic == self.topic_audio_frame: # Extract audio data with io.BytesIO(message.payload) as wav_buffer: with wave.open(wav_buffer, mode="rb") as wav_file: rate, width, channels = ( wav_file.getframerate(), wav_file.getsampwidth(), wav_file.getnchannels(), ) if (rate != 16000) or (width != 2) or (channels != 1): audio_data = convert_wav(message.payload) else: # Use original data audio_data = wav_file.readframes(wav_file.getnframes()) data_message = AudioData(audio_data) # Forward to subscribers for receiver in self.receivers: self.send(receiver, data_message) # Append to buffers for buffer_name in self.buffers: self.buffers[buffer_name] += audio_data elif isinstance(message, StartStreaming): self.receivers.append(message.receiver or sender) elif isinstance(message, StartRecordingToBuffer): self.buffers[message.buffer_name] = bytes() elif isinstance(message, StopStreaming): if message.receiver is None: # Clear all receivers self.receivers.clear() else: self.receivers.remove(message.receiver) elif isinstance(message, StopRecordingToBuffer): if message.buffer_name is None: # Clear all buffers self.buffers.clear() else: # Respond with buffer buffer = self.buffers.pop(message.buffer_name, bytes()) self.send(message.receiver or sender, AudioData(buffer))
def process_data() -> None: self.record_proc = subprocess.Popen(arecord_cmd, stdout=subprocess.PIPE) assert self.record_proc is not None while self.is_recording: # Pull from process STDOUT data = self.record_proc.stdout.read(self.chunk_size) if data: # Send to this actor to avoid threading issues self.send(self.myAddress, AudioData(data)) else: # Avoid 100% CPU usage time.sleep(0.01)
def do_POST(self): """Handle POST requests.""" try: self.recorder.get_response = None self.recorder.logger.debug("Receiving audio data") num_bytes = 0 while True: # Assume chunked transfer encoding chunk_size_str = self.rfile.readline().decode().strip() if not chunk_size_str: break chunk_size = int(chunk_size_str, 16) if chunk_size <= 0: break audio_chunk = self.rfile.read(chunk_size) # Consume \r\n self.rfile.read(2) num_bytes += len(audio_chunk) message = AudioData(audio_chunk) # Forward to subscribers for receiver in self.recorder.receivers: self.recorder.send(receiver, message) # Append to buffers for buffer_name in self.recorder.buffers: self.recorder.buffers[buffer_name] += message.data if (self.recorder.stop_after != "never") and ( self.recorder.get_response is not None ): # Stop self.send_response(200) self.end_headers() return self.send_response(200) self.end_headers() self.wfile.write(str(num_bytes).encode()) except Exception: self.recorder.logger.exception("do_POST")
def in_recording(self, message: Any, sender: RhasspyActor) -> None: """Handle messages in recording state.""" if isinstance(message, StartStreaming): self.receivers.append(message.receiver or sender) elif isinstance(message, StartRecordingToBuffer): self.buffers[message.buffer_name] = bytes() elif isinstance(message, StopStreaming): if message.receiver is None: # Clear all receivers self.receivers.clear() else: self.receivers.remove(message.receiver) elif isinstance(message, StopRecordingToBuffer): if message.buffer_name is None: # Clear all buffers self.buffers.clear() else: # Respond with buffer buffer = self.buffers.pop(message.buffer_name, bytes()) self.send(message.receiver or sender, AudioData(buffer)) # Check to see if anyone is still listening if not self.receivers and not self.buffers: self.transition("started")
def in_started(self, message: Any, sender: RhasspyActor) -> None: """Handle messages in started state.""" if isinstance(message, StopRecordingToBuffer): # Return empty buffer self._logger.warning("Dummy microphone system only returns empty buffers!") self.send(message.receiver or sender, AudioData(bytes()))
def stream_callback(data, frame_count, time_info, status): if data: # Send to this actor to avoid threading issues self.send(self.myAddress, AudioData(data)) return (data, pyaudio.paContinue)