Удалите вывод системного звука при записи с микрофоном в Python

На самом деле я записываю каждый звук с помощью микрофона, и я хотел бы отфильтровать вход, чтобы удалить вывод системного звука, чтобы четко понимать голос пользователя, например, при воспроизведении музыки (например, как это делает 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()

person Tony Stark    schedule 22.07.2018    source источник


Ответы (1)


Полностью удалить вывод звука из записи голоса (обычно без наилучших условий, например, с помощью настольного микрофона в шумной среде) очень сложно сделать хорошо, и существует множество методов фильтрации, хотя на ум приходит самый простой из них.

Удаление системного вывода прямого звука

Чтобы получить вывод аудиосистемы, вам понадобится своего рода loopback устройство, вероятно, использующее PulseAudio. Таким образом, вы можете открыть 2 входных аудиопотока и сможете одновременно получать данные вашего микрофона и выходные данные системы (это будет работать с блокирующим подходом, как у вас сейчас, но я был бы осторожен, если вы переключитесь на обратные вызовы) .

Тогда самый простой способ — вычесть все значения в аудиоблоке аудиовыхода системы из аудиоблока, принимаемого микрофоном. Предполагая, что реальной проблемы с задержкой нет, это удалит весь прямой звук, исходящий от устройства, из записи микрофона.

Псевдокод:

output = microphone_audioBlock - systemOutput_audioBlock 

Вам нужно будет подумать о нескольких вещах:

  • Вам нужно будет проверить, используются ли наушники, чтобы звук не вычитался.
  • Это не отменит весь косвенный звук (т.е. реверберацию/отражения, генерируемые в комнате).

Этот метод прост, но, как я уже говорил, он не отменит непрямой звук. Существует много методов подавления непрямого звука, но все они, как правило, являются исследовательскими концепциями.

Уменьшение фонового шума

Помимо этого вы, вероятно, захотите уменьшить фоновый шум; В терминах DSP это называется подавлением шума. .

Поскольку у вас будет доступ только к одному микрофону и не будет большого контроля над позиционированием (скорее всего), нет прямого способа реализовать это без какой-либо реализации алгоритма DSP. Ниже я прикрепил несколько мест, где вы можете прочитать о методах активного шумоподавления:

person WoodyDev    schedule 23.07.2018