├── README.md ├── readme.txt ├── reclist-gen-cvvc.ini └── reclist-gen-cvvc.py /README.md: -------------------------------------------------------------------------------- 1 | # reclist-gen-cvvc 2 | Reclist generator for UTAU CVVC 3 | 4 | Please see readme.txt for usage. 5 | 6 | # Running 7 | `python3 reclist-gen-cvvc.py` -------------------------------------------------------------------------------- /readme.txt: -------------------------------------------------------------------------------- 1 | ReclistGen_CVVC ver20200621 2 | 本程序通过读取presamp文件,自动生成CVVC录音表以及对应的初始oto模板。 3 | 4 | 用法: 5 | 按需求修改配置文件:reclist-gen-cvvc.ini,然后运行reclist-gen-cvvc.exe即可。 6 | (也可以执行reclist-gen-cvvc.py) 7 | 8 | 配置说明: 9 | input_path=presamp.ini 输入presamp文件的相对路径 10 | reclist_output_path=Reclist.txt 输出录音表文件的相对路径 11 | length=8 每句的字数 12 | include_CV_head=True 是否要求包含句首CV字(True为要求,False为不要求) 13 | include_VV=True 是否要求包含VV字(True为要求,False为不要求) 14 | use_underbar=True 字与字之间是否加入“_”(True为是,False为否) 15 | use_planb=True 是否使用Plan B(另附说明) 16 | oto_output_path=oto.ini 输出oto文件的相对路径 17 | oto_max_of_same_cv=3 oto中相同CV音素最多重复出现的条目数 18 | oto_max_of_same_vc=3 oto中相同VC音素最多重复出现的条目数 19 | oto_preset_blank=1250 oto的前置空白长度 20 | oto_bpm=130 录音的BPM 21 | oto_devide_vccv=False 是否将VC和CV分开排列(True为是,False为否) 22 | 23 | 如遇到bug或者使用上的问题,请联系sder.colin@gmail.com。 24 | 25 | 26 | **更新履历** 27 | 20200621: 28 | - 修正了非Plan B时可能出现的一个错误。 29 | 30 | 20200604: 31 | - 减少了少量不必要的重复输出。 32 | 33 | 20191215: 34 | - 修正了presamp文件的读取错误。 35 | 36 | 20191120: 37 | - 将"oto_max_of_same"参数分为了分别针对CV和VC的两个参数。 38 | 39 | 20180918: 40 | - 增加了Plan B。 41 | 42 | 20180108: 43 | - 修正了oto文件中R不占位的错误。 44 | - 修正了部分句中CV缺失的错误。 45 | - 发布包中增加了源代码文件。 -------------------------------------------------------------------------------- /reclist-gen-cvvc.ini: -------------------------------------------------------------------------------- 1 | [RECLIST] 2 | input_path=presamp.ini 3 | reclist_output_path=Reclist.txt 4 | length=8 5 | include_CV_head=True 6 | include_VV=True 7 | use_underbar=True 8 | use_planb=True 9 | [OTOSET] 10 | oto_output_path=oto.ini 11 | oto_max_of_same_cv=3 12 | oto_max_of_same_vc=3 13 | oto_preset_blank=1250 14 | oto_bpm=130 15 | oto_devide_vccv=True -------------------------------------------------------------------------------- /reclist-gen-cvvc.py: -------------------------------------------------------------------------------- 1 | import re 2 | import codecs 3 | 4 | version = "200621" 5 | debug = False 6 | 7 | 8 | class cv: 9 | def __init__(self, name, c, v, type): 10 | self.name = name 11 | self.c = c 12 | self.v = v 13 | self.type = type 14 | 15 | 16 | class worker(): 17 | cvlist = [] 18 | vclist = [] 19 | vvlist = [] 20 | clist = [] 21 | vlist = [] 22 | 23 | def findcv(self, list, c, v, fromindex=0): 24 | for i in range(fromindex, len(list)): 25 | cv = list[i] 26 | if(cv.c == c and cv.v == v): 27 | return cv 28 | return None 29 | 30 | def findcv_c(self, list, c, fromindex=0, cyclic=False): 31 | for i in range(fromindex, len(list)): 32 | cv = list[i] 33 | if(cv.c == c): 34 | return cv 35 | 36 | # 循环搜索 37 | if cyclic: 38 | for i in range(0, len(list)): 39 | cv = list[i] 40 | if(cv.c == c): 41 | return cv 42 | return None 43 | 44 | def findcv_v(self, list, v, fromindex=0, cyclic=False): 45 | for i in range(fromindex, len(list)): 46 | cv = list[i] 47 | if(cv.v == v): 48 | return cv 49 | # 循环搜索 50 | if cyclic: 51 | for i in range(0, len(list)): 52 | cv = list[i] 53 | if(cv.v == v): 54 | return cv 55 | return None 56 | 57 | def read_presamp(self, filename='presamp.ini'): 58 | V_list = [] 59 | C_list = [] 60 | CV_V_list = [] 61 | CV_C_list = [] 62 | tag = '' 63 | for temp in open(filename, 'r', encoding='UTF-8').readlines(): 64 | if (temp.find('[VOWEL]') != -1): 65 | tag = '[VOWEL]' 66 | elif (temp.find('[CONSONANT]') != -1): 67 | tag = '[CONSONANT]' 68 | elif (temp.find('[') != -1): 69 | tag = '' 70 | else: 71 | if(tag == '[VOWEL]'): 72 | temp_list = re.split(r'[,=]+', temp) 73 | V_list.append(temp_list[0]) 74 | CV_V_list.append(temp_list[2:-1]) 75 | elif(tag == '[CONSONANT]'): 76 | temp_list = re.split(r'[,=]+', temp) 77 | if V_list.count(temp_list[0]) == 0: 78 | C_list.append(temp_list[0]) 79 | else: 80 | C_list.append(temp_list[0] + '#') 81 | CV_C_list.append(temp_list[1:-1]) 82 | l = -1 83 | for i in range(0, len(V_list)): 84 | for j in CV_V_list[i]: 85 | l = l + 1 86 | cv_now = cv(j, '', V_list[i], 'cv') 87 | for k in range(0, len(C_list)): 88 | if j in CV_C_list[k]: 89 | cv_now.c = C_list[k] 90 | if cv_now.c == '': 91 | cv_now.c = cv_now.v 92 | self.cvlist.append(cv_now) 93 | self.clist = C_list[:] 94 | self.vlist = V_list[:] 95 | 96 | for _c in self.clist: 97 | for _v in self.vlist: 98 | vc = cv(_v + ' ' + ''.join(_c).replace('#', ''), _c, _v, 'vc') 99 | self.vclist.append(vc) 100 | 101 | for _v1 in self.vlist: 102 | for _v2 in self.vlist: 103 | if self.findcv_c(self.cvlist, _v1) != None: # 确保VV作为VC时C部分的元音有存在纯元音 104 | vv = cv(_v2 + ' ' + _v1, _v1, _v2, 'vv') 105 | self.vvlist.append(vv) 106 | else: 107 | break 108 | 109 | if debug: 110 | read_result = codecs.open("read_result.txt", "w", encoding="UTF-8") 111 | read_result.write("clist:\r\n") 112 | for _c in self.clist: 113 | read_result.write(_c + " ") 114 | read_result.write("\r\nvlist:\r\n") 115 | for _v in self.vlist: 116 | read_result.write(_v + " ") 117 | read_result.write("\r\ncvlist:\r\n") 118 | for _cv in self.cvlist: 119 | read_result.write(_cv.name + "=" + _cv.c + " " + _cv.v + "\r\n") 120 | read_result.write("\r\nvclist:\r\n") 121 | for _vc in self.vclist: 122 | read_result.write(_vc.name + "\r\n") 123 | read_result.write("\r\nvvlist:\r\n") 124 | for _vv in self.vvlist: 125 | read_result.write(_vv.name + "\r\n") 126 | 127 | def gen_CVVC(self, path='Reclist.txt', length=8, UsePlanB=True, CV_head=True, IncludeVV=True, UseUnderlineInReclist=True, otopath='oto.ini', OtoMaxOfSameCV=3, OtoMaxOfSameVC=3, preset_blank=float(1250), oto_bpm=float(130), DivideVCCV=True): 128 | reclist = [] # List> 按行收录 129 | vc_remained = self.vclist[:] # 余下的VC部 130 | vR_remained = self.vlist[:] # 余下的V_R 131 | 132 | # 如果要求包含VV,则包含VV 133 | if IncludeVV == True: 134 | vc_remained.extend(self.vvlist) 135 | 136 | if (not UsePlanB) and CV_head: 137 | headcv_remained = self.cvlist[:] # 余下的句首CV 138 | 139 | notheadcv_remained = self.cvlist[:] # 余下的句中CV 140 | 141 | if not UsePlanB: 142 | # 遍历CV部(Plan A) 143 | row_total = int(len(self.cvlist) / length) 144 | vc_count_inlastrow = len(self.cvlist) % length 145 | if(vc_count_inlastrow != 0): 146 | row_total += 1 147 | for i in range(0, row_total): 148 | row = [] 149 | v_last = '' 150 | for j in range(0, length): 151 | if(i * length + j == len(self.cvlist)): 152 | break 153 | cv_now = self.cvlist[i * length + j] 154 | row.append(cv_now) 155 | if j == 0: 156 | if CV_head: 157 | headcv_remained.remove(cv_now) # 删除已经出现的句首CV字 158 | elif notheadcv_remained.count(cv_now) > 0: 159 | notheadcv_remained.remove(cv_now) # 删除已经出现的句中CV字 160 | if(vc_remained.count(self.findcv(self.vclist, cv_now.c, v_last))): 161 | vc_remained.remove(self.findcv(self.vclist, cv_now.c, v_last)) # 删除已经出现的VC部 162 | v_last = cv_now.v 163 | reclist.append(row) 164 | # 记录句尾V的出现 165 | if(vR_remained.count(row[len(row) - 1].v) > 0): 166 | vR_remained.remove(row[len(row) - 1].v) 167 | else: 168 | # 遍历CV部(Plan B) 169 | for cv_now in self.cvlist: 170 | row = [] 171 | row.append(cv_now) 172 | row.append(cv_now) 173 | row.append(cv_now) 174 | if(vc_remained.count(self.findcv(self.vclist, cv_now.c, cv_now.v))): 175 | vc_remained.remove(self.findcv(self.vclist, cv_now.c, cv_now.v)) # 删除已经出现的VC部 176 | if(vc_remained.count(self.findcv(self.vvlist, cv_now.c, cv_now.v))): 177 | vc_remained.remove(self.findcv(self.vvlist, cv_now.c, cv_now.v)) # 删除已经出现的VV部 178 | reclist.append(row) 179 | 180 | # 补全VC部 181 | row = [] # 生成新行 182 | count = 0 # 该行的字数 183 | vc_wanted = None 184 | vc_wanted_next = None 185 | add_flag = 0 # 用于标记是否出现增字(浪费了一个VC部的机会) 186 | index_findcv_connective = 0 # 为寻找可接续的CV而设置的搜索指针 187 | # 为随意取CV时尽量平均而设置的搜索指针 188 | index_random_findcv_c = [] 189 | for i in range(0, len(self.clist)): 190 | index_random_findcv_c.append(0) 191 | index_random_findcv_v = [] 192 | for i in range(0, len(self.vlist)): 193 | index_random_findcv_v.append(0) 194 | 195 | while len(vc_remained) > 0: # 主循环 196 | if vc_wanted != None and count != 0: # 非句首且不出现增字时 197 | vc_remained.remove(vc_wanted) # 取出将要写入的VC部 198 | if vc_wanted.type != 'vv': 199 | index_findcv_connective = index_random_findcv_c[self.clist.index(vc_wanted.c)] 200 | else: 201 | index_findcv_connective = 0 202 | while True: # 以CV字为单位的子循环 203 | # 句首或者出现增字时,需要先写入一个与前文无关的CV字 204 | if count == 0: # 句首时 205 | vc_wanted = vc_remained[0] # 随便取出一个VC部 206 | vc_remained.remove(vc_wanted) # 移除 207 | cv_now = None 208 | if CV_head and not UsePlanB: 209 | # 要求句首CV时,首先尝试写入一个以VC部的V结尾,且还未在句首出现过的CV字 210 | cv_now = self.findcv_v(headcv_remained, vc_wanted.v) 211 | if cv_now != None: 212 | headcv_remained.remove(cv_now) # 删除已经出现句首的CV字 213 | if cv_now == None: 214 | cv_now = self.findcv_v(self.cvlist, vc_wanted.v, index_random_findcv_v[self.vlist.index(vc_wanted.v)], True) # 写入一个以VC部的V结尾的CV字 215 | index_random_findcv_v[self.vlist.index(vc_wanted.v)] = self.cvlist.index(cv_now) + 1 216 | row.append(cv_now) 217 | count += 1 218 | elif add_flag == 1: # 出现增字的情况 219 | if count + 1 == length: # 如果加入增字会导致超出行长度,则先行换行 220 | count = 0 221 | reclist.append(row) 222 | # 记录句尾V的出现 223 | if(vR_remained.count(row[len(row) - 1].v) > 0): 224 | vR_remained.remove(row[len(row) - 1].v) 225 | row = [] 226 | cv_now = self.findcv_v(self.cvlist, vc_wanted.v, index_random_findcv_v[self.vlist.index(vc_wanted.v)], True) # 写入一个以VC部的V结尾的CV字(此字为增字,因为其C和前一个字的V组成的VC部已经不需要) 227 | if count != 1: # 如果前一个字是句首则已经写入过,所以不再写入 228 | index_random_findcv_v[self.vlist.index(vc_wanted.v)] = self.cvlist.index(cv_now) + 1 229 | row.append(cv_now) 230 | if notheadcv_remained.count(cv_now) > 0 and count > 0: 231 | notheadcv_remained.remove(cv_now) # 删除已经出现的句中CV字 232 | count += 1 233 | add_flag = 0 234 | 235 | # 搜索确定下一个要写入的CV字,使得其C与上一个字凑成所需要的VC部 236 | if index_findcv_connective < len(self.cvlist): 237 | cv_now = self.findcv_c(self.cvlist, vc_wanted.c, index_findcv_connective) # 从上次搜索到的位置继续向下搜索 238 | else: 239 | cv_now = None # 若指针越界或已经搜索完所有结果,则置空cv_now,并准备增字 240 | 241 | # 由于搜索不到任何符合条件的VC,则下一个字必须增字,并离开本轮子循环 242 | if cv_now == None: 243 | # 先随意写入一个CV字来完成本轮的VC部,V是什么无所谓,因为没有能够接续下去的V 244 | if vc_wanted.type != 'vv': 245 | cv_now = self.findcv_c(self.cvlist, vc_wanted.c, index_random_findcv_c[self.clist.index(vc_wanted.c)], True) 246 | else: 247 | cv_now = self.findcv_c(self.cvlist, vc_wanted.c) 248 | add_flag = 1 # 点亮增字标记 249 | if(len(vc_remained) > 0): 250 | vc_wanted = vc_remained[0] # 随意取出一个下轮的VC部 251 | break # 离开本轮子循环 252 | 253 | # 检查搜索到的CV字是否符合要求 254 | # 尝试找到下一个需要的VC部,使得其V与目前检索到的CV字的V相同(即能够接续) 255 | vc_wanted_next = self.findcv_v(vc_remained, cv_now.v) 256 | index_findcv_connective = self.cvlist.index(cv_now) + 1 # 记录搜索指针到达的位置 257 | if vc_wanted_next != None: 258 | # 如果找到了符合要求的VC部,则记录该VC部,并离开本轮子循环 259 | if vc_wanted.type != 'vv': 260 | index_random_findcv_c[self.clist.index(vc_wanted.c)] = index_findcv_connective 261 | vc_wanted = vc_wanted_next 262 | break 263 | 264 | # VC部用尽时结束工作 265 | if len(vc_remained) == 0: 266 | break 267 | 268 | # 离开上述子循环的条件是:已经找到一个合适的CV字来写入(有可能在其之前还要再写入一个增字) 269 | if not cv_now == None: 270 | row.append(cv_now) # 写入该CV字 271 | if notheadcv_remained.count(cv_now) > 0 and count > 0: 272 | notheadcv_remained.remove(cv_now) # 删除已经出现的句中CV字 273 | count += 1 274 | 275 | # 如果字数达到一句的长度,则换行 276 | if(count == length): 277 | count = 0 278 | reclist.append(row) 279 | # 记录句尾V的出现 280 | if(vR_remained.count(row[len(row) - 1].v) > 0): 281 | vR_remained.remove(row[len(row) - 1].v) 282 | row = [] 283 | 284 | # 全部VC部用尽后,将最后一行未满的字写入 285 | if len(row) > 0: 286 | reclist.append(row) 287 | # 记录句尾V的出现 288 | if(vR_remained.count(row[len(row) - 1].v) > 0): 289 | vR_remained.remove(row[len(row) - 1].v) 290 | 291 | if not UsePlanB: 292 | # 如果要求句首CV,则需要在最后单独补充 293 | if CV_head: 294 | while True: 295 | row = [] 296 | i = 0 297 | while i < length: 298 | if len(headcv_remained) > 0: 299 | row.append(headcv_remained[0]) 300 | # 记录句尾V的出现 301 | if(vR_remained.count(headcv_remained[0].v) > 0): 302 | vR_remained.remove(headcv_remained[0].v) 303 | headcv_remained.remove(headcv_remained[0]) 304 | i += 1 305 | else: 306 | break 307 | if i < length: # 隔一个字放置一个空拍 308 | if i + 1 < length and len(headcv_remained) > 0: 309 | row.append(cv('blank', '', '', 'blank')) 310 | i += 1 311 | reclist.append(row) 312 | if len(headcv_remained) == 0: 313 | break 314 | 315 | # 补充句中CV 316 | while len(notheadcv_remained)>0: 317 | row = [] 318 | i = 0 319 | while i < length: 320 | if len(notheadcv_remained) > 0: 321 | row.append(notheadcv_remained[0]) 322 | notheadcv_remained.remove(notheadcv_remained[0]) 323 | i += 1 324 | else: 325 | break 326 | reclist.append(row) 327 | 328 | # 记录句尾V的出现 329 | if(vR_remained.count(row[len(row) - 1].v) > 0): 330 | vR_remained.remove(row[len(row) - 1].v) 331 | 332 | # 补充V_R 333 | for v_R in vR_remained: 334 | row = [] 335 | row.append(self.findcv_v(self.cvlist, v_R, 0, False)) 336 | reclist.append(row) 337 | 338 | # 写入CVVC录音表文件 339 | f_reclist = open(path, 'w', encoding='UTF-8') 340 | reclist_text = [] 341 | for row in reclist: 342 | text = '_' 343 | for _cv in row: 344 | if UseUnderlineInReclist and text != '_': 345 | text += '_' 346 | if _cv.name != 'blank': 347 | text += _cv.name 348 | else: 349 | if UseUnderlineInReclist: 350 | text += 'R' 351 | else: 352 | text += '_' 353 | reclist_text.append(text) 354 | f_reclist.write(text + "\n") 355 | 356 | # 写入oto文件 357 | f_oto = open(otopath, 'w', encoding='UTF-8') 358 | exist_list_cv = [] 359 | exist_list_vc = [] 360 | ticks = float(60) / oto_bpm * float(1000) 361 | vc_list_temp = [] 362 | repeat_list = [] 363 | for i in range(0, len(reclist)): 364 | row_text = reclist_text[i] + ".wav=" 365 | row = reclist[i] 366 | count = 0 367 | row_count = 0 368 | cv_last = None 369 | for _cv in row: 370 | if _cv.name == 'blank': 371 | count = count + 1 372 | cv_last = None 373 | continue 374 | # VC 375 | text = row_text 376 | if cv_last != None: 377 | _name = cv_last.v + ' ' + _cv.c.replace('#', '') 378 | else: 379 | _name = None 380 | if _name != None: 381 | if OtoMaxOfSameVC == -1 or exist_list_vc.count(_name) < OtoMaxOfSameVC: 382 | text += _name 383 | if exist_list_vc.count(_name) > 0: 384 | text += str(exist_list_vc.count(_name) + 1) 385 | if exist_list_vc.count(_name) == 1: 386 | repeat_list.append(_name + ',' + str(exist_list_vc.count(_name) + 1) + '\n') 387 | else: 388 | repeat_list.remove(_name + ',' + str(exist_list_vc.count(_name)) + '\n') 389 | repeat_list.append(_name + ',' + str(exist_list_vc.count(_name) + 1) + '\n') 390 | text += ',' + \ 391 | "{:.1f}".format(preset_blank - 0.5 * ticks + float(count) * ticks) 392 | text += ',' + "{:.1f}".format(0.65 * ticks) 393 | text += ',' + "{:.1f}".format(-1 * ticks) 394 | text += ',' + "{:.1f}".format(0.5 * ticks) 395 | text += ',' + "{:.1f}".format(0.5 * ticks / float(3)) 396 | if DivideVCCV: 397 | vc_list_temp.append(text + '\n') 398 | else: 399 | f_oto.write(text + "\n") 400 | exist_list_vc.append(_name) 401 | 402 | # CV 403 | text = row_text 404 | if cv_last: 405 | _name = _cv.name 406 | else: 407 | _name = "- " + _cv.name 408 | 409 | if UsePlanB and row_count == 2 and len(row) == 3: 410 | _name = _name + "_L" 411 | 412 | if OtoMaxOfSameCV == -1 or exist_list_cv.count(_name) < OtoMaxOfSameCV: 413 | text += _name 414 | repeat_time = '' 415 | if exist_list_cv.count(_name) > 0: 416 | repeat_time = str(exist_list_cv.count(_name) + 1) 417 | text += repeat_time 418 | if exist_list_cv.count(_name) == 1: 419 | repeat_list.append(_name + ',' + str(exist_list_cv.count(_name) + 1) + '\n') 420 | else: 421 | repeat_list.remove(_name + ',' + str(exist_list_cv.count(_name)) + '\n') 422 | repeat_list.append(_name + ',' + str(exist_list_cv.count(_name) + 1) + '\n') 423 | text += ',' + \ 424 | "{:.1f}".format(preset_blank - 0.1 * ticks + float(count) * ticks) 425 | text += ',' + "{:.1f}".format(0.3 * ticks) 426 | text += ',' + "{:.1f}".format(float(-0.7) * ticks) 427 | text += ',' + "{:.1f}".format(0.1 * ticks) 428 | text += ',' + "{:.1f}".format(0.1 * ticks / float(3)) 429 | f_oto.write(text + "\n") 430 | exist_list_cv.append(_name) 431 | 432 | cv_last = _cv 433 | count += 1 434 | row_count += 1 435 | 436 | # V_R 437 | text = row_text 438 | _name = cv_last.v + ' R' 439 | if OtoMaxOfSameVC == -1 or exist_list_vc.count(_name) < OtoMaxOfSameVC: 440 | text += _name 441 | if exist_list_vc.count(_name) > 0: 442 | text += str(exist_list_vc.count(_name) + 1) 443 | if exist_list_vc.count(_name) == 1: 444 | repeat_list.append(_name + ',' + str(exist_list_vc.count(_name) + 1) + '\n') 445 | else: 446 | repeat_list.remove(_name + ',' + str(exist_list_vc.count(_name)) + '\n') 447 | repeat_list.append(_name + ',' + str(exist_list_vc.count(_name) + 1) + '\n') 448 | text += ',' + \ 449 | "{:.1f}".format(preset_blank - 0.5 * ticks + float(count) * ticks) 450 | text += ',' + "{:.1f}".format(0.65 * ticks) 451 | text += ',' + "{:.1f}".format(-1 * ticks) 452 | text += ',' + "{:.1f}".format(0.5 * ticks) 453 | text += ',' + "{:.1f}".format(0.5 * ticks / float(3)) 454 | if DivideVCCV: 455 | vc_list_temp.append(text + '\n') 456 | else: 457 | f_oto.write(text + "\n") 458 | exist_list_vc.append(_name) 459 | 460 | if DivideVCCV: 461 | f_oto.writelines(vc_list_temp) 462 | 463 | if debug: 464 | # 写入repeat文件 465 | f_repeat = open('repeat.txt', 'w', encoding='UTF-8') 466 | f_repeat.writelines(repeat_list) 467 | return 468 | 469 | 470 | ini = open('reclist-gen-cvvc.ini', 'r', encoding='UTF-8').readlines() 471 | _input_path = ''.join(re.split(r'[,=]+', ini[1])[1]).strip('\n') 472 | _reclist_output_path = ''.join(re.split(r'[,=]+', ini[2])[1]).strip('\n') 473 | _length = int(''.join(re.split(r'[,=]+', ini[3])[1]).strip('\n')) 474 | _include_CV_head = ''.join(re.split(r'[,=]+', ini[4])[1]).strip('\n') == 'True' 475 | _include_VV = ''.join(re.split(r'[,=]+', ini[5])[1]).strip('\n') == 'True' 476 | _use_underbar = ''.join(re.split(r'[,=]+', ini[6])[1]).strip('\n') == 'True' 477 | _use_planb = ''.join(re.split(r'[,=]+', ini[7])[1]).strip('\n') == 'True' 478 | _oto_output_path = ''.join(re.split(r'[,=]+', ini[9])[1]).strip('\n') 479 | _oto_max_of_same_cv = int(''.join(re.split(r'[,=]+', ini[10])[1]).strip('\n')) 480 | _oto_max_of_same_vc = int(''.join(re.split(r'[,=]+', ini[11])[1]).strip('\n')) 481 | _oto_preset_blank = int(''.join(re.split(r'[,=]+', ini[12])[1]).strip('\n')) 482 | _oto_bpm = int(''.join(re.split(r'[,=]+', ini[13])[1]).strip('\n')) 483 | _oto_divide_vccv = ''.join(re.split(r'[,=]+', ini[14])[1]).strip('\n') == 'True' 484 | 485 | my_worker = worker() 486 | my_worker.read_presamp(_input_path) 487 | my_worker.gen_CVVC(_reclist_output_path, _length, _use_planb, _include_CV_head, _include_VV, 488 | _use_underbar, _oto_output_path, _oto_max_of_same_cv, _oto_max_of_same_vc, _oto_preset_blank, _oto_bpm, _oto_divide_vccv) 489 | --------------------------------------------------------------------------------