Spaces:
Running
on
T4
Running
on
T4
File size: 9,660 Bytes
2777fde |
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 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
"""
Implementation of Audio Effects Chain Manipulation for the task 'Mixing Style Transfer'
"""
from glob import glob
import os
import sys
currentdir = os.path.dirname(os.path.realpath(__file__))
sys.path.append(currentdir)
sys.path.append(os.path.dirname(currentdir))
from common_audioeffects import *
from common_dataprocessing import create_dataset
# create augmentation effects chain according to targeted effects with their applying probability
def create_effects_augmentation_chain(effects, \
ir_dir_path=None, \
sample_rate=44100, \
shuffle=False, \
parallel=False, \
parallel_weight_factor=None):
'''
Args:
effects (list of tuples or string) : First tuple element is string denoting the target effects.
Second tuple element is probability of applying current effects.
ir_dir_path (string) : directory path that contains directories of impulse responses organized according to RT60
sample_rate (int) : using sampling rate
shuffle (boolean) : shuffle FXs inside current FX chain
parallel (boolean) : compute parallel FX computation (alpha * input + (1-alpha) * manipulated output)
parallel_weight_factor : the value of alpha for parallel FX computation. default=None : random value in between (0.0, 0.5)
'''
fx_list = []
apply_prob = []
for cur_fx in effects:
# store probability to apply current effects. default is to set as 100%
if isinstance(cur_fx, tuple):
apply_prob.append(cur_fx[1])
cur_fx = cur_fx[0]
else:
apply_prob.append(1)
# processors of each audio effects
if isinstance(cur_fx, AugmentationChain) or isinstance(cur_fx, Processor):
fx_list.append(cur_fx)
elif cur_fx.lower()=='gain':
fx_list.append(Gain())
elif 'eq' in cur_fx.lower():
fx_list.append(Equaliser(n_channels=2, sample_rate=sample_rate))
elif 'comp' in cur_fx.lower():
fx_list.append(Compressor(sample_rate=sample_rate))
elif 'expand' in cur_fx.lower():
fx_list.append(Expander(sample_rate=sample_rate))
elif 'pan' in cur_fx.lower():
fx_list.append(Panner())
elif 'image'in cur_fx.lower():
fx_list.append(MidSideImager())
elif 'algorithmic' in cur_fx.lower():
fx_list.append(AlgorithmicReverb(sample_rate=sample_rate))
elif 'reverb' in cur_fx.lower():
# apply algorithmic reverberation if ir_dir_path is not defined
if ir_dir_path==None:
fx_list.append(AlgorithmicReverb(sample_rate=sample_rate))
# apply convolution reverberation
else:
IR_paths = glob(f"{ir_dir_path}*/RT60_avg/[!0-]*")
IR_list = []
IR_dict = {}
for IR_path in IR_paths:
cur_rt = IR_path.split('/')[-1]
if cur_rt not in IR_dict:
IR_dict[cur_rt] = []
IR_dict[cur_rt].extend(create_dataset(path=IR_path, \
accepted_sampling_rates=[sample_rate], \
sources=['impulse_response'], \
mapped_sources={}, load_to_memory=True, debug=False)[0])
long_ir_list = []
for cur_rt in IR_dict:
cur_rt_len = int(cur_rt.split('-')[0])
if cur_rt_len < 3000:
IR_list.append(IR_dict[cur_rt])
else:
long_ir_list.extend(IR_dict[cur_rt])
IR_list.append(long_ir_list)
fx_list.append(ConvolutionalReverb(IR_list, sample_rate))
else:
raise ValueError(f"make sure the target effects are in the Augment FX chain : received fx called {cur_fx}")
aug_chain_in = []
for cur_i, cur_fx in enumerate(fx_list):
normalize = False if isinstance(cur_fx, AugmentationChain) or cur_fx.name=='Gain' else True
aug_chain_in.append((cur_fx, apply_prob[cur_i], normalize))
return AugmentationChain(fxs=aug_chain_in, shuffle=shuffle, parallel=parallel, parallel_weight_factor=parallel_weight_factor)
# create audio FX-chain according to input instrument
def create_inst_effects_augmentation_chain(inst, \
apply_prob_dict, \
ir_dir_path=None, \
algorithmic=False, \
sample_rate=44100):
'''
Args:
inst (string) : FXmanipulator for target instrument. Current version only distinguishes 'drums' for applying reverberation
apply_prob_dict (dictionary of (FX name, probability)) : applying proababilities for each FX
ir_dir_path (string) : directory path that contains directories of impulse responses organized according to RT60
algorithmic (boolean) : rather to use algorithmic reverberation (True) or convolution reverberation (False)
sample_rate (int) : using sampling rate
'''
reverb_type = 'algorithmic' if algorithmic else 'reverb'
eq_comp_rand = create_effects_augmentation_chain([('eq', apply_prob_dict['eq']), ('comp', apply_prob_dict['comp'])], \
ir_dir_path=ir_dir_path, \
sample_rate=sample_rate, \
shuffle=True)
pan_image_rand = create_effects_augmentation_chain([('pan', apply_prob_dict['pan']), ('imager', apply_prob_dict['imager'])], \
ir_dir_path=ir_dir_path, \
sample_rate=sample_rate, \
shuffle=True)
if inst=='drums':
# apply reverberation to low frequency with little probability
low_pass_eq_params = ParameterList()
low_pass_eq_params.add(Parameter('high_shelf_gain', -50.0, 'float', minimum=-50.0, maximum=-50.0))
low_pass_eq_params.add(Parameter('high_shelf_freq', 100.0, 'float', minimum=100.0, maximum=100.0))
low_pass_eq = Equaliser(n_channels=2, \
sample_rate=sample_rate, \
bands=['high_shelf'], \
parameters=low_pass_eq_params)
reverb_parallel_low = create_effects_augmentation_chain([low_pass_eq, (reverb_type, apply_prob_dict['reverb']*0.01)], \
ir_dir_path=ir_dir_path, \
sample_rate=sample_rate, \
parallel=True, \
parallel_weight_factor=0.8)
# high pass eq for drums reverberation
high_pass_eq_params = ParameterList()
high_pass_eq_params.add(Parameter('low_shelf_gain', -50.0, 'float', minimum=-50.0, maximum=-50.0))
high_pass_eq_params.add(Parameter('low_shelf_freq', 100.0, 'float', minimum=100.0, maximum=100.0))
high_pass_eq = Equaliser(n_channels=2, \
sample_rate=sample_rate, \
bands=['low_shelf'], \
parameters=high_pass_eq_params)
reverb_parallel_high = create_effects_augmentation_chain([high_pass_eq, (reverb_type, apply_prob_dict['reverb'])], \
ir_dir_path=ir_dir_path, \
sample_rate=sample_rate, \
parallel=True, \
parallel_weight_factor=0.6)
reverb_parallel = create_effects_augmentation_chain([reverb_parallel_low, reverb_parallel_high], \
ir_dir_path=ir_dir_path, \
sample_rate=sample_rate)
else:
reverb_parallel = create_effects_augmentation_chain([(reverb_type, apply_prob_dict['reverb'])], \
ir_dir_path=ir_dir_path, \
sample_rate=sample_rate, \
parallel=True)
# full effects chain
effects_chain = create_effects_augmentation_chain([eq_comp_rand, \
pan_image_rand, \
reverb_parallel, \
('gain', apply_prob_dict['gain'])], \
ir_dir_path=ir_dir_path, \
sample_rate=sample_rate)
return effects_chain
|