-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrecord.py
102 lines (82 loc) · 3.19 KB
/
record.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import queue
import sys
import time
import sounddevice as sd
import soundfile as sf
import numpy # Make sure NumPy is loaded before it is used in the callback
assert numpy # avoid "imported but unused" message (W0611)
import logging
logger = logging.getLogger(__name__)
from utils import prettyDict
def selectMicrophone():
"""
Prompts the user to select a microphone device by displaying a list of available devices and asking for the device number.
Returns:
int: The selected microphone device number.
"""
devices = sd.query_devices()
for device in devices:
print(prettyDict(device))
microphone = input('Enter the microphone device number: ')
return int(microphone)
class Recorder:
"""
A class for recording audio from a microphone.
Args:
device (int): The index of the audio device to use. Default is 1.
channels (int): The number of audio channels. Default is 2.
samplerate (int): The sample rate of the audio. Default is 44100.
Attributes:
q (Queue): A queue to store the recorded audio data.
device (int): The index of the audio device being used.
channels (int): The number of audio channels being recorded.
samplerate (int): The sample rate of the audio being recorded.
"""
def __init__(self, device=1, channels=2, samplerate=44100, DEBUG=False):
sd.default.device = device
logger.info(f'default microphone:{sd.default.device}')
if DEBUG:
print(f'default microphone:{sd.default.device}')
self.q = queue.Queue()
self.device = device
self.channels = channels
self.samplerate = samplerate
def __del__(self):
del self.q
def callback(self, indata, frames, time, status):
"""
This is called (from a separate thread) for each audio block.
Args:
indata (ndarray): The input audio data.
frames (int): The number of frames in the audio block.
time (CData): The time stamp of the audio block.
status (int): The status of the audio block.
Returns:
None
"""
if status:
print(status, file=sys.stderr)
self.q.put(indata.copy())
def record(self, filename='./output.wav'):
"""
Records audio from the microphone and saves it to a file.
Args:
filename (str): The path to the output file. Default is './output.wav'.
Returns:
None
"""
logger.info(f'Recording audio to {filename}')
try:
with sf.SoundFile(filename, mode='w', samplerate=44100,
channels=self.channels) as file:
with sd.InputStream(samplerate=self.samplerate, device=self.device,
channels=self.channels, callback=self.callback):
t = time.time()
while True:
file.write(self.q.get())
if time.time() - t > 10:
break
except KeyboardInterrupt:
pass
logger.info('Recording finished')
print('\nRecording finished')