На самом деле я записываю каждый звук с помощью микрофона, и я хотел бы отфильтровать вход, чтобы удалить вывод системного звука, чтобы четко понимать голос пользователя, например, при воспроизведении музыки (например, как это делает Skype).
Я ищу модуль Python, который позволяет делать это в Ubuntu 16.04 или, по крайней мере, что-то, что записывает вывод системы.
Вот мой скрипт (я использую Pyaudio):
THRESHOLD = 1500
CHUNK_SIZE = 1024
FORMAT = pyaudio.paInt16
RATE = 44100
MAX_RECORDING_TIME = 7 # seconds
MAX_SILENCE_UNITS = 65
def is_silent(snd_data):
"Returns 'True' if below the 'silent' threshold"
return max(snd_data) < THRESHOLD
def normalize(snd_data):
"Average the volume out"
MAXIMUM = 16384
times = float(MAXIMUM)/max(abs(i) for i in snd_data)
r = array('h')
for i in snd_data:
r.append(int(i*times))
return r
def record():
"""
Record a word or words from the microphone and
return the data as an array of signed shorts.
Normalizes the audio.
the recording stops after 7 seconds or a sequence of 65 silent recording units
"""
p = pyaudio.PyAudio()
stream = p.open(format=FORMAT, channels=1, rate=RATE,
input=True, output=False,
frames_per_buffer=CHUNK_SIZE)
num_silent = 0
snd_started = False
r = array('h')
begin_time = 0
while 1:
# little endian, signed short
snd_data = array('h', stream.read(CHUNK_SIZE))
if byteorder == 'big':
snd_data.byteswap()
if (snd_started):
r.extend(snd_data)
silent = is_silent(snd_data)
if silent and snd_started: # we compute the number of silent units
num_silent += 1
elif not silent and not snd_started:
print("start recording !")
snd_started = True
begin_time = time.time() # we save the current time
if not silent:
num_silent = 0
now = int(time.time())
if snd_started and (now-begin_time>MAX_RECORDING_TIME or num_silent > MAX_SILENCE_UNITS):
break
print("recording finished !")
sample_width = p.get_sample_size(FORMAT)
stream.stop_stream()
stream.close()
p.terminate()
r = normalize(r)
return sample_width, r
def record_to_file(path):
"Records from the microphone and outputs the resulting data to 'path'"
sample_width, data = record()
data = pack('<' + ('h'*len(data)), *data)
wf = wave.open(path, 'wb')
wf.setnchannels(1)
wf.setsampwidth(sample_width)
wf.setframerate(RATE)
wf.writeframes(data)
wf.close()