Задержка звука с 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_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'
Байт на выборку: 2
Образцы в секунду: 44100
Первые 10 байтов:
Ь '\ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ XFE \ XFF'
Реализуйте функцию задержки
Простейшая функция задержки создаст копию ввода, добавит некоторое молчание (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' )
Изменить громкость задержанного звука
Чтобы сделать этот звук более похожим на реалистичное эхо, мы можем изменить громкость задержанного звука, умножив его с помощью 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' )
Несколько задержек
Еще одно усовершенствование функции задержки - возможность многократного повторения. Каждый раз, когда происходит повторение, громкость будет постепенно увеличиваться или уменьшаться в зависимости от коэффициента.
В [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
Оставьте место в конце
Вышеуказанные мульти-задержки выводят звук той же длины, что и оригинал, поэтому попытка добавить слишком много повторов приведет к исключению. Чтобы дать больше времени, чтобы услышать эффекты, давайте увеличим длину, чтобы каждый повтор заканчивался.
В [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
Примеры
Лучший способ понять, как различные параметры влияют на окончательный звук, - это попробовать множество примеров. 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» используется в функции задержки, поэтому было бы здорово смоделировать затухание способом, более похожим на естественный звук.
Другая интересная проблема будет заключаться в применении задержки к живому сигналу, а не в качестве эффекта постобработки.
И, конечно, было бы неплохо попробовать эту функцию с некоторыми новыми аудиоклипами, так как мне очень надоело это соло на трубе.
Комментарии
Отправить комментарий