9
9
import logging
10
10
11
11
from ...utils import verboselogs
12
+
12
13
from .constants import LOGGING , CHANNELS , RATE , CHUNK
13
14
14
15
if TYPE_CHECKING :
@@ -22,8 +23,8 @@ class Microphone: # pylint: disable=too-many-instance-attributes
22
23
23
24
_logger : verboselogs .VerboseLogger
24
25
25
- _audio : "pyaudio.PyAudio"
26
- _stream : "pyaudio.Stream"
26
+ _audio : Optional [ "pyaudio.PyAudio" ] = None
27
+ _stream : Optional [ "pyaudio.Stream" ] = None
27
28
28
29
_chunk : int
29
30
_rate : int
@@ -145,77 +146,49 @@ def start(self) -> bool:
145
146
self ._asyncio_thread = None
146
147
self ._push_callback = self ._push_callback_org
147
148
148
- self ._stream = self ._audio .open (
149
- format = self ._format ,
150
- channels = self ._channels ,
151
- rate = self ._rate ,
152
- input = True ,
153
- frames_per_buffer = self ._chunk ,
154
- input_device_index = self ._input_device_index ,
155
- stream_callback = self ._callback ,
156
- )
149
+ if self ._audio is not None :
150
+ self ._stream = self ._audio .open (
151
+ format = self ._format ,
152
+ channels = self ._channels ,
153
+ rate = self ._rate ,
154
+ input = True ,
155
+ output = False ,
156
+ frames_per_buffer = self ._chunk ,
157
+ input_device_index = self ._input_device_index ,
158
+ stream_callback = self ._callback ,
159
+ )
160
+
161
+ if self ._stream is None :
162
+ self ._logger .error ("start failed. No stream created." )
163
+ self ._logger .debug ("Microphone.start LEAVE" )
164
+ return False
157
165
158
166
self ._exit .clear ()
159
- self ._stream .start_stream ()
167
+ if self ._stream is not None :
168
+ self ._stream .start_stream ()
160
169
161
170
self ._logger .notice ("start succeeded" )
162
171
self ._logger .debug ("Microphone.start LEAVE" )
163
172
return True
164
173
165
- def _callback (
166
- self , input_data , frame_count , time_info , status_flags
167
- ): # pylint: disable=unused-argument
168
- """
169
- The callback used to process data in callback mode.
170
- """
171
- # dynamic import of pyaudio as not to force the requirements on the SDK (and users)
172
- import pyaudio # pylint: disable=import-outside-toplevel
173
-
174
- self ._logger .debug ("Microphone._callback ENTER" )
175
-
176
- if self ._exit .is_set ():
177
- self ._logger .info ("exit is Set" )
178
- self ._logger .notice ("_callback stopping..." )
179
- self ._logger .debug ("Microphone._callback LEAVE" )
180
- return None , pyaudio .paAbort
181
-
182
- if input_data is None :
183
- self ._logger .warning ("input_data is None" )
184
- self ._logger .debug ("Microphone._callback LEAVE" )
185
- return None , pyaudio .paContinue
186
-
187
- try :
188
- if self ._is_muted :
189
- size = len (input_data )
190
- input_data = b"\x00 " * size
191
-
192
- self ._push_callback (input_data )
193
- except Exception as e :
194
- self ._logger .error ("Error while sending: %s" , str (e ))
195
- self ._logger .debug ("Microphone._callback LEAVE" )
196
- raise
197
-
198
- self ._logger .debug ("Microphone._callback LEAVE" )
199
- return input_data , pyaudio .paContinue
200
-
201
174
def mute (self ) -> bool :
202
175
"""
203
176
mute - mutes the microphone stream
204
177
205
178
Returns:
206
179
bool: True if the stream was muted, False otherwise
207
180
"""
208
- self ._logger .debug ("Microphone.mute ENTER" )
181
+ self ._logger .verbose ("Microphone.mute ENTER" )
209
182
210
183
if self ._stream is None :
211
184
self ._logger .error ("mute failed. Library not initialized." )
212
- self ._logger .debug ("Microphone.mute LEAVE" )
185
+ self ._logger .verbose ("Microphone.mute LEAVE" )
213
186
return False
214
187
215
188
self ._is_muted = True
216
189
217
190
self ._logger .notice ("mute succeeded" )
218
- self ._logger .debug ("Microphone.mute LEAVE" )
191
+ self ._logger .verbose ("Microphone.mute LEAVE" )
219
192
return True
220
193
221
194
def unmute (self ) -> bool :
@@ -225,19 +198,42 @@ def unmute(self) -> bool:
225
198
Returns:
226
199
bool: True if the stream was unmuted, False otherwise
227
200
"""
228
- self ._logger .debug ("Microphone.unmute ENTER" )
201
+ self ._logger .verbose ("Microphone.unmute ENTER" )
229
202
230
203
if self ._stream is None :
231
204
self ._logger .error ("unmute failed. Library not initialized." )
232
- self ._logger .debug ("Microphone.unmute LEAVE" )
205
+ self ._logger .verbose ("Microphone.unmute LEAVE" )
233
206
return False
234
207
235
208
self ._is_muted = False
236
209
237
210
self ._logger .notice ("unmute succeeded" )
238
- self ._logger .debug ("Microphone.unmute LEAVE" )
211
+ self ._logger .verbose ("Microphone.unmute LEAVE" )
239
212
return True
240
213
214
+ def is_muted (self ) -> bool :
215
+ """
216
+ is_muted - returns the state of the stream
217
+
218
+ Args:
219
+ None
220
+
221
+ Returns:
222
+ True if the stream is muted, False otherwise
223
+ """
224
+ self ._logger .spam ("Microphone.is_muted ENTER" )
225
+
226
+ if self ._stream is None :
227
+ self ._logger .spam ("is_muted: stream is None" )
228
+ self ._logger .spam ("Microphone.is_muted LEAVE" )
229
+ return False
230
+
231
+ val = self ._is_muted
232
+
233
+ self ._logger .spam ("is_muted: %s" , val )
234
+ self ._logger .spam ("Microphone.is_muted LEAVE" )
235
+ return val
236
+
241
237
def finish (self ) -> bool :
242
238
"""
243
239
finish - stops the microphone stream
@@ -255,7 +251,6 @@ def finish(self) -> bool:
255
251
self ._logger .notice ("stopping stream..." )
256
252
self ._stream .stop_stream ()
257
253
self ._stream .close ()
258
- self ._stream = None # type: ignore
259
254
self ._logger .notice ("stream stopped" )
260
255
261
256
# clean up the thread
@@ -265,13 +260,44 @@ def finish(self) -> bool:
265
260
self ._asyncio_thread
266
261
is not None
267
262
):
268
- self ._logger .notice ("stopping asyncio loop ..." )
263
+ self ._logger .notice ("stopping _asyncio_loop ..." )
269
264
self ._asyncio_loop .call_soon_threadsafe (self ._asyncio_loop .stop )
270
265
self ._asyncio_thread .join ()
271
- self ._asyncio_thread = None
272
266
self ._logger .notice ("_asyncio_thread joined" )
273
267
268
+ self ._stream = None
269
+ self ._asyncio_thread = None
270
+
274
271
self ._logger .notice ("finish succeeded" )
275
272
self ._logger .debug ("Microphone.finish LEAVE" )
276
273
277
274
return True
275
+
276
+ def _callback (
277
+ self , input_data , frame_count , time_info , status_flags
278
+ ): # pylint: disable=unused-argument
279
+ """
280
+ The callback used to process data in callback mode.
281
+ """
282
+ # dynamic import of pyaudio as not to force the requirements on the SDK (and users)
283
+ import pyaudio # pylint: disable=import-outside-toplevel
284
+
285
+ if self ._exit .is_set ():
286
+ self ._logger .notice ("_callback exit is Set. stopping..." )
287
+ return None , pyaudio .paAbort
288
+
289
+ if input_data is None :
290
+ self ._logger .warning ("input_data is None" )
291
+ return None , pyaudio .paContinue
292
+
293
+ try :
294
+ if self ._is_muted :
295
+ size = len (input_data )
296
+ input_data = b"\x00 " * size
297
+
298
+ self ._push_callback (input_data )
299
+ except Exception as e :
300
+ self ._logger .error ("Error while sending: %s" , str (e ))
301
+ raise
302
+
303
+ return input_data , pyaudio .paContinue
0 commit comments