mirror of
https://github.com/chidiwilliams/buzz.git
synced 2026-03-15 07:05:48 +01:00
151 lines
4.3 KiB
Python
151 lines
4.3 KiB
Python
import os
|
|
import time
|
|
from threading import Thread
|
|
from typing import Callable, Any
|
|
from unittest.mock import MagicMock
|
|
|
|
import numpy as np
|
|
import sounddevice
|
|
|
|
from buzz import whisper_audio
|
|
|
|
mock_query_devices = [
|
|
{
|
|
"name": "Background Music",
|
|
"index": 0,
|
|
"hostapi": 0,
|
|
"max_input_channels": 2,
|
|
"max_output_channels": 2,
|
|
"default_low_input_latency": 0.01,
|
|
"default_low_output_latency": 0.008,
|
|
"default_high_input_latency": 0.1,
|
|
"default_high_output_latency": 0.064,
|
|
"default_samplerate": 8000.0,
|
|
},
|
|
{
|
|
"name": "Background Music (UI Sounds)",
|
|
"index": 1,
|
|
"hostapi": 0,
|
|
"max_input_channels": 2,
|
|
"max_output_channels": 2,
|
|
"default_low_input_latency": 0.01,
|
|
"default_low_output_latency": 0.008,
|
|
"default_high_input_latency": 0.1,
|
|
"default_high_output_latency": 0.064,
|
|
"default_samplerate": 8000.0,
|
|
},
|
|
{
|
|
"name": "BlackHole 2ch",
|
|
"index": 2,
|
|
"hostapi": 0,
|
|
"max_input_channels": 2,
|
|
"max_output_channels": 2,
|
|
"default_low_input_latency": 0.01,
|
|
"default_low_output_latency": 0.0013333333333333333,
|
|
"default_high_input_latency": 0.1,
|
|
"default_high_output_latency": 0.010666666666666666,
|
|
"default_samplerate": 48000.0,
|
|
},
|
|
{
|
|
"name": "MacBook Pro Microphone",
|
|
"index": 3,
|
|
"hostapi": 0,
|
|
"max_input_channels": 1,
|
|
"max_output_channels": 0,
|
|
"default_low_input_latency": 0.034520833333333334,
|
|
"default_low_output_latency": 0.01,
|
|
"default_high_input_latency": 0.043854166666666666,
|
|
"default_high_output_latency": 0.1,
|
|
"default_samplerate": 48000.0,
|
|
},
|
|
{
|
|
"name": "MacBook Pro Speakers",
|
|
"index": 4,
|
|
"hostapi": 0,
|
|
"max_input_channels": 0,
|
|
"max_output_channels": 2,
|
|
"default_low_input_latency": 0.01,
|
|
"default_low_output_latency": 0.0070416666666666666,
|
|
"default_high_input_latency": 0.1,
|
|
"default_high_output_latency": 0.016375,
|
|
"default_samplerate": 48000.0,
|
|
},
|
|
{
|
|
"name": "Null Audio Device",
|
|
"index": 5,
|
|
"hostapi": 0,
|
|
"max_input_channels": 2,
|
|
"max_output_channels": 2,
|
|
"default_low_input_latency": 0.01,
|
|
"default_low_output_latency": 0.0014512471655328798,
|
|
"default_high_input_latency": 0.1,
|
|
"default_high_output_latency": 0.011609977324263039,
|
|
"default_samplerate": 44100.0,
|
|
},
|
|
{
|
|
"name": "Multi-Output Device",
|
|
"index": 6,
|
|
"hostapi": 0,
|
|
"max_input_channels": 0,
|
|
"max_output_channels": 2,
|
|
"default_low_input_latency": 0.01,
|
|
"default_low_output_latency": 0.0033333333333333335,
|
|
"default_high_input_latency": 0.1,
|
|
"default_high_output_latency": 0.012666666666666666,
|
|
"default_samplerate": 48000.0,
|
|
},
|
|
]
|
|
|
|
|
|
class MockInputStream(MagicMock):
|
|
running = False
|
|
thread: Thread
|
|
|
|
def __init__(
|
|
self,
|
|
callback: Callable[[np.ndarray, int, Any, sounddevice.CallbackFlags], None],
|
|
*args,
|
|
**kwargs,
|
|
):
|
|
super().__init__(spec=sounddevice.InputStream)
|
|
self.thread = Thread(target=self.target)
|
|
self.callback = callback
|
|
|
|
def start(self):
|
|
self.thread.start()
|
|
|
|
def target(self):
|
|
sample_rate = whisper_audio.SAMPLE_RATE
|
|
file_path = os.path.join(
|
|
os.path.dirname(__file__), "../testdata/whisper-french.mp3"
|
|
)
|
|
audio = whisper_audio.load_audio(file_path, sr=sample_rate)
|
|
|
|
chunk_duration_secs = 1
|
|
|
|
self.running = True
|
|
seek = 0
|
|
num_samples_in_chunk = chunk_duration_secs * sample_rate
|
|
|
|
while self.running:
|
|
time.sleep(chunk_duration_secs)
|
|
chunk = audio[seek : seek + num_samples_in_chunk]
|
|
self.callback(chunk, 0, None, sounddevice.CallbackFlags())
|
|
seek += num_samples_in_chunk
|
|
|
|
# loop back around
|
|
if seek + num_samples_in_chunk > audio.size:
|
|
seek = 0
|
|
|
|
def stop(self):
|
|
self.running = False
|
|
self.thread.join()
|
|
|
|
def close(self):
|
|
pass
|
|
|
|
def __enter__(self):
|
|
self.start()
|
|
|
|
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
self.stop()
|