@@ -199,17 +199,19 @@ def get_audio_properties(input_path: str) -> Tuple[int, int]:
199
199
container .close ()
200
200
return channels , rate
201
201
202
+
202
203
class AudioIoProcess (Process ):
203
- def __init__ (self ,
204
- input_device ,
205
- output_device ,
206
- input_audio_block_size : int ,
207
- sample_rate : int ,
208
- channel_num : int = 2 ,
209
- is_device_combined : bool = True ,
210
- is_input_wasapi_exclusive : bool = False ,
211
- is_output_wasapi_exclusive : bool = False
212
- ):
204
+ def __init__ (
205
+ self ,
206
+ input_device ,
207
+ output_device ,
208
+ input_audio_block_size : int ,
209
+ sample_rate : int ,
210
+ channel_num : int = 2 ,
211
+ is_device_combined : bool = True ,
212
+ is_input_wasapi_exclusive : bool = False ,
213
+ is_output_wasapi_exclusive : bool = False ,
214
+ ):
213
215
super ().__init__ ()
214
216
self .in_dev = input_device
215
217
self .out_dev = output_device
@@ -222,18 +224,19 @@ def __init__(self,
222
224
self .is_output_wasapi_exclusive : bool = is_output_wasapi_exclusive
223
225
224
226
self .__rec_ptr = 0
225
- self .in_ptr = Value ('i' , 0 ) # 当收满一个block时由本进程设置
226
- self .out_ptr = Value ('i' , 0 ) # 由主进程设置,指示下一次预期写入位置
227
- self .play_ptr = Value ('i' , 0 ) # 由本进程设置,指示当前音频已经播放到哪里
227
+ self .in_ptr = Value ("i" , 0 ) # 当收满一个block时由本进程设置
228
+ self .out_ptr = Value ("i" , 0 ) # 由主进程设置,指示下一次预期写入位置
229
+ self .play_ptr = Value ("i" , 0 ) # 由本进程设置,指示当前音频已经播放到哪里
228
230
self .in_evt = Event () # 当收满一个block时由本进程设置
229
231
self .stop_evt = Event () # 当主进程停止音频活动时由主进程设置
230
232
231
- self .latency = Value ('d' , 114514.1919810 )
233
+ self .latency = Value ("d" , 114514.1919810 )
232
234
233
235
self .buf_shape : tuple = (self .buf_size , self .channels )
234
236
self .buf_dtype : np .dtype = np .float32
235
237
self .buf_nbytes : int = int (
236
- np .prod (self .buf_shape ) * np .dtype (self .buf_dtype ).itemsize )
238
+ np .prod (self .buf_shape ) * np .dtype (self .buf_dtype ).itemsize
239
+ )
237
240
238
241
self .in_mem = SharedMemory (create = True , size = self .buf_nbytes )
239
242
self .out_mem = SharedMemory (create = True , size = self .buf_nbytes )
@@ -256,11 +259,7 @@ def get_np_dtype(self) -> np.dtype:
256
259
return self .buf_dtype
257
260
258
261
def get_ptrs_and_events (self ):
259
- return self .in_ptr , \
260
- self .out_ptr ,\
261
- self .play_ptr ,\
262
- self .in_evt , \
263
- self .stop_evt \
262
+ return self .in_ptr , self .out_ptr , self .play_ptr , self .in_evt , self .stop_evt
264
263
265
264
def get_latency (self ) -> float :
266
265
return self .latency .value
@@ -272,12 +271,14 @@ def run(self):
272
271
273
272
in_mem = SharedMemory (name = self .in_mem_name )
274
273
self .in_buf = np .ndarray (
275
- self .buf_shape , dtype = self .buf_dtype , buffer = in_mem .buf , order = 'C' )
274
+ self .buf_shape , dtype = self .buf_dtype , buffer = in_mem .buf , order = "C"
275
+ )
276
276
self .in_buf .fill (0.0 )
277
277
278
278
out_mem = SharedMemory (name = self .out_mem_name )
279
279
self .out_buf = np .ndarray (
280
- self .buf_shape , dtype = self .buf_dtype , buffer = out_mem .buf , order = 'C' )
280
+ self .buf_shape , dtype = self .buf_dtype , buffer = out_mem .buf , order = "C"
281
+ )
281
282
self .out_buf .fill (0.0 )
282
283
283
284
exclusive_settings = sd .WasapiSettings (exclusive = True )
@@ -302,11 +303,11 @@ def input_callback(indata, frames, time_info, status):
302
303
# 收录输入数据
303
304
end_ptr = self .__rec_ptr + frames
304
305
if end_ptr <= self .buf_size : # 整块拷贝
305
- self .in_buf [self .__rec_ptr : end_ptr ] = indata
306
+ self .in_buf [self .__rec_ptr : end_ptr ] = indata
306
307
else : # 处理回绕
307
308
first = self .buf_size - self .__rec_ptr
308
309
second = end_ptr - self .buf_size
309
- self .in_buf [self .__rec_ptr :] = indata [:first ]
310
+ self .in_buf [self .__rec_ptr :] = indata [:first ]
310
311
self .in_buf [:second ] = indata [first :]
311
312
write_pos = self .__rec_ptr
312
313
self .__rec_ptr = end_ptr % self .buf_size
@@ -328,11 +329,14 @@ def combined_callback(indata, outdata, frames, time_info, status):
328
329
samplerate = self .sample_rate ,
329
330
channels = self .channels ,
330
331
dtype = self .buf_dtype ,
331
- latency = 'low' ,
332
- extra_settings = exclusive_settings if
333
- self .is_input_wasapi_exclusive and
334
- self .is_output_wasapi_exclusive else None ,
335
- callback = combined_callback
332
+ latency = "low" ,
333
+ extra_settings = (
334
+ exclusive_settings
335
+ if self .is_input_wasapi_exclusive
336
+ and self .is_output_wasapi_exclusive
337
+ else None
338
+ ),
339
+ callback = combined_callback ,
336
340
) as s :
337
341
self .latency .value = s .latency [- 1 ]
338
342
self .stop_evt .wait ()
@@ -342,16 +346,20 @@ def combined_callback(indata, outdata, frames, time_info, status):
342
346
samplerate = self .sample_rate ,
343
347
channels = self .channels ,
344
348
dtype = self .buf_dtype ,
345
- latency = 'low' ,
346
- extra_settings = exclusive_settings if self .is_input_wasapi_exclusive else None ,
347
- callback = input_callback
349
+ latency = "low" ,
350
+ extra_settings = (
351
+ exclusive_settings if self .is_input_wasapi_exclusive else None
352
+ ),
353
+ callback = input_callback ,
348
354
) as si , sd .OutputStream (
349
355
samplerate = self .sample_rate ,
350
356
channels = self .channels ,
351
357
dtype = self .buf_dtype ,
352
- latency = 'low' ,
353
- extra_settings = exclusive_settings if self .is_output_wasapi_exclusive else None ,
354
- callback = output_callback
358
+ latency = "low" ,
359
+ extra_settings = (
360
+ exclusive_settings if self .is_output_wasapi_exclusive else None
361
+ ),
362
+ callback = output_callback ,
355
363
) as so :
356
364
self .latency .value = si .latency [- 1 ] + so .latency [- 1 ]
357
365
self .stop_evt .wait ()
0 commit comments