@@ -69,7 +69,6 @@ def __init__(
69
69
self .conversation_ended_wait_timeout = 5
70
70
self ._session_needs_closing = False
71
71
self ._audio_buffer = None
72
- self ._pyaudio = pyaudio .PyAudio
73
72
74
73
# The following asyncio fields are fully instantiated in
75
74
# _init_synchronization_primitives
@@ -86,7 +85,6 @@ async def _init_synchronization_primitives(self):
86
85
"""
87
86
self ._conversation_started = asyncio .Event ()
88
87
self ._conversation_ended = asyncio .Event ()
89
- self ._pyaudio = pyaudio .PyAudio ()
90
88
self ._buffer_semaphore = asyncio .BoundedSemaphore (
91
89
self .connection_settings .message_buffer_size
92
90
)
@@ -165,7 +163,6 @@ async def _consumer(self, message, from_cli: False):
165
163
:raises ForceEndSession: If this was raised by the user's event
166
164
handler.
167
165
"""
168
- LOGGER .debug (message )
169
166
if isinstance (message , (bytes , bytearray )):
170
167
# add an audio message to local buffer only when running from cli
171
168
if from_cli :
@@ -174,6 +171,7 @@ async def _consumer(self, message, from_cli: False):
174
171
# so we need to set it here for event_handler to work
175
172
message_type = ServerMessageType .audio
176
173
else :
174
+ LOGGER .debug (message )
177
175
message = json .loads (message )
178
176
message_type = message .get ("message" )
179
177
@@ -200,14 +198,15 @@ async def _consumer(self, message, from_cli: False):
200
198
raise ConversationError (message ["reason" ])
201
199
202
200
async def _read_from_microphone (self ):
201
+ _pyaudio = pyaudio .PyAudio ()
203
202
print (
204
- f"Default input device: { self . _pyaudio .get_default_input_device_info ()['name' ]} "
203
+ f"Default input device: { _pyaudio .get_default_input_device_info ()['name' ]} "
205
204
)
206
205
print (
207
- f"Default output device: { self . _pyaudio .get_default_output_device_info ()['name' ]} "
206
+ f"Default output device: { _pyaudio .get_default_output_device_info ()['name' ]} "
208
207
)
209
208
print ("Start speaking..." )
210
- stream = self . _pyaudio .open (
209
+ stream = _pyaudio .open (
211
210
format = pyaudio .paInt16 ,
212
211
channels = 1 ,
213
212
rate = self .audio_settings .sample_rate ,
@@ -229,13 +228,15 @@ async def _read_from_microphone(self):
229
228
self .seq_no += 1
230
229
self ._call_middleware (ClientMessageType .AddAudio , audio_chunk , True )
231
230
await self .websocket .send (audio_chunk )
231
+ # send audio at a constant rate
232
+ await asyncio .sleep (0.01 )
232
233
except KeyboardInterrupt :
233
234
await self .websocket .send (self ._end_of_audio ())
234
235
finally :
235
236
await self ._wait_for_conversation_ended ()
236
237
stream .stop_stream ()
237
238
stream .close ()
238
- self . _pyaudio .terminate ()
239
+ _pyaudio .terminate ()
239
240
240
241
async def _consumer_handler (self , from_cli : False ):
241
242
"""
@@ -295,7 +296,8 @@ async def _playback_handler(self):
295
296
"""
296
297
Reads audio binary messages from the playback buffer and plays them to the user.
297
298
"""
298
- stream = self ._pyaudio .open (
299
+ _pyaudio = pyaudio .PyAudio ()
300
+ stream = _pyaudio .open (
299
301
format = pyaudio .paInt16 ,
300
302
channels = 1 ,
301
303
rate = self .audio_settings .sample_rate ,
@@ -309,13 +311,15 @@ async def _playback_handler(self):
309
311
audio_message = await self ._audio_buffer .get ()
310
312
stream .write (audio_message )
311
313
self ._audio_buffer .task_done ()
314
+ # read from buffer at a constant rate
315
+ await asyncio .sleep (0.005 )
312
316
except Exception as e :
313
317
LOGGER .error (f"Error during audio playback: { e } " )
314
318
raise e
315
319
finally :
316
320
stream .close ()
317
321
stream .stop_stream ()
318
- self . _pyaudio .terminate ()
322
+ _pyaudio .terminate ()
319
323
320
324
def _call_middleware (self , event_name , * args ):
321
325
"""
0 commit comments