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