listeningpy.set_preparation
Functions for preparing sets for listening tests.
1""" 2Functions for preparing sets for listening tests. 3""" 4 5from pandas import DataFrame, concat 6import logging 7from itertools import combinations 8import os 9# logging.basicConfig(level=logging.INFO) 10 11### GENERAL ### 12 13def filter_wavs(paths: list[str]) -> list[str]: 14 '''Filters files with '.wav' extension from a list of paths. 15 16 Parameters 17 ---------- 18 paths : list[str] 19 list of file paths 20 21 Returns 22 ------- 23 paths : list[str] 24 list of filtered file paths 25 ''' 26 paths = filter(lambda file: file.lower().endswith('.wav'), paths) 27 return list(paths) 28 29def read_folder( 30 folder, 31 parent=None, 32 filterwav=True 33 ) -> list[str]: 34 '''Reads files inside a specified folder and keeps '.wav' files 35 inside it. 36 37 Parameters 38 ---------- 39 folder : str 40 folder containing wav files 41 parent : str 42 path to project folder 43 filterwav : bool 44 True value filters out other than '.wav' files 45 46 Returns 47 ------- 48 audio_paths : list[str] 49 list containing paths to audio files inside a specified folder 50 ''' 51 if parent == None: 52 audio_folder = folder 53 else: 54 audio_folder = os.path.join(parent, folder) 55 audio_paths = os.scandir(audio_folder) 56 audio_paths = [ 57 os.path.join(audio_folder, p.name) for p in audio_paths if p.is_file() 58 ] 59 if filterwav: 60 audio_paths = filter_wavs(audio_paths) 61 logging.info(f"Read these files: {audio_paths}") 62 return audio_paths 63 64def sub_folders( 65 folder : str, 66 ) -> list[str]: 67 """Return a list of sub-folders within the specified folder. 68 69 Parameters 70 ---------- 71 folder : str 72 The name of the folder. 73 parent : str 74 The parent directory of the folder. 75 76 Returns 77 ------- 78 list[str] 79 A list of sub-folders within the specified folder. 80 """ 81 parent = os.path.split(folder)[0] 82 main_folder = os.path.join(parent, folder) 83 subs = os.scandir(main_folder) 84 subs = [ 85 os.path.join(parent, folder, p.name) 86 for p in subs if p.is_dir() 87 ] 88 return subs 89 90def randomization(df: DataFrame) -> DataFrame: 91 ''' 92 Shuffles rows in a provided DataFrame. In this context, it randomizes 93 sets for discrimination listening tests. 94 95 Parameters 96 ---------- 97 df : pandas.DataFrame 98 DataFrame containing sets for the listening test, one per row. 99 100 Returns 101 ------- 102 df : pandas.DataFrame 103 DataFrame with randomly shuffled rows. 104 ''' 105 return df.sample(frac=1).reset_index(drop=True) 106 107### COMBINATIONS PREPARATION ### 108 109def abx_combination( 110 folder: str, 111 parent: str=".", 112 constant_reference: bool=False 113 ) -> DataFrame: 114 '''Reads files in a specified folder and generates combinations for 115 ABX test. 116 117 Parameters 118 ---------- 119 folder : str 120 Folder containing wav files. 121 parent : str, optional 122 Path to the project folder. Default is the current directory. 123 constant_reference : bool, optional 124 Determines whether to generate combinations for standard ABX (False) or CR-ABX (True). 125 For CR-ABX, the combinations will have half the length of ABX. Default is False. 126 127 Returns 128 ------- 129 audio_path_comb : pandas.DataFrame 130 Sorted sets for ABX test. 131 132 Notes 133 ----- 134 - The function reads the files in the specified folder and generates combinations of pairs. 135 - Each combination is represented as a row in the returned DataFrame. 136 - The DataFrame contains columns for the two audio paths in each combination, as well as an ID column. 137 - If constant_reference is True, the reference audio path will be the same for all combinations. 138 Otherwise, the reference audio path will vary for each combination. 139 - The DataFrame is sorted by the first audio path in each combination. 140 141 Examples 142 -------- 143 >>> abx_combination("audio_folder", parent="project_folder", constant_reference=True) 144 Returns combinations for CR-ABX with a constant reference audio path. 145 146 >>> abx_combination("audio_folder") 147 Returns combinations for standard ABX. 148 149 ''' 150 audio_path_list = read_folder(folder, parent) 151 audio_path_comb = DataFrame(combinations(audio_path_list, 2), columns=['0', '1']) 152 audio_path_comb['ID'] = audio_path_comb.index.format(name=False, formatter="{0:0=2d}".format) 153 if constant_reference: 154 audio_path_comb["Ref"] = audio_path_comb.loc[:, '0'] 155 else: 156 audio_path_comb_copy = audio_path_comb.copy() 157 audio_path_comb["Ref"] = audio_path_comb.loc[:, '0'] 158 audio_path_comb_copy["Ref"] = audio_path_comb_copy.loc[:, '1'] 159 audio_path_comb = concat([audio_path_comb, audio_path_comb_copy]) 160 161 audio_path_comb_inv = audio_path_comb.copy() 162 audio_path_comb_inv.loc[:, ['1', '0']] = audio_path_comb_inv.loc[:, ['0', '1']].values 163 audio_path_comb = concat([audio_path_comb, audio_path_comb_inv]).reset_index(drop=True) 164 audio_path_comb = audio_path_comb.sort_values(by=['0']) 165 logging.info("ABX combinations returned.") 166 return audio_path_comb 167 168def abx_combination_subset( 169 folder: str, 170 parent: str=".", 171 constant_reference: bool=False 172 ) -> DataFrame: 173 '''Reads files in a specified folder and generates combinations for 174 ABX test. Creates a subset of combinations containing the first path 175 read. 176 177 Parameters 178 ---------- 179 folder : str 180 Folder containing wav files. 181 parent : str, optional 182 Path to the project folder. Default is the current directory. 183 constant_reference : bool, optional 184 Determines whether to return combinations for standard ABX (False) 185 or CR-ABX (True) with half the length of ABX. Default is False. 186 187 Returns 188 ------- 189 audio_path_comb : pandas.DataFrame 190 Sorted sets for ABX test. 191 192 Notes 193 ----- 194 This function reads the files in the specified folder and generates 195 combinations for an ABX test. It creates a subset of combinations 196 that contain the first path read. The resulting combinations are 197 returned as a pandas DataFrame. 198 199 If `constant_reference` is True, the function generates combinations 200 for CR-ABX, where the reference path remains constant. If False, it 201 generates combinations for standard ABX, where the reference path 202 changes for each combination. 203 204 Examples 205 -------- 206 >>> abx_combination_subset("audio_folder", parent="project_folder", constant_reference=True) 207 Returns combinations for CR-ABX with the first path as the reference. 208 209 >>> abx_combination_subset("audio_folder", constant_reference=False) 210 Returns combinations for standard ABX with the first path as the reference. 211 ''' 212 audio_path_list = read_folder(folder, parent) 213 audio_path_comb = DataFrame(combinations(audio_path_list, 2), columns=['0', '1']) 214 audio_path_comb = audio_path_comb[audio_path_comb.loc[:,'0'] == audio_path_list[0]] 215 audio_path_comb['ID'] = audio_path_comb.index.format(name=False, formatter="{0:0=2d}".format) 216 if constant_reference: 217 audio_path_comb["Ref"] = audio_path_comb.loc[:, '0'] 218 else: 219 audio_path_comb_copy = audio_path_comb.copy() 220 audio_path_comb["Ref"] = audio_path_comb.loc[:, '0'] 221 audio_path_comb_copy["Ref"] = audio_path_comb_copy.loc[:, '1'] 222 audio_path_comb = concat([audio_path_comb, audio_path_comb_copy]) 223 224 audio_path_comb_inv = audio_path_comb.copy() 225 audio_path_comb_inv.loc[:, ['0', '1']] = audio_path_comb_inv.loc[:, ['0', '1']].values 226 audio_path_comb = concat([audio_path_comb, audio_path_comb_inv]).reset_index(drop=True) 227 audio_path_comb = audio_path_comb.sort_values(by=['0']) 228 logging.info("ABX combinations returned.") 229 return audio_path_comb 230 231def adaptive_combination(folder: str, parent: str): 232 '''Reads files in a specified folder and generates combinations for 233 adaptive method test. 234 235 Parameters 236 ---------- 237 folder : str 238 Folder containing set subfolders. 239 parent : str 240 Path to project folder. 241 242 Returns 243 ------- 244 audio_path_df : pandas.DataFrame 245 Sorted sets for adaptive method test. 246 ''' 247 audio_path_df = DataFrame() 248 sets = sub_folders(folder, parent) 249 for s in sets: 250 paths = read_folder(s) 251 ids = [os.path.split(p)[1][:-4] for p in paths] 252 set_list = [os.path.split(s)[1] for p in paths] 253 dict_ = {'set': set_list, 'id': ids, 'path':paths} 254 df = DataFrame(dict_) 255 audio_path_df = concat([audio_path_df, df]) 256 return audio_path_df 257 258def adaptive_irs(folder: str): 259 '''Reads files in a specified folder and generates DataFrame 260 261 Parameters 262 ---------- 263 folder : str 264 folder containing set subfolders 265 266 Returns 267 ------- 268 audio_path_df : pandas.DataFrame 269 sorted irs for adaptive method test 270 ''' 271 paths = read_folder(folder) 272 paths.sort() 273 ids = [os.path.split(p)[1][:-4] for p in paths] 274 dict_ = {'id': ids, 'path':paths} 275 audio_path_df = DataFrame(dict_) 276 277 return audio_path_df
14def filter_wavs(paths: list[str]) -> list[str]: 15 '''Filters files with '.wav' extension from a list of paths. 16 17 Parameters 18 ---------- 19 paths : list[str] 20 list of file paths 21 22 Returns 23 ------- 24 paths : list[str] 25 list of filtered file paths 26 ''' 27 paths = filter(lambda file: file.lower().endswith('.wav'), paths) 28 return list(paths)
Filters files with '.wav' extension from a list of paths.
Parameters
- paths (list[str]): list of file paths
Returns
- paths (list[str]): list of filtered file paths
30def read_folder( 31 folder, 32 parent=None, 33 filterwav=True 34 ) -> list[str]: 35 '''Reads files inside a specified folder and keeps '.wav' files 36 inside it. 37 38 Parameters 39 ---------- 40 folder : str 41 folder containing wav files 42 parent : str 43 path to project folder 44 filterwav : bool 45 True value filters out other than '.wav' files 46 47 Returns 48 ------- 49 audio_paths : list[str] 50 list containing paths to audio files inside a specified folder 51 ''' 52 if parent == None: 53 audio_folder = folder 54 else: 55 audio_folder = os.path.join(parent, folder) 56 audio_paths = os.scandir(audio_folder) 57 audio_paths = [ 58 os.path.join(audio_folder, p.name) for p in audio_paths if p.is_file() 59 ] 60 if filterwav: 61 audio_paths = filter_wavs(audio_paths) 62 logging.info(f"Read these files: {audio_paths}") 63 return audio_paths
Reads files inside a specified folder and keeps '.wav' files inside it.
Parameters
- folder (str): folder containing wav files
- parent (str): path to project folder
- filterwav (bool): True value filters out other than '.wav' files
Returns
- audio_paths (list[str]): list containing paths to audio files inside a specified folder
65def sub_folders( 66 folder : str, 67 ) -> list[str]: 68 """Return a list of sub-folders within the specified folder. 69 70 Parameters 71 ---------- 72 folder : str 73 The name of the folder. 74 parent : str 75 The parent directory of the folder. 76 77 Returns 78 ------- 79 list[str] 80 A list of sub-folders within the specified folder. 81 """ 82 parent = os.path.split(folder)[0] 83 main_folder = os.path.join(parent, folder) 84 subs = os.scandir(main_folder) 85 subs = [ 86 os.path.join(parent, folder, p.name) 87 for p in subs if p.is_dir() 88 ] 89 return subs
Return a list of sub-folders within the specified folder.
Parameters
- folder (str): The name of the folder.
- parent (str): The parent directory of the folder.
Returns
- list[str]: A list of sub-folders within the specified folder.
91def randomization(df: DataFrame) -> DataFrame: 92 ''' 93 Shuffles rows in a provided DataFrame. In this context, it randomizes 94 sets for discrimination listening tests. 95 96 Parameters 97 ---------- 98 df : pandas.DataFrame 99 DataFrame containing sets for the listening test, one per row. 100 101 Returns 102 ------- 103 df : pandas.DataFrame 104 DataFrame with randomly shuffled rows. 105 ''' 106 return df.sample(frac=1).reset_index(drop=True)
Shuffles rows in a provided DataFrame. In this context, it randomizes sets for discrimination listening tests.
Parameters
- df (pandas.DataFrame): DataFrame containing sets for the listening test, one per row.
Returns
- df (pandas.DataFrame): DataFrame with randomly shuffled rows.
110def abx_combination( 111 folder: str, 112 parent: str=".", 113 constant_reference: bool=False 114 ) -> DataFrame: 115 '''Reads files in a specified folder and generates combinations for 116 ABX test. 117 118 Parameters 119 ---------- 120 folder : str 121 Folder containing wav files. 122 parent : str, optional 123 Path to the project folder. Default is the current directory. 124 constant_reference : bool, optional 125 Determines whether to generate combinations for standard ABX (False) or CR-ABX (True). 126 For CR-ABX, the combinations will have half the length of ABX. Default is False. 127 128 Returns 129 ------- 130 audio_path_comb : pandas.DataFrame 131 Sorted sets for ABX test. 132 133 Notes 134 ----- 135 - The function reads the files in the specified folder and generates combinations of pairs. 136 - Each combination is represented as a row in the returned DataFrame. 137 - The DataFrame contains columns for the two audio paths in each combination, as well as an ID column. 138 - If constant_reference is True, the reference audio path will be the same for all combinations. 139 Otherwise, the reference audio path will vary for each combination. 140 - The DataFrame is sorted by the first audio path in each combination. 141 142 Examples 143 -------- 144 >>> abx_combination("audio_folder", parent="project_folder", constant_reference=True) 145 Returns combinations for CR-ABX with a constant reference audio path. 146 147 >>> abx_combination("audio_folder") 148 Returns combinations for standard ABX. 149 150 ''' 151 audio_path_list = read_folder(folder, parent) 152 audio_path_comb = DataFrame(combinations(audio_path_list, 2), columns=['0', '1']) 153 audio_path_comb['ID'] = audio_path_comb.index.format(name=False, formatter="{0:0=2d}".format) 154 if constant_reference: 155 audio_path_comb["Ref"] = audio_path_comb.loc[:, '0'] 156 else: 157 audio_path_comb_copy = audio_path_comb.copy() 158 audio_path_comb["Ref"] = audio_path_comb.loc[:, '0'] 159 audio_path_comb_copy["Ref"] = audio_path_comb_copy.loc[:, '1'] 160 audio_path_comb = concat([audio_path_comb, audio_path_comb_copy]) 161 162 audio_path_comb_inv = audio_path_comb.copy() 163 audio_path_comb_inv.loc[:, ['1', '0']] = audio_path_comb_inv.loc[:, ['0', '1']].values 164 audio_path_comb = concat([audio_path_comb, audio_path_comb_inv]).reset_index(drop=True) 165 audio_path_comb = audio_path_comb.sort_values(by=['0']) 166 logging.info("ABX combinations returned.") 167 return audio_path_comb
Reads files in a specified folder and generates combinations for ABX test.
Parameters
- folder (str): Folder containing wav files.
- parent (str, optional): Path to the project folder. Default is the current directory.
- constant_reference (bool, optional): Determines whether to generate combinations for standard ABX (False) or CR-ABX (True). For CR-ABX, the combinations will have half the length of ABX. Default is False.
Returns
- audio_path_comb (pandas.DataFrame): Sorted sets for ABX test.
Notes
- The function reads the files in the specified folder and generates combinations of pairs.
- Each combination is represented as a row in the returned DataFrame.
- The DataFrame contains columns for the two audio paths in each combination, as well as an ID column.
- If constant_reference is True, the reference audio path will be the same for all combinations. Otherwise, the reference audio path will vary for each combination.
- The DataFrame is sorted by the first audio path in each combination.
Examples
>>> abx_combination("audio_folder", parent="project_folder", constant_reference=True)
Returns combinations for CR-ABX with a constant reference audio path.
>>> abx_combination("audio_folder")
Returns combinations for standard ABX.
169def abx_combination_subset( 170 folder: str, 171 parent: str=".", 172 constant_reference: bool=False 173 ) -> DataFrame: 174 '''Reads files in a specified folder and generates combinations for 175 ABX test. Creates a subset of combinations containing the first path 176 read. 177 178 Parameters 179 ---------- 180 folder : str 181 Folder containing wav files. 182 parent : str, optional 183 Path to the project folder. Default is the current directory. 184 constant_reference : bool, optional 185 Determines whether to return combinations for standard ABX (False) 186 or CR-ABX (True) with half the length of ABX. Default is False. 187 188 Returns 189 ------- 190 audio_path_comb : pandas.DataFrame 191 Sorted sets for ABX test. 192 193 Notes 194 ----- 195 This function reads the files in the specified folder and generates 196 combinations for an ABX test. It creates a subset of combinations 197 that contain the first path read. The resulting combinations are 198 returned as a pandas DataFrame. 199 200 If `constant_reference` is True, the function generates combinations 201 for CR-ABX, where the reference path remains constant. If False, it 202 generates combinations for standard ABX, where the reference path 203 changes for each combination. 204 205 Examples 206 -------- 207 >>> abx_combination_subset("audio_folder", parent="project_folder", constant_reference=True) 208 Returns combinations for CR-ABX with the first path as the reference. 209 210 >>> abx_combination_subset("audio_folder", constant_reference=False) 211 Returns combinations for standard ABX with the first path as the reference. 212 ''' 213 audio_path_list = read_folder(folder, parent) 214 audio_path_comb = DataFrame(combinations(audio_path_list, 2), columns=['0', '1']) 215 audio_path_comb = audio_path_comb[audio_path_comb.loc[:,'0'] == audio_path_list[0]] 216 audio_path_comb['ID'] = audio_path_comb.index.format(name=False, formatter="{0:0=2d}".format) 217 if constant_reference: 218 audio_path_comb["Ref"] = audio_path_comb.loc[:, '0'] 219 else: 220 audio_path_comb_copy = audio_path_comb.copy() 221 audio_path_comb["Ref"] = audio_path_comb.loc[:, '0'] 222 audio_path_comb_copy["Ref"] = audio_path_comb_copy.loc[:, '1'] 223 audio_path_comb = concat([audio_path_comb, audio_path_comb_copy]) 224 225 audio_path_comb_inv = audio_path_comb.copy() 226 audio_path_comb_inv.loc[:, ['0', '1']] = audio_path_comb_inv.loc[:, ['0', '1']].values 227 audio_path_comb = concat([audio_path_comb, audio_path_comb_inv]).reset_index(drop=True) 228 audio_path_comb = audio_path_comb.sort_values(by=['0']) 229 logging.info("ABX combinations returned.") 230 return audio_path_comb
Reads files in a specified folder and generates combinations for ABX test. Creates a subset of combinations containing the first path read.
Parameters
- folder (str): Folder containing wav files.
- parent (str, optional): Path to the project folder. Default is the current directory.
- constant_reference (bool, optional): Determines whether to return combinations for standard ABX (False) or CR-ABX (True) with half the length of ABX. Default is False.
Returns
- audio_path_comb (pandas.DataFrame): Sorted sets for ABX test.
Notes
This function reads the files in the specified folder and generates combinations for an ABX test. It creates a subset of combinations that contain the first path read. The resulting combinations are returned as a pandas DataFrame.
If constant_reference
is True, the function generates combinations
for CR-ABX, where the reference path remains constant. If False, it
generates combinations for standard ABX, where the reference path
changes for each combination.
Examples
>>> abx_combination_subset("audio_folder", parent="project_folder", constant_reference=True)
Returns combinations for CR-ABX with the first path as the reference.
>>> abx_combination_subset("audio_folder", constant_reference=False)
Returns combinations for standard ABX with the first path as the reference.
232def adaptive_combination(folder: str, parent: str): 233 '''Reads files in a specified folder and generates combinations for 234 adaptive method test. 235 236 Parameters 237 ---------- 238 folder : str 239 Folder containing set subfolders. 240 parent : str 241 Path to project folder. 242 243 Returns 244 ------- 245 audio_path_df : pandas.DataFrame 246 Sorted sets for adaptive method test. 247 ''' 248 audio_path_df = DataFrame() 249 sets = sub_folders(folder, parent) 250 for s in sets: 251 paths = read_folder(s) 252 ids = [os.path.split(p)[1][:-4] for p in paths] 253 set_list = [os.path.split(s)[1] for p in paths] 254 dict_ = {'set': set_list, 'id': ids, 'path':paths} 255 df = DataFrame(dict_) 256 audio_path_df = concat([audio_path_df, df]) 257 return audio_path_df
Reads files in a specified folder and generates combinations for adaptive method test.
Parameters
- folder (str): Folder containing set subfolders.
- parent (str): Path to project folder.
Returns
- audio_path_df (pandas.DataFrame): Sorted sets for adaptive method test.
259def adaptive_irs(folder: str): 260 '''Reads files in a specified folder and generates DataFrame 261 262 Parameters 263 ---------- 264 folder : str 265 folder containing set subfolders 266 267 Returns 268 ------- 269 audio_path_df : pandas.DataFrame 270 sorted irs for adaptive method test 271 ''' 272 paths = read_folder(folder) 273 paths.sort() 274 ids = [os.path.split(p)[1][:-4] for p in paths] 275 dict_ = {'id': ids, 'path':paths} 276 audio_path_df = DataFrame(dict_) 277 278 return audio_path_df
Reads files in a specified folder and generates DataFrame
Parameters
- folder (str): folder containing set subfolders
Returns
- audio_path_df (pandas.DataFrame): sorted irs for adaptive method test