AudioServerStream.py
Go to the documentation of this file.
1 import errno
2 import threading
3 from six.moves import queue
4 import socket
5 import time
6 
7 # Audio recording parameters
8 RATE = 16000
9 CHUNK = 1600
10 
11 
12 class AudioServerStream(object):
13  """Opens a recording stream as a generator yielding the audio chunks."""
14  def __init__(self, rate=RATE, chunk=CHUNK, server_name='127.0.0.1',
15  port=4444):
16  self._rate = rate
17  self._chunk = chunk
18  self._server_name = server_name
19  self._port = port
20 
21  # Socket for connection
22  self.s = None
23  self._connected = False
24 
25  # Audio data thread to get data from server
26  self.data_thread = threading.Thread(target=self._get_server_data)
27  self.data_thread.daemon = True
28 
29  # Create a thread-safe buffer of audio data
30  self._buff = queue.Queue()
31  self.closed = True
32 
33  def _connect(self):
34  """Creates a socket to listen for audio data from the server."""
35  self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
36  self.s.connect((self._server_name, self._port))
37  self._connected = True
38 
39  def _get_server_data(self):
40  """Daemon thread that receives data from the audio socket and puts in a
41  buffer. Works just like _get_audio_data but data comes from server,
42  not mic.
43  """
44  try:
45  while True:
46  data = self.s.recv(self._chunk)
47  self._buff.put(data)
48  except KeyboardInterrupt as e:
49  print("AUDIO_SERVER: Shutdown from thread: {}".format(e))
50  self.__exit__()
51 
52  def __enter__(self):
53  """Makes 3 attempts at connecting to the audio server defined in the
54  parameters file.
55  """
56  print("AUDIO_SERVER: Using audio server.")
57  # Retry 3 times to connect
58  MAX_CONNECTION_RETRY = 3
59  for _ in range(0, MAX_CONNECTION_RETRY):
60  try:
61  self._connect()
62  except socket.error as e:
63  print("AUDIO_SERVER: Socket exception caught!\n{}\n"
64  "Retrying...".format(e))
65  time.sleep(1)
66  continue
67  break
68  # Yay :)
69  if self._connected:
70  print("AUDIO_SERVER: Connected to audio server.")
71  self.data_thread.start()
72  self.closed = False
73  return self
74  # Nay :c
75  else:
76  raise errno.ECONNREFUSED("AUDIO_SERVER: Unable to connect to audio "
77  "server! Make sure it is running and you "
78  "are connected on the same network.")
79 
80  def __exit__(self, type, value, traceback):
81  self.data_thread.join()
82  self.s.shutdown()
83  self.s.close()
84  self.closed = True
85  # Signal the generator to terminate so that the client's
86  # streaming_recognize method will not block the process termination.
87  self._buff.put(None)
88 
89  def generator(self):
90  while not self.closed:
91  # Use a blocking get() to ensure there's at least one chunk of
92  # data, and stop iteration if the chunk is None, indicating the
93  # end of the audio stream.
94  chunk = self._buff.get()
95  if chunk is None:
96  return
97  data = [chunk]
98 
99  # Now consume whatever other data's still buffered.
100  while True:
101  try:
102  chunk = self._buff.get(block=False)
103  if chunk is None:
104  return
105  data.append(chunk)
106  except queue.Empty:
107  break
108 
109  yield b''.join(data)
def __init__(self, rate=RATE, chunk=CHUNK, server_name='127.0.0.1', port=4444)


dialogflow_ros
Author(s): Anas Abou Allaban
autogenerated on Mon Jun 10 2019 13:02:59