5
5
import inspect
6
6
import asyncio
7
7
import threading
8
- from typing import Optional , Callable , TYPE_CHECKING
8
+ from typing import Optional , Callable , Union , TYPE_CHECKING
9
9
import logging
10
10
11
11
from ...utils import verboselogs
@@ -21,10 +21,10 @@ class Microphone: # pylint: disable=too-many-instance-attributes
21
21
"""
22
22
23
23
_logger : verboselogs .VerboseLogger
24
- _exit : threading .Event
25
24
26
25
_audio : "pyaudio.PyAudio"
27
26
_stream : "pyaudio.Stream"
27
+
28
28
_chunk : int
29
29
_rate : int
30
30
_format : int
@@ -34,9 +34,10 @@ class Microphone: # pylint: disable=too-many-instance-attributes
34
34
35
35
_asyncio_loop : asyncio .AbstractEventLoop
36
36
_asyncio_thread : threading .Thread
37
+ _exit : threading .Event
37
38
38
- _push_callback_org : object
39
- _push_callback : object
39
+ _push_callback_org : Optional [ Callable ] = None
40
+ _push_callback : Optional [ Callable ] = None
40
41
41
42
def __init__ (
42
43
self ,
@@ -53,6 +54,7 @@ def __init__(
53
54
self ._logger = verboselogs .VerboseLogger (__name__ )
54
55
self ._logger .addHandler (logging .StreamHandler ())
55
56
self ._logger .setLevel (verbose )
57
+
56
58
self ._exit = threading .Event ()
57
59
58
60
self ._audio = pyaudio .PyAudio ()
@@ -71,9 +73,16 @@ def _start_asyncio_loop(self) -> None:
71
73
72
74
def is_active (self ) -> bool :
73
75
"""
74
- returns True if the stream is active, False otherwise
76
+ is_active - returns the state of the stream
77
+
78
+ Args:
79
+ None
80
+
81
+ Returns:
82
+ True if the stream is active, False otherwise
75
83
"""
76
84
self ._logger .debug ("Microphone.is_active ENTER" )
85
+
77
86
if self ._stream is None :
78
87
self ._logger .error ("stream is None" )
79
88
self ._logger .debug ("Microphone.is_active LEAVE" )
@@ -87,24 +96,34 @@ def is_active(self) -> bool:
87
96
88
97
def set_callback (self , push_callback : Callable ) -> None :
89
98
"""
90
- Set the callback function to be called when data is received.
99
+ set_callback - sets the callback function to be called when data is received.
100
+
101
+ Args:
102
+ push_callback (Callable): The callback function to be called when data is received.
103
+ This should be the websocket send function.
104
+
105
+ Returns:
106
+ None
91
107
"""
92
108
self ._push_callback_org = push_callback
93
109
94
110
def start (self ) -> bool :
95
111
"""
96
- starts the microphone stream
112
+ starts - starts the microphone stream
113
+
114
+ Returns:
115
+ bool: True if the stream was started, False otherwise
97
116
"""
98
117
self ._logger .debug ("Microphone.start ENTER" )
99
118
100
119
self ._logger .info ("format: %s" , self ._format )
101
120
self ._logger .info ("channels: %d" , self ._channels )
102
121
self ._logger .info ("rate: %d" , self ._rate )
103
122
self ._logger .info ("chunk: %d" , self ._chunk )
104
- self ._logger .info ("input_device_id: %d" , self ._input_device_index )
123
+ # self._logger.info("input_device_id: %d", self._input_device_index)
105
124
106
125
if self ._push_callback_org is None :
107
- self ._logger .error ("start() failed. No callback set." )
126
+ self ._logger .error ("start failed. No callback set." )
108
127
self ._logger .debug ("Microphone.start LEAVE" )
109
128
return False
110
129
@@ -114,9 +133,13 @@ def start(self) -> bool:
114
133
self ._asyncio_thread = threading .Thread (target = self ._start_asyncio_loop )
115
134
self ._asyncio_thread .start ()
116
135
117
- self ._push_callback = lambda data : asyncio .run_coroutine_threadsafe (
118
- self ._push_callback_org (data ), self ._asyncio_loop
119
- ).result ()
136
+ self ._push_callback = lambda data : (
137
+ asyncio .run_coroutine_threadsafe (
138
+ self ._push_callback_org (data ), self ._asyncio_loop
139
+ ).result ()
140
+ if self ._push_callback_org
141
+ else None
142
+ )
120
143
else :
121
144
self ._logger .verbose ("regular threaded callback" )
122
145
self ._push_callback = self ._push_callback_org
@@ -134,7 +157,7 @@ def start(self) -> bool:
134
157
self ._exit .clear ()
135
158
self ._stream .start_stream ()
136
159
137
- self ._logger .notice ("start() succeeded" )
160
+ self ._logger .notice ("start succeeded" )
138
161
self ._logger .debug ("Microphone.start LEAVE" )
139
162
return True
140
163
@@ -176,41 +199,50 @@ def _callback(
176
199
177
200
def mute (self ) -> bool :
178
201
"""
179
- Mutes the microphone stream
202
+ mute - mutes the microphone stream
203
+
204
+ Returns:
205
+ bool: True if the stream was muted, False otherwise
180
206
"""
181
207
self ._logger .debug ("Microphone.mute ENTER" )
182
208
183
209
if self ._stream is None :
184
- self ._logger .error ("mute() failed. Library not initialized." )
210
+ self ._logger .error ("mute failed. Library not initialized." )
185
211
self ._logger .debug ("Microphone.mute LEAVE" )
186
212
return False
187
213
188
214
self ._is_muted = True
189
215
190
- self ._logger .notice ("mute() succeeded" )
216
+ self ._logger .notice ("mute succeeded" )
191
217
self ._logger .debug ("Microphone.mute LEAVE" )
192
218
return True
193
219
194
220
def unmute (self ) -> bool :
195
221
"""
196
- Unmutes the microphone stream
222
+ unmute - unmutes the microphone stream
223
+
224
+ Returns:
225
+ bool: True if the stream was unmuted, False otherwise
197
226
"""
198
227
self ._logger .debug ("Microphone.unmute ENTER" )
199
228
200
229
if self ._stream is None :
201
- self ._logger .error ("unmute() failed. Library not initialized." )
230
+ self ._logger .error ("unmute failed. Library not initialized." )
202
231
self ._logger .debug ("Microphone.unmute LEAVE" )
203
232
return False
204
233
205
234
self ._is_muted = False
206
235
207
- self ._logger .notice ("unmute() succeeded" )
236
+ self ._logger .notice ("unmute succeeded" )
208
237
self ._logger .debug ("Microphone.unmute LEAVE" )
209
238
return True
210
239
211
240
def finish (self ) -> bool :
212
241
"""
213
- Stops the microphone stream
242
+ finish - stops the microphone stream
243
+
244
+ Returns:
245
+ bool: True if the stream was stopped, False otherwise
214
246
"""
215
247
self ._logger .debug ("Microphone.finish ENTER" )
216
248
@@ -219,19 +251,24 @@ def finish(self) -> bool:
219
251
220
252
# Stop the stream.
221
253
if self ._stream is not None :
254
+ self ._logger .notice ("stopping stream..." )
222
255
self ._stream .stop_stream ()
223
256
self ._stream .close ()
224
257
self ._stream = None # type: ignore
258
+ self ._logger .notice ("stream stopped" )
225
259
226
260
# clean up the thread
227
261
if (
228
- inspect .iscoroutinefunction (self ._push_callback_org )
229
- and self ._asyncio_thread is not None
262
+ # inspect.iscoroutinefunction(self._push_callback_org)
263
+ # and
264
+ self ._asyncio_thread
265
+ is not None
230
266
):
267
+ self ._logger .notice ("stopping asyncio loop..." )
231
268
self ._asyncio_loop .call_soon_threadsafe (self ._asyncio_loop .stop )
232
269
self ._asyncio_thread .join ()
233
270
self ._asyncio_thread = None # type: ignore
234
- self ._logger .notice ("stream/recv thread joined" )
271
+ self ._logger .notice ("_asyncio_thread joined" )
235
272
236
273
self ._logger .notice ("finish succeeded" )
237
274
self ._logger .debug ("Microphone.finish LEAVE" )
0 commit comments