Задержка звука с Python

 


Задержка звука с Python

Исходный код ноутбука

Задержка является фундаментальным звуковым эффектом. Идея воспроизведения звука и его повторения через некоторое время проста, но он широко используется в производстве музыки в качестве отдельного эффекта и в качестве основы реверберации , хора и отбортовки . В этой статье я расскажу о версии задержки, чтобы проверить поддержку звука в стандартной библиотеке и лучше понять, как работает эффект.

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

В 1]:

из IPython.display импортируйте аудио , дисплей , HTML 

s3 = 'https://s3.amazonaws.com/audio-experiment/examples/'


#display аудио объект и текстовую ссылку для браузеров , не совместимых с <аудио> 

Защиту display_link_audio ( файл ): 

    возвращение дисплей ( HTML ( '<a href=' + s3 + файл +'> ' + файл + '' </a> ) , 

           Аудио ( url = s3 + file , embed = False ))


печать ( "Input:"

display_link_audio ( 'Trumpet.wav' )  

печать ( " \ п Выходы с задержкой:"

display_link_audio ( 'Trumpet_delay_700ms.wav'

display_link_audio ( 'Trumpet_delay_1ms_0.75f_1n.wav'

display_link_audio ( «Trumpet_delay_250ms_0.7f_10n .wav ' )

 

Входные данные:


Trumpet.wav

Выходы с задержкой:


Trumpet_delay_700ms.wav

Trumpet_delay_1ms_0.75f_1n.wav

Trumpet_delay_250ms_0.7f_10n.wav

(Если вы просто хотите услышать задержанный звук, перейдите прямо к разделу « Примеры »).

Получить аудио 

Модуль Wave обрабатывает ввод и вывод файлов Wav. Этот несжатый формат состоит из множества сэмплов, каждый из которых является измерением амплитуды звуковой волны. Образцы данных представлены в виде байтового объекта, что делает этот стандартный библиотечный модуль менее полезным, чем некоторые другие модули, которые возвращают пустой массив (например, audiolab ).

Для работы с данными в байтовом объекте нам нужно знать количество байтов на выборку и частоту выборки . Для простоты эти примеры поддерживают только монофонический звук, поэтому параметр nchannels должен быть равен 1.

В [2]:

волна импорта


def input_wave ( filename , frames = 10000000 ): # 10000000 - произвольно большое количество кадров 

    с волной . open ( имя файла , 'rb' ) как wave_file : 

        params = wave_file . getparams () 

        audio = wave_file . читать кадры ( кадры ),  

        если params . nchannels ! = 1

            повысить исключение («Входной звук должен быть моно для этих примеров»

    return params , audio


#output в файл, чтобы мы могли использовать аудио-виджет 

ipython notebook def output_wave ( audio , params , stem , суффикс ): # 

    динамически форматировать имя файла, передавая данные 

    filename = stem . заменить ( '.wav' , '_ {}. wav' . format ( суффикс )) 

    на wave . открыть ( имя файла , 'wb' ) как wave_file : 

        wave_file . setparams ( params )

        wave_file . записывать кадры ( аудио )

 

Следующие короткие монофонические аудиоклипы будут использованы для демонстрации эффекта задержки. Один - это соло на трубе, а другой - звук удара.

В [3]:

trumpet_params , trumpet_bytes = input_wave ( 'wavs / Trumpet.wav'

punch_params , punch_bytes = input_wave ( 'wavs / Punch.wav' )


печать ( "байт в образце: {}" . формата ( trumpet_params . sampwidth ), 

      "Образцы в секунду: {}" . Формат ( trumpet_params . частота кадров ), 

      "Первые 10 байт:" , trumpet_bytes [: 10 ], сентябрь = ' \ n '

display_link_audio ( ' Trumpet.wav ' )


печать ( "байт в образце: {}" . формата ( punch_params . sampwidth ), 

      "Образцы в секунду: {}" . Формат ( punch_params . частота кадров ), 

      "Первые 10 байт:" , punch_bytes [: 10 ], сентябрь = ' \ n '

display_link_audio ( ' Punch.wav ' )

 

Байт на выборку: 3

Образцы в секунду: 44100

Первые 10 байтов:

Ь '\ x00 \ x00 \ x00 \ x13 \ x00 \ x00 \ x1f \ x00 \ X005'


Trumpet.wav

Байт на выборку: 2

Образцы в секунду: 44100

Первые 10 байтов:

Ь '\ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ XFE \ XFF'


Punch.wav

Реализуйте функцию задержки 

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

В [4]:

из аудиооп импорта добавить


def delay ( audio_bytes , params , offset_ms ): 

    "" "версия 1: задержка после миллисекунд" offset_ms "" "" # 

    вычислить число байтов, соответствующее смещению в миллисекундах 

    offset = params . sampwidth * offset_ms * int ( params . framerate / 1000 ) # 

    создать некоторое молчание 

    начало = b ' \ 0 ' * смещение # 

    удалить пробел от конца 

    end = audio_bytes [:- смещение ] 

    return add ( audio_bytes , начало + конец , параметры . ширина выборки )

 

В [5]:

# 1-секундная задержка 

output_wave ( задержка ( trumpet_bytes , trumpet_params , 1000 ), 

            trumpet_params , 'wavs / Trumpet.wav' , 'delay_1000ms'

# 250 мс задержка 

output_wave ( задержка ( punch_bytes , punch_params , 250 ), 

            punch_params , 'wavs / Punch.wav ' , ' delay_250ms ' )


display_link_audio ( 'Trumpet_delay_1000ms.wav'

display_link_audio ( 'Punch_delay_250ms.wav' )

 

Trumpet_delay_1000ms.wav

Punch_delay_250ms.wav

Изменить громкость задержанного звука 

Чтобы сделать этот звук более похожим на реалистичное эхо, мы можем изменить громкость задержанного звука, умножив его с помощью audioop.mul. Обратите внимание, что умножение каждого сэмпла на половину - это не то же самое, что уменьшение воспринимаемой громкости на половину.

В [6]:

от audioop импортировать MUL 

#new функции задержки с фактором 

четкости задержкой ( audio_bytes , Params , offset_ms , фактор = 1 ): 

    «» «версия 2: задержка после миллисекунд„“offset_ms усиливаемыха„фактор“» «» 

    #calculate количества байт что соответствует смещению в миллисекундах 

    offset = params . sampwidth * offset_ms * int ( params . framerate / 1000 ) # 

    создать некоторое 

    начало тишины = б ' \ 0 ' * смещение 

    #remove пространства от конца 

    конца = audio_bytes [: - смещение ] 

    #multiply фактора 

    multiplied_end = мул ( audio_bytes [: - офсетный ], Params . sampwidth , фактор ) 

    возвращение добавить ( audio_bytes , начиная + multiplied_end , params . samplewidth )

 

В [7]:

# 1-секундная задержка с коэффициентом .5 

output_wave ( задержка ( trumpet_bytes , trumpet_params , offset_ms = 1000 , factor = 0.5 ), 

            trumpet_params , 'wavs / Trumpet.wav' , 'delay_1000ms_0.5f'

# 500 мс задержка с коэффициентом .25 

output_wave ( задержка ( punch_bytes , punch_params , offset_ms = 250 , коэффициент = 0,25 ), 

            punch_params , 'wavs / Punch.wav' ,'delay_250ms_0.25f' )


display_link_audio ( 'Trumpet_delay_1000ms_0.5f.wav'

display_link_audio ( 'Punch_delay_250ms_0.25f.wav' )

 

Trumpet_delay_1000ms_0.5f.wav

Punch_delay_250ms_0.25f.wav

Несколько задержек 

Еще одно усовершенствование функции задержки - возможность многократного повторения. Каждый раз, когда происходит повторение, громкость будет постепенно увеличиваться или уменьшаться в зависимости от коэффициента.

В [8]:

из предупреждений импорт предупреждать


Защиту задержка ( audio_bytes , PARAMS , offset_ms , коэффициент = 1 , Num = 1 ): 

    "" "версия 3: 'пит' задержка после миллисекунд 'offset_ms' усиливаемыха 'фактором'" "" , 

    если коэффициент > = 1

        предупредить ( " Эти настройки могут привести к очень громкому звуковому файлу.

             Пожалуйста, соблюдайте осторожность при прослушивании " ) # 

    рассчитайте количество байтов, которое соответствует смещению в миллисекундах 

    offset = params .ширина выборки * смещение_ms *int ( params . framerate / 1000 ) # 

    добавить дополнительный пробел в конце для задержек 

    delayed_bytes = audio_bytes 

    для i в диапазоне ( num ): 

        # создать некоторое молчание, 

        начиная с = b ' \ 0 ' * offset * ( i + 1

        #remove пробел от конца 

        end = audio_bytes [: - смещение * ( i + 1 )]

        # умножить на множитель 

        multiplied_end = mul ( end , params . samplewidth , factor ** ( i + 1 )) 

        delayed_bytes = add ( delayed_bytes , начало + multiplied_end , params . sampwidth ) 

    вернуть delayed_bytes

 

В [9]:

# 1-секундная задержка с коэффициентом .5, 3 повторения 

output_wave ( задержка ( trumpet_bytes , trumpet_params , offset_ms = 1000 , factor = 0.5 , num = 3 ), 

            trumpet_params , 'wavs / Trumpet.wav' , 'delay_1000ms_0.5f_3n'

# Задержка 250 мс с коэффициентом .7, 4 повторения 

output_wave ( delay ( punch_bytes , punch_params , offset_ms = 250 , factor = 0.7 , num = 4 ), 

            punch_params , 'wavs / Punch.wav' , 'delay_250ms_0.7f_4n' )


display_link_audio ( 'Trumpet_delay_1000ms_0.5f_3n.wav'

display_link_audio ( 'Punch_delay_250ms_0.7f_4n.wav' )

 

Trumpet_delay_1000ms_0.5f_3n.wav

Punch_delay_250ms_0.7f_4n.wav

Оставьте место в конце 

Вышеуказанные мульти-задержки выводят звук той же длины, что и оригинал, поэтому попытка добавить слишком много повторов приведет к исключению. Чтобы дать больше времени, чтобы услышать эффекты, давайте увеличим длину, чтобы каждый повтор заканчивался.

В [10]:

Защита задержка ( audio_bytes , PARAMS , offset_ms , коэффициент = 1 , Num = 1 ): 

    "" "версия 4: 'NUM' задержка после миллисекунд 'offset_ms' усиливаемыха 'фактора' 

    с дополнительным пространством" "" , 

    если коэффициент > = 1

        warn ( «Эти настройки могут привести к очень громкому звуковому файлу.

              Пожалуйста, соблюдайте осторожность при прослушивании» ) # 

    рассчитайте количество байтов, которое соответствует смещению в миллисекундах 

    offset = params .sampwidth* offset_ms * int ( params . framerate / 1000 ) # 

    добавить дополнительный пробел в конце для задержек 

    audio_bytes = audio_bytes + b ' \ 0 ' * offset * ( num ) 

    # создать копию оригинала, чтобы применить задержки 

    delayed_bytes = audio_bytes 

    для i в диапазоне ( num ): 

        # создать некоторое молчание, 

        начало = b ' \ 0 ' * смещение* ( Я + 1

        #remove пространство от торцевого 

        конца = audio_bytes [: - смещение * ( я + 1 )] 

        #multiply множителя 

        multiplied_end = MUL ( конец , PARAMS . Sampwidth , фактор ** ( я + 1 )) 

        delayed_bytes = add ( delayed_bytes , начало + multiplied_end , параметры .samplewidth ) 

    return delayed_bytes

 

В [11]:

# 3-секундная задержка с коэффициентом .5, 3 повторения 

output_wave ( задержка ( trumpet_bytes , trumpet_params , offset_ms = 3000 , factor = 0.5 , num = 3 ), 

            trumpet_params , 'wavs / Trumpet.wav' , 'delay_3000ms_0.5f_3n'

# Задержка 500 мс с коэффициентом .7, 6 повторений 

output_wave ( delay ( punch_bytes , punch_params , offset_ms = 500 , factor = 0.7 , num = 6 ), 

            punch_params , 'wavs / Punch.wav' , 'delay_500ms_0.7f_6n' )


display_link_audio ( 'Trumpet_delay_3000ms_0.5f_3n.wav'

display_link_audio ( 'Punch_delay_500ms_0.7f_6n.wav' )

 

Trumpet_delay_3000ms_0.5f_3n.wav

Punch_delay_500ms_0.7f_6n.wav

Примеры 

Лучший способ понять, как различные параметры влияют на окончательный звук, - это попробовать множество примеров. delay_to_file - вспомогательная функция для ускорения этого процесса.

В [12]:

Функция #helper для проверки множества задержек 

def delay_to_file ( audio_bytes , params , offset_ms , file_stem , factor = 1 , num = 1 ): 

    echoed_bytes = задержка ( audio_bytes , params , offset_ms , factor , num ) 

    output_wave ( echoed_bytes , params , file_stem) , 

                'delay _ {} ms _ {} f _ {} n' . format (offset_ms , factor , num ))

 

Задержка в 1-2 секунды слишком велика, чтобы звучать как естественное эхо, поэтому это можно использовать для музыкального эффекта.

В [13]:

delay_to_file ( trumpet_bytes , trumpet_params , offset_ms = 1000 , file_stem = 'WAVs / Trumpet.wav'

              коэффициент =. 5

delay_to_file ( trumpet_bytes , trumpet_params , offset_ms = 2000 , file_stem = 'WAVs / Trumpet.wav'

              коэффициент =. 9 , число = 10 )


display_link_audio ( 'Trumpet_delay_1000ms_0.5f_1n.wav'

display_link_audio ( 'Trumpet_delay_2000ms_0.9f_10n.wav' )

 

Trumpet_delay_1000ms_0.5f_1n.wav

Trumpet_delay_2000ms_0.9f_10n.wav

Добавление 250-400 мс задержки с достаточно низким коэффициентом затухания начинает создавать впечатление естественного эха, который может возникнуть в большем физическом пространстве.

В [14]:

delay_to_file ( trumpet_bytes , trumpet_params , offset_ms = 400 , file_stem = 'WAVs / Trumpet.wav'

              коэффициент =. 5 , Num = 5

delay_to_file ( trumpet_bytes , trumpet_params , offset_ms = 400 , file_stem = 'WAVs / Trumpet.wav'

              фактор =. 25

delay_to_file ( punch_bytes , punch_params , offset_ms= 400 , file_stem = 'wavs / Punch.wav'

              factor =. 5 , num = 10

delay_to_file ( trumpet_bytes , trumpet_params , offset_ms = 250 , file_stem = 'wavs / Trumpet.wav'

              factor =. 5 , num = 4

delay_to_file ( trumpet_bytes , trumpet_params , offset_ms = 250 , file_stem ='wavs / Trumpet.wav'

              фактор =. 25 , num = 3

delay_to_file ( punch_bytes , punch_params , offset_ms = 250 , file_stem = 'wavs / Punch.wav'

              factor =. 5 , num = 10 )


display_link_audio ( 'Trumpet_delay_400ms_0.5f_5n.wav'

display_link_audio ( 'Trumpet_delay_400ms_0.25f_1n.wav'

display_link_audio ( 'Punch_delay_400ms_0.5f_10n.wav'

display_link_audio ( 'Trumpet_delay_250ms_0.5f_4n.wav'

display_link_audio ( 'Trumpet_delay_250ms_0.25f_3n.wav'

display_link_audio ( 'Punch_delay_250ms_0.5f_10n.wav' )

 

Trumpet_delay_400ms_0.5f_5n.wav

Trumpet_delay_400ms_0.25f_1n.wav

Punch_delay_400ms_0.5f_10n.wav

Trumpet_delay_250ms_0.5f_4n.wav

Trumpet_delay_250ms_0.25f_3n.wav

Punch_delay_250ms_0.5f_10n.wav

По мере того, как задержки становятся короче, около 125 мс или меньше, эффект начинает восприниматься как отдельный звук, а не как отдельное эхо. Это создает эффект гребенчатого фильтра, поскольку определенные частоты становятся громче или мягче из-за помех. На образце трубы задержка в 1-5 мс звучит очень похоже на трубу, проигрываемую беззвучно , особенно с большим количеством задержек.

В [15]:

delay_to_file ( trumpet_bytes , trumpet_params , offset_ms = 125 , file_stem = 'WAVs / Trumpet.wav'

              коэффициент =. 5

delay_to_file ( trumpet_bytes , trumpet_params , offset_ms = 75 , file_stem = 'WAVs / Trumpet.wav'

              коэффициент =. 5

delay_to_file ( trumpet_bytes , trumpet_params , offset_ms = 20 , file_stem = 'wavs / Trumpet.wav'

              factor =. 75

delay_to_file ( trumpet_bytes , trumpet_params , offset_ms = 5 , file_stem = 'WAVs / Trumpet.wav'

              коэффициент =. 75

delay_to_file ( trumpet_bytes , trumpet_params , offset_ms = 1 , file_stem = 'WAVs / Trumpet.wav'

              коэффициент =. 75 , число = 20)


display_link_audio ( 'Trumpet_delay_125ms_0.5f_1n.wav'

display_link_audio ( 'Trumpet_delay_75ms_0.5f_1n.wav'

display_link_audio ( 'Trumpet_delay_20ms_0.75f_1n.wav'

display_link_audio ( 'Trumpet_delay_5ms_0.75f_1n.wav'

display_link_audio ( 'Trumpet_delay_1ms_0.75f_20n.wav' )     

 

Trumpet_delay_125ms_0.5f_1n.wav

Trumpet_delay_75ms_0.5f_1n.wav

Trumpet_delay_20ms_0.75f_1n.wav

Trumpet_delay_5ms_0.75f_1n.wav

Trumpet_delay_1ms_0.75f_20n.wav

Действительно интересные звуки могут быть произведены с задержкой до 125 мс при использовании множества повторов. Труба начинает звучать как совершенно другой инструмент.

Поскольку звук удара очень короткий, мы можем использовать задержку для создания тона. Например, применение задержки 2 мс много раз практически без затухания приведет к затуханию ноты в 500 Гц, поскольку мы эффективно воспроизводим один и тот же звук удара с частотой 500 раз в секунду.

В [16]:

delay_to_file ( trumpet_bytes , trumpet_params , offset_ms = 50 , file_stem = 'WAVs / Trumpet.wav'

              коэффициент =. 76 , Num = 10

delay_to_file ( trumpet_bytes , trumpet_params , offset_ms = 125 , file_stem = 'WAVs / Trumpet.wav'

              фактор =. 7 , num = 10

delay_to_file ( trumpet_bytes , trumpet_params , offset_ms = 20 , file_stem = 'wavs / Trumpet.wav'

              factor =. 97 , num = 300

delay_to_file ( punch_bytes , punch_params , offset_ms = 2 , file_stem = 'wavs / Punch.wav'

              коэффициент =. 996 , num = 3000 )


display_link_audio ( 'Trumpet_delay_50ms_0.76f_10n.wav'

display_link_audio ( 'Trumpet_delay_125ms_0.7f_10n.wav'

display_link_audio ( 'Trumpet_delay_20ms_0.97f_300n.wav'

display_link_audio ( 'Punch_delay_2ms_0.996f_3000n.wav' )

 

Trumpet_delay_50ms_0.76f_10n.wav

Trumpet_delay_125ms_0.7f_10n.wav

Trumpet_delay_20ms_0.97f_300n.wav

Punch_delay_2ms_0.996f_3000n.wav

Следующие шаги 

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

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

Я также хотел бы использовать эту функцию задержки для создания эффектов более высокого уровня. Изменение величины задержки, применяемой к аудиоклипу вместо использования фиксированного смещения, создает эффект отбортовки . И объединение нескольких задержек с различными параметрами произведет реверберацию .

Я не удовлетворен тем, как параметр «factor» используется в функции задержки, поэтому было бы здорово смоделировать затухание способом, более похожим на естественный звук.

Другая интересная проблема будет заключаться в применении задержки к живому сигналу, а не в качестве эффекта постобработки.

И, конечно, было бы неплохо попробовать эту функцию с некоторыми новыми аудиоклипами, так как мне очень надоело это соло на трубе.

Спасибо за чтение!


Комментарии

Популярные сообщения из этого блога

Распознавание диктора