├── .gitattributes ├── .gitignore ├── Packed ├── PyUtau_Release.zip └── pyuppslink_external.7z ├── README.md ├── Release ├── DLLs │ ├── _bsddb.pyd │ ├── _ctypes.pyd │ ├── _ctypes_test.pyd │ ├── _elementtree.pyd │ ├── _hashlib.pyd │ ├── _multiprocessing.pyd │ ├── _socket.pyd │ ├── _sqlite3.pyd │ ├── _testcapi.pyd │ ├── _tkinter.pyd │ ├── bz2.pyd │ ├── py.ico │ ├── pyc.ico │ ├── pyexpat.pyd │ ├── select.pyd │ ├── sqlite3.dll │ ├── tcl85.dll │ ├── tclpip85.dll │ ├── tk85.dll │ ├── unicodedata.pyd │ └── winsound.pyd ├── pysrc │ ├── pyuppslink.py │ ├── pyutau │ │ ├── __init__.py │ │ ├── base64pb.py │ │ ├── midikey.py │ │ └── resamplerargs.py │ └── pyutauplus.py ├── pystandalone.exe ├── python27.dll ├── pythonlib.zip └── pyutauplus_resampler.exe ├── pystandalone ├── main.cpp ├── pystandalone.cpp ├── pystandalone.h ├── pystandalone.vcxproj └── pystandalone.vcxproj.filters ├── pyutau.sln ├── pyutau ├── __init__.py ├── base64pb.py ├── midikey.py ├── pyutau.pyproj └── resamplerargs.py ├── pyutauplus ├── pyuppslink.py ├── pyutauplus.py └── pyutauplus.pyproj └── pyutauplus_resampler ├── main.cpp ├── pyutauplus_resampler.vcxproj └── pyutauplus_resampler.vcxproj.filters /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | 19 | # External tool builders 20 | .externalToolBuilders/ 21 | 22 | # Locally stored "Eclipse launch configurations" 23 | *.launch 24 | 25 | # CDT-specific 26 | .cproject 27 | 28 | # PDT-specific 29 | .buildpath 30 | 31 | 32 | ################# 33 | ## Visual Studio 34 | ################# 35 | 36 | ## Ignore Visual Studio temporary files, build results, and 37 | ## files generated by popular Visual Studio add-ons. 38 | 39 | # User-specific files 40 | *.suo 41 | *.user 42 | *.sln.docstates 43 | 44 | # Build results 45 | 46 | [Dd]ebug/ 47 | # [Rr]elease/ 48 | x64/ 49 | build/ 50 | [Bb]in/ 51 | [Oo]bj/ 52 | 53 | # MSTest test Results 54 | [Tt]est[Rr]esult*/ 55 | [Bb]uild[Ll]og.* 56 | 57 | *_i.c 58 | *_p.c 59 | *.ilk 60 | *.meta 61 | *.obj 62 | *.pch 63 | *.pdb 64 | *.pgc 65 | *.pgd 66 | *.rsp 67 | *.sbr 68 | *.tlb 69 | *.tli 70 | *.tlh 71 | *.tmp 72 | *.tmp_proj 73 | *.log 74 | *.vspscc 75 | *.vssscc 76 | .builds 77 | *.pidb 78 | *.log 79 | *.scc 80 | 81 | # Visual C++ cache files 82 | ipch/ 83 | *.aps 84 | *.ncb 85 | *.opensdf 86 | *.sdf 87 | *.cachefile 88 | 89 | # Visual Studio profiler 90 | *.psess 91 | *.vsp 92 | *.vspx 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | 101 | # TeamCity is a build add-in 102 | _TeamCity* 103 | 104 | # DotCover is a Code Coverage Tool 105 | *.dotCover 106 | 107 | # NCrunch 108 | *.ncrunch* 109 | .*crunch*.local.xml 110 | 111 | # Installshield output folder 112 | [Ee]xpress/ 113 | 114 | # DocProject is a documentation generator add-in 115 | DocProject/buildhelp/ 116 | DocProject/Help/*.HxT 117 | DocProject/Help/*.HxC 118 | DocProject/Help/*.hhc 119 | DocProject/Help/*.hhk 120 | DocProject/Help/*.hhp 121 | DocProject/Help/Html2 122 | DocProject/Help/html 123 | 124 | # Click-Once directory 125 | publish/ 126 | 127 | # Publish Web Output 128 | *.Publish.xml 129 | *.pubxml 130 | 131 | # NuGet Packages Directory 132 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line 133 | #packages/ 134 | 135 | # Windows Azure Build Output 136 | csx 137 | *.build.csdef 138 | 139 | # Windows Store app package directory 140 | AppPackages/ 141 | 142 | # Others 143 | sql/ 144 | *.Cache 145 | ClientBin/ 146 | [Ss]tyle[Cc]op.* 147 | ~$* 148 | *~ 149 | *.dbmdl 150 | *.[Pp]ublish.xml 151 | *.pfx 152 | *.publishsettings 153 | 154 | # RIA/Silverlight projects 155 | Generated_Code/ 156 | 157 | # Backup & report files from converting an old project file to a newer 158 | # Visual Studio version. Backup files are not needed, because we have git ;-) 159 | _UpgradeReport_Files/ 160 | Backup*/ 161 | UpgradeLog*.XML 162 | UpgradeLog*.htm 163 | 164 | # SQL Server files 165 | App_Data/*.mdf 166 | App_Data/*.ldf 167 | 168 | ############# 169 | ## Windows detritus 170 | ############# 171 | 172 | # Windows image file caches 173 | Thumbs.db 174 | ehthumbs.db 175 | 176 | # Folder config file 177 | Desktop.ini 178 | 179 | # Recycle Bin used on file shares 180 | $RECYCLE.BIN/ 181 | 182 | # Mac crap 183 | .DS_Store 184 | 185 | 186 | ############# 187 | ## Python 188 | ############# 189 | 190 | *.py[co] 191 | 192 | # Packages 193 | *.egg 194 | *.egg-info 195 | dist/ 196 | build/ 197 | eggs/ 198 | parts/ 199 | var/ 200 | sdist/ 201 | develop-eggs/ 202 | .installed.cfg 203 | 204 | # Installer logs 205 | pip-log.txt 206 | 207 | # Unit test / coverage reports 208 | .coverage 209 | .tox 210 | 211 | #Translations 212 | *.mo 213 | 214 | #Mr Developer 215 | .mr.developer.cfg 216 | -------------------------------------------------------------------------------- /Packed/PyUtau_Release.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Toufukun/PyUtau/689c383cf51be52336395e106f392b67f6737502/Packed/PyUtau_Release.zip -------------------------------------------------------------------------------- /Packed/pyuppslink_external.7z: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Toufukun/PyUtau/689c383cf51be52336395e106f392b67f6737502/Packed/pyuppslink_external.7z -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | PyUtau 2 | ====== 3 | A Python package for scripting with UTAU 4 | 5 | **Warning:** This project is only a snapshot containing a Python port of `uppslink`, and will probably no longer be developed. And there won't be any documentation or tutorial about this project as well. 6 | -------------------------------------------------------------------------------- /Release/DLLs/_bsddb.pyd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Toufukun/PyUtau/689c383cf51be52336395e106f392b67f6737502/Release/DLLs/_bsddb.pyd -------------------------------------------------------------------------------- /Release/DLLs/_ctypes.pyd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Toufukun/PyUtau/689c383cf51be52336395e106f392b67f6737502/Release/DLLs/_ctypes.pyd -------------------------------------------------------------------------------- /Release/DLLs/_ctypes_test.pyd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Toufukun/PyUtau/689c383cf51be52336395e106f392b67f6737502/Release/DLLs/_ctypes_test.pyd -------------------------------------------------------------------------------- /Release/DLLs/_elementtree.pyd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Toufukun/PyUtau/689c383cf51be52336395e106f392b67f6737502/Release/DLLs/_elementtree.pyd -------------------------------------------------------------------------------- /Release/DLLs/_hashlib.pyd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Toufukun/PyUtau/689c383cf51be52336395e106f392b67f6737502/Release/DLLs/_hashlib.pyd -------------------------------------------------------------------------------- /Release/DLLs/_multiprocessing.pyd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Toufukun/PyUtau/689c383cf51be52336395e106f392b67f6737502/Release/DLLs/_multiprocessing.pyd -------------------------------------------------------------------------------- /Release/DLLs/_socket.pyd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Toufukun/PyUtau/689c383cf51be52336395e106f392b67f6737502/Release/DLLs/_socket.pyd -------------------------------------------------------------------------------- /Release/DLLs/_sqlite3.pyd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Toufukun/PyUtau/689c383cf51be52336395e106f392b67f6737502/Release/DLLs/_sqlite3.pyd -------------------------------------------------------------------------------- /Release/DLLs/_testcapi.pyd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Toufukun/PyUtau/689c383cf51be52336395e106f392b67f6737502/Release/DLLs/_testcapi.pyd -------------------------------------------------------------------------------- /Release/DLLs/_tkinter.pyd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Toufukun/PyUtau/689c383cf51be52336395e106f392b67f6737502/Release/DLLs/_tkinter.pyd -------------------------------------------------------------------------------- /Release/DLLs/bz2.pyd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Toufukun/PyUtau/689c383cf51be52336395e106f392b67f6737502/Release/DLLs/bz2.pyd -------------------------------------------------------------------------------- /Release/DLLs/py.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Toufukun/PyUtau/689c383cf51be52336395e106f392b67f6737502/Release/DLLs/py.ico -------------------------------------------------------------------------------- /Release/DLLs/pyc.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Toufukun/PyUtau/689c383cf51be52336395e106f392b67f6737502/Release/DLLs/pyc.ico -------------------------------------------------------------------------------- /Release/DLLs/pyexpat.pyd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Toufukun/PyUtau/689c383cf51be52336395e106f392b67f6737502/Release/DLLs/pyexpat.pyd -------------------------------------------------------------------------------- /Release/DLLs/select.pyd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Toufukun/PyUtau/689c383cf51be52336395e106f392b67f6737502/Release/DLLs/select.pyd -------------------------------------------------------------------------------- /Release/DLLs/sqlite3.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Toufukun/PyUtau/689c383cf51be52336395e106f392b67f6737502/Release/DLLs/sqlite3.dll -------------------------------------------------------------------------------- /Release/DLLs/tcl85.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Toufukun/PyUtau/689c383cf51be52336395e106f392b67f6737502/Release/DLLs/tcl85.dll -------------------------------------------------------------------------------- /Release/DLLs/tclpip85.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Toufukun/PyUtau/689c383cf51be52336395e106f392b67f6737502/Release/DLLs/tclpip85.dll -------------------------------------------------------------------------------- /Release/DLLs/tk85.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Toufukun/PyUtau/689c383cf51be52336395e106f392b67f6737502/Release/DLLs/tk85.dll -------------------------------------------------------------------------------- /Release/DLLs/unicodedata.pyd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Toufukun/PyUtau/689c383cf51be52336395e106f392b67f6737502/Release/DLLs/unicodedata.pyd -------------------------------------------------------------------------------- /Release/DLLs/winsound.pyd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Toufukun/PyUtau/689c383cf51be52336395e106f392b67f6737502/Release/DLLs/winsound.pyd -------------------------------------------------------------------------------- /Release/pysrc/pyuppslink.py: -------------------------------------------------------------------------------- 1 | # PyUtauPlus Synth Engine - Uppslink 2 | # Copyright 2013-2014 Toufukun 3 | 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | from pyutau import * 17 | import sys,locale,os,subprocess 18 | 19 | _system_encoding=locale.getdefaultlocale()[1] 20 | # _system_encoding='cp936' 21 | 22 | def _calc_synth_pos(orig_pos,cons_len,cons_spd_mul,rest_mul,msec_per_beat,pit_time_shift): 23 | # print orig_pos,cons_len,cons_spd_mul,rest_mul,msec_per_beat,pit_time_shift 24 | if orig_pos>cons_len: 25 | return int((cons_len*cons_spd_mul+(orig_pos-cons_len)*rest_mul)/msec_per_beat)-pit_time_shift 26 | else: 27 | return int((orig_pos*cons_spd_mul)/msec_per_beat)-pit_time_shift 28 | 29 | def resample(argv): 30 | dirname,filename = os.path.split(os.path.abspath(argv[0])) 31 | 32 | # settings 33 | verbose=True 34 | write_log=True 35 | dont_delete_temp_file=False 36 | uses_cache=True 37 | pit_blur=3 38 | pit_blur_gate_hz=10 39 | orig_pit_floor=75 40 | orig_pit_ceiling=600 41 | 42 | # constant definition 43 | msec_per_minute=60*1000*1.0 44 | ticks_per_beat=480*1.0 45 | in_pb_max_len=4096 46 | manip_pb_max_len=1024 47 | manip_accuracy=0.005 48 | 49 | # convert arguments 50 | dirname,filename=os.path.split(os.path.abspath(argv[0])) 51 | arg=UtauResamplerArguments(argv[1:]) 52 | arg_hash=''.join([arg["in_wav"],str(arg["head_offset"]),str(arg["cons_len"]),str(arg["tail_offset"])]) 53 | arg_hash='%08x'%(binascii.crc32(arg_hash)&0xffffffff) 54 | 55 | # convert file name into utf8 (for Praat scripting) 56 | in_wav_u=arg["in_wav"].decode(_system_encoding).encode('utf-8') 57 | out_wav_u=arg["out_wav"].decode(_system_encoding).encode('utf-8') 58 | 59 | # create cache folder 60 | if not os.path.exists("$s\\Cache"): 61 | os.mkdir("$s\\Cache") 62 | 63 | # write log 64 | if write_log: # debug 65 | log_output=open(arg["in_wav"]+".log",'a') 66 | log_output.write("Uppslink Log\n\n") 67 | log_output.write("arg: \n") 68 | for (k,v) in arg.arg.items(): 69 | log_output.write("%8s=%s\n" % (k.upper(),v)) 70 | log_output.write("hash "+arg_hash) 71 | 72 | # preprocess the file using sox 73 | dest_vol_db=-3*(20**(1-arg["vol"]/100.0)) 74 | if uses_cache: 75 | new_in_wav="%s\\Cache\\$s.wav" % [dirname,arg_hash] 76 | else: 77 | new_in_wav="%s-2.wav" % arg["in_wav"] 78 | new_in_wav_u=new_in_wav.decode(_system_encoding).encode('utf-8') 79 | if not (uses_cache and os.path.isfile(new_in_wav)): 80 | trim2=arg["tail_offset"]/1000.0 81 | if trim2>=0: 82 | trim2="-"+str(trim2) 83 | else: 84 | trim2=str(-trim2) 85 | sox_command='"%s\\sox.exe" --norm=%.4f "%s" "%s" trim %f %s pad 0 %f' %\ 86 | (dirname,dest_vol_db,arg["in_wav"],new_in_wav, 87 | arg["head_offset"]/1000.0,trim2,arg["dest_dur"]/1000.0) 88 | subprocess.call(sox_command) 89 | 90 | # process the pitch bend array 91 | utau_pb_accuracy=96 92 | full_pb_len=int(arg["dest_dur"]/(msec_per_minute/arg["tempo"])*utau_pb_accuracy) 93 | 94 | in_pb=arg["pb"].get_array()[:] 95 | for i in range(len(in_pb),full_pb_len): 96 | in_pb.append(0) 97 | 98 | pitch_tier_file_name=new_in_wav+".txt" 99 | if not (uses_cache and os.path.isfile(pitch_tier_file_name)): 100 | init_script_file_name=new_in_wav+".init.praat" 101 | output=open(init_script_file_name,'w') 102 | output.write("Read from file... %s\n" % new_in_wav_u + 103 | "select 1\n" + 104 | "To Pitch... %f %d %d\n" % (manip_accuracy,orig_pit_floor,orig_pit_ceiling) + 105 | "Down to PitchTier\n" + 106 | "Save as text file... %s.txt\n" % new_in_wav_u) 107 | output.close() 108 | init_script_file_name_u=init_script_file_name.decode(_system_encoding).encode('utf-8') 109 | subprocess.call('"%s\\praatcon.exe" "%s"' % (dirname,init_script_file_name_u)) 110 | 111 | orig_pit=[] 112 | pit_pos=[] 113 | input=open(pitch_tier_file_name) 114 | input_lines=input.readlines() 115 | input.close 116 | for line in input_lines: 117 | try: 118 | (k,v)=line.split(" = ") 119 | v=v[:-2] 120 | if k==" number": 121 | pit_pos.append(float(v)) 122 | elif k==" value": 123 | orig_pit.append(float(v)) 124 | elif k=="xmax": 125 | orig_dur=float(v)*1000-arg["dest_dur"] 126 | except: 127 | pass 128 | 129 | # avoid violent pitch change (Pitch Blur) 130 | refined_pit=orig_pit[:] 131 | pit_len=len(refined_pit) 132 | for i in range(pit_blur,pit_len-pit_blur): 133 | avg=sum(orig_pit[i-pit_blur:i+pit_blur+1]) 134 | avg0=avg-orig_pit[i] 135 | avg/=(2*pit_blur+1) 136 | avg0/=(2*pit_blur) 137 | if abs(refined_pit[i]-avg0)>pit_blur_gate_hz: 138 | refined_pit[i]=avg0 139 | else: 140 | refined_pit[i]=avg 141 | 142 | semitone=2.0 ** (1.0/12) 143 | cent=2.0 ** (1.0/1200) 144 | dest_base_hz=440*(semitone**(arg["dest_key"].to_midi_key()-69)) 145 | cons_spd_mul=100.0/arg["cons_spd"] 146 | rest_mul=(arg["dest_dur"]-arg["cons_len"]*cons_spd_mul)/(orig_dur-arg["cons_len"]) 147 | msec_per_beat=msec_per_minute/arg["tempo"]/utau_pb_accuracy 148 | pit_time_shift=6 149 | theoreic_pit=[] 150 | for i in range(pit_len): 151 | orig_pos=pit_pos[i]*1000 152 | synth_pos=_calc_synth_pos(orig_pos,arg["cons_len"],cons_spd_mul,rest_mul,msec_per_beat,pit_time_shift) 153 | theoreic_pit.append(dest_base_hz*(cent ** in_pb[min(synth_pos,len(in_pb)-1)])) 154 | 155 | dest_pit=[orig_pit[i]+theoreic_pit[i]-refined_pit[i] for i in range(0,pit_len)] 156 | 157 | synth_script_file_name=new_in_wav+".synth.praat" 158 | output=open(synth_script_file_name,'w') 159 | output.write("Read from file... %s\n" % new_in_wav_u+ 160 | "select 1\n"+ 161 | "To Manipulation... %f %d %d\n"%(manip_accuracy,orig_pit_floor,orig_pit_ceiling)+ 162 | "Extract pitch tier\n"+ 163 | "select 2\n"+ 164 | "Extract duration tier\n"+ 165 | "select 3\n") 166 | for i in range(0,pit_len): 167 | output.write("val[%d]=%f\npos[%d]=%f\n" % (i,dest_pit[i],i,pit_pos[i])) 168 | output.write("Remove points between... 0.0 20.0\n"+ 169 | "for i from 0 to %d\n"%(pit_len-1)+ 170 | " vali = val[i]\n"+ 171 | " posi = pos[i]\n"+ 172 | " Add point... posi vali\n"+ 173 | "endfor\n"+ 174 | "plus 2\n"+ 175 | "Replace pitch tier\n"+ 176 | "select 4\n"+ 177 | "Add point... 0 %f\n"%cons_spd_mul+ 178 | "Add point... %0.2f %f\n"%(arg["cons_len"]/1000.0,cons_spd_mul)+ 179 | "Add point... %0.2f+0.01 %f\n"%(arg["cons_len"]/1000.0,rest_mul)+ 180 | "plus 2\n"+ 181 | "Replace duration tier\n"+ 182 | "select 2\n"+ 183 | "Get resynthesis (overlap-add)\n"+ 184 | "select 5\n"+ 185 | "Save as WAV file... %s\n"%out_wav_u) 186 | output.close() 187 | 188 | synth_script_file_name_u=synth_script_file_name.decode(_system_encoding).encode('utf-8') 189 | subprocess.call('"%s\\praatcon.exe" "%s"' % (dirname,synth_script_file_name_u)) 190 | if not dont_delete_temp_file: 191 | os.remove(new_in_wav) 192 | os.remove(init_script_file_name) 193 | os.remove(synth_script_file_name) 194 | 195 | # write log 196 | if write_log: # debug 197 | log_output.write("PIT: POS ORIGINAL THEOREIC REFINED DEST ORIG_POS\n") 198 | for i in range(pit_len): 199 | orig_pos=pit_pos[i]*1000 200 | synth_pos=_calc_synth_pos(orig_pos,arg["cons_len"],cons_spd_mul,rest_mul,msec_per_beat,pit_time_shift) 201 | log_output.write("%10f %10f %10f %10f %10f %10d\n" % (pit_pos[i],orig_pit[i],theoreic_pit[i],refined_pit[i],dest_pit[i],synth_pos)) 202 | log_output.write("\n") 203 | log_output.write("Cons. Mul=%f Rest Mul=%f\n" % (cons_spd_mul,rest_mul)) 204 | log_output.write("\n") 205 | log_output.close() 206 | 207 | if __name__=="__main__": 208 | resample(sys.argv) 209 | -------------------------------------------------------------------------------- /Release/pysrc/pyutau/__init__.py: -------------------------------------------------------------------------------- 1 | # PyUtau package 2 | # Copyright 2014 Toufukun 3 | 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | from base64pb import UtauBase64PitchBend 17 | from resamplerargs import UtauResamplerArguments 18 | from midikey import MidiKey 19 | __all__=["UtauBase64PitchBend","MidiKey","UtauResamplerArguments"] 20 | -------------------------------------------------------------------------------- /Release/pysrc/pyutau/base64pb.py: -------------------------------------------------------------------------------- 1 | def _bib64_to_int(s): 2 | res = 0 3 | for c in s: 4 | res*=64 5 | if 'A' <= c <= 'Z': 6 | res+=ord(c) - ord('A') 7 | elif 'a' <= c <= 'z': 8 | res+=ord(c) - ord('a') + 26 9 | elif c == '/': 10 | res+=63 11 | elif c == '+': 12 | res+=62 13 | else: 14 | res+=ord(c) - ord('0') + 52 15 | if res & (1 << 11): 16 | res = (res - 1) ^ ((1 << 12) - 1) 17 | res = -res 18 | return res 19 | def _int_to_bib64(x): 20 | s = "" 21 | if (x < 0): 22 | x = -x 23 | x = (x ^ ((1 << 12) - 1)) + 1 24 | a = [int(x / 64),x % 64] 25 | for p in a: 26 | if 0 <= p < 26: 27 | s+=chr(ord('A') + p) 28 | elif p < 52: 29 | s+=chr(ord('a') + p - 26) 30 | elif p == 63: 31 | s+='/' 32 | elif p == 62: 33 | s+='+' 34 | else: 35 | s+=chr(ord('0') + p - 52) 36 | return s 37 | class UtauBase64PitchBend: 38 | def __init__(self,str=""): 39 | self.pba = [] 40 | i = 0 41 | repetition_num = 0 42 | in_sharp = False 43 | buf = "" 44 | while i < len(str): 45 | if str[i] == '#': 46 | if in_sharp: 47 | in_sharp = False 48 | repetition_num-=1 49 | while repetition_num >= 0: 50 | self.pba.append(buf) 51 | repetition_num-=1 52 | else: 53 | in_sharp = True 54 | repetition_num = 0 55 | else: 56 | if in_sharp: 57 | repetition_num*=10 58 | repetition_num+=ord(str[i]) - ord('0') 59 | else: 60 | if isinstance(buf,int): 61 | buf = "" 62 | buf+=str[i] 63 | if len(buf) == 2: 64 | buf = _bib64_to_int(buf) 65 | if i + 1 == len(str) or str[i + 1] != '#': 66 | self.pba.append(buf) 67 | i+=1 68 | def __getitem__(self, index): 69 | if index >= len(self.pba) or index < 0: 70 | return 0 71 | else: 72 | return self.pba[index] 73 | def get_array(self): 74 | return self.pba[:] 75 | def get_base64(self): 76 | if len(self.pba) == 0: 77 | return "" 78 | str = "" 79 | prev = self.pba[0] 80 | cnt = 0 81 | for p in self.pba: 82 | if p != prev: 83 | str+=_int_to_bib64(prev) 84 | if cnt > 1: 85 | str+="#%d#" % cnt 86 | cnt = 1 87 | prev = p 88 | else: 89 | cnt+=1 90 | str+=_int_to_bib64(prev) 91 | if cnt > 1: 92 | str+="#%d#" % cnt 93 | return str 94 | def __str__(self): 95 | return str(self.pba) 96 | 97 | def _test(): 98 | while True: 99 | s = raw_input() 100 | p = UtauBase64PitchBend(s) 101 | print str(p.get_array()), str(p.get_base64()) 102 | 103 | if __name__ == '__main__': 104 | _test() 105 | -------------------------------------------------------------------------------- /Release/pysrc/pyutau/midikey.py: -------------------------------------------------------------------------------- 1 | def _isFlat(s): 2 | for c in s: 3 | if c == 'b' or c == '#': 4 | return False 5 | return True 6 | class MidiKey: 7 | key = 96 8 | def __init__(self,k): 9 | if isinstance(k,int): 10 | self.key = k 11 | elif str.isdigit(k): 12 | self.key = int(k) 13 | else: 14 | Key = [9,11,0,2,4,5,7] 15 | if 'a' <= k[0] <= 'z': 16 | k[0]-=32 17 | if _isFlat(k): 18 | letter = k[0] 19 | octave = int(k[1:]) 20 | self.key = (octave - 5) * 12 + 72 + Key[ord(letter) - ord('A')] 21 | else: 22 | letter = k[0] 23 | tone = k[1] 24 | octave = int(k[2:]) 25 | self.key = (octave - 5) * 12 + 72 + Key[ord(letter) - ord('A')] 26 | if tone == '#': 27 | self.key+=1 28 | else: 29 | self.key-=1 30 | def to_midi_key(self): 31 | return self.key 32 | def to_letter_key(self): 33 | lKey = ["C","C#","D","D#","E","F","F#","G","G#","A","A#","B"] 34 | octave = (self.key - 11) / 12 35 | return "%s%d" % (lKey[self.key % 12],octave) 36 | def __str__(self): 37 | return "%s(%d)" % (self.to_letter_key(),self.key) 38 | 39 | def _test(): 40 | while True: 41 | s = raw_input() 42 | k = MidiKey(s) 43 | print k.to_letter_key(), k.to_midi_key() 44 | 45 | if __name__ == '__main__': 46 | _test() 47 | -------------------------------------------------------------------------------- /Release/pysrc/pyutau/resamplerargs.py: -------------------------------------------------------------------------------- 1 | from base64pb import UtauBase64PitchBend 2 | from midikey import MidiKey 3 | import sys 4 | 5 | class UtauResamplerArguments: 6 | def __init__(self,args=["","","C5","100","","0","0","0","0","100","0"]): 7 | if (not isinstance(args,list)) or (len(args) != 13 and len(args) != 11): 8 | raise Exception("bad utau resampler arguments (len=%d)" % len(args)) 9 | self.arg = {} 10 | arg_name = ["in_wav","out_wav","dest_key","cons_spd","flags", 11 | "head_offset","dest_dur","cons_len","tail_offset", 12 | "vol","mod"] 13 | args[2]=MidiKey(args[2]) 14 | for i in [3] + range(5,10+1): 15 | args[i] = eval(args[i]) 16 | for i in range(11): 17 | self.arg[arg_name[i]] = args[i] 18 | self.orig_len = len(args) 19 | if len(args) > 11: 20 | self.arg["tempo"] = float(args[-2][1:]) 21 | self.arg["base64_pb"] = args[-1] 22 | else: 23 | self.arg["tempo"] = 120.0 24 | self.arg["base64_pb"] = "AA" 25 | self.arg["pb"] = UtauBase64PitchBend(args[-1]) 26 | def __getitem__(self, index): 27 | if not self.arg.has_key(index): 28 | return "" 29 | return self.arg[index] 30 | 31 | def _test(): 32 | arg = UtauResamplerArguments() 33 | print arg.arg 34 | 35 | if __name__ == '__main__': 36 | _test(sys.argv) 37 | -------------------------------------------------------------------------------- /Release/pysrc/pyutauplus.py: -------------------------------------------------------------------------------- 1 | # PyUtauPlus 2 | # Copyright 2014 Toufukun 3 | 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | from pyutau import * 17 | import os,sys,subprocess 18 | 19 | def resampler(argv): 20 | verbose=True 21 | 22 | resampler_list = ["resampler.exe","fresamp.exe","TIPS.exe","pyuppslink"] 23 | arg = UtauResamplerArguments(argv[1:]) 24 | if verbose: 25 | print argv[0] 26 | for k,v in arg.arg.items(): 27 | if k == "pit": 28 | print k,v.get_array() 29 | else: 30 | print k,v 31 | ptr_sel_st = max(arg["flags"].find("\\"),arg["flags"].find("/")) 32 | if ptr_sel_st == -1: 33 | resampler_num = 0 34 | else: 35 | ptr_sel_st+=1 36 | ptr_sel_ed = ptr_sel_st 37 | while ptr_sel_ed < len(arg["flags"]) and arg["flags"][ptr_sel_ed].isdigit(): 38 | ptr_sel_ed+=1 39 | resampler_num = arg["flags"][ptr_sel_st:ptr_sel_ed] 40 | if resampler_num == "": 41 | resampler_num = 0 42 | else: 43 | resampler_num = int(resampler_num) 44 | 45 | if resampler_num > len(resampler_list): 46 | target = "resampler.exe" 47 | else: 48 | target = resampler_list[resampler_num] 49 | 50 | dirname,filename = os.path.split(os.path.abspath(argv[0])) 51 | if target.endswith("exe"): 52 | cmdarg = "" 53 | for x in argv[1:]: 54 | if str(x).find(" ") == -1: 55 | if x == "": 56 | cmdarg+="0 " 57 | else: 58 | cmdarg+=x + " " 59 | else: 60 | cmdarg+='"' + x + '" ' 61 | # print "%s\\%s %s" % (dirname,target,cmdarg) 62 | subprocess.call("%s\\%s %s" % (dirname,target,cmdarg)) 63 | else: 64 | # print target,argv 65 | exec("import %s" % target) 66 | exec("%s.resample(%s)" % (target,argv)) 67 | -------------------------------------------------------------------------------- /Release/pystandalone.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Toufukun/PyUtau/689c383cf51be52336395e106f392b67f6737502/Release/pystandalone.exe -------------------------------------------------------------------------------- /Release/python27.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Toufukun/PyUtau/689c383cf51be52336395e106f392b67f6737502/Release/python27.dll -------------------------------------------------------------------------------- /Release/pythonlib.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Toufukun/PyUtau/689c383cf51be52336395e106f392b67f6737502/Release/pythonlib.zip -------------------------------------------------------------------------------- /Release/pyutauplus_resampler.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Toufukun/PyUtau/689c383cf51be52336395e106f392b67f6737502/Release/pyutauplus_resampler.exe -------------------------------------------------------------------------------- /pystandalone/main.cpp: -------------------------------------------------------------------------------- 1 | #include "pystandalone.h" 2 | using namespace std; 3 | int main(int argc, char * argv[]){ 4 | const char moduleName[] = "main", funcName[] = "main"; 5 | runPython(argc, argv, moduleName, funcName); 6 | return 0; 7 | } 8 | -------------------------------------------------------------------------------- /pystandalone/pystandalone.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Toufukun/PyUtau/689c383cf51be52336395e106f392b67f6737502/pystandalone/pystandalone.cpp -------------------------------------------------------------------------------- /pystandalone/pystandalone.h: -------------------------------------------------------------------------------- 1 | int runPython(int argc, char* argv[], 2 | const char* moduleName, const char* functionName); 3 | -------------------------------------------------------------------------------- /pystandalone/pystandalone.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Debug 10 | x64 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {9FA5C7D9-C526-40A7-9A7E-99B69CAE92FC} 23 | Win32Proj 24 | pystandalone 25 | 26 | 27 | 28 | Application 29 | true 30 | v120 31 | NotSet 32 | 33 | 34 | Application 35 | true 36 | v120 37 | NotSet 38 | 39 | 40 | Application 41 | false 42 | v120 43 | true 44 | NotSet 45 | 46 | 47 | Application 48 | false 49 | v120 50 | true 51 | NotSet 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | true 71 | C:\Python27\include;$(IncludePath) 72 | C:\Python27\libs;$(LibraryPath) 73 | $(Platform)\$(Configuration)\ 74 | 75 | 76 | true 77 | C:\Python27\include;$(IncludePath) 78 | C:\Python27\libs;$(LibraryPath) 79 | $(SolutionDir)$(Configuration)\ 80 | $(Platform)\$(Configuration)\ 81 | 82 | 83 | false 84 | C:\Python27\include;$(IncludePath) 85 | C:\Python27\libs;$(LibraryPath) 86 | $(Platform)\$(Configuration)\ 87 | 88 | 89 | false 90 | C:\Python27\include;$(IncludePath) 91 | C:\Python27\libs;$(LibraryPath) 92 | $(SolutionDir)$(Configuration)\ 93 | $(ProjectName) 94 | $(Platform)\$(Configuration)\ 95 | 96 | 97 | 98 | 99 | 100 | Level3 101 | Disabled 102 | WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 103 | 104 | 105 | Console 106 | true 107 | 108 | 109 | 110 | 111 | 112 | 113 | Level3 114 | Disabled 115 | WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 116 | 117 | 118 | Console 119 | false 120 | 121 | 122 | 123 | 124 | Level3 125 | 126 | 127 | MaxSpeed 128 | true 129 | true 130 | WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 131 | 132 | 133 | Console 134 | true 135 | true 136 | true 137 | C:\Python27\libs\python27.lib;%(AdditionalDependencies) 138 | 139 | 140 | 141 | 142 | Level3 143 | 144 | 145 | MaxSpeed 146 | true 147 | true 148 | WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 149 | MultiThreaded 150 | 151 | 152 | Console 153 | false 154 | true 155 | true 156 | C:\Python27\libs\python27.lib;%(AdditionalDependencies) 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | -------------------------------------------------------------------------------- /pystandalone/pystandalone.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 源文件 20 | 21 | 22 | 源文件 23 | 24 | 25 | 26 | 27 | 头文件 28 | 29 | 30 | -------------------------------------------------------------------------------- /pyutau.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.21005.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{888888A0-9F3D-457C-B088-3A5042F75D52}") = "pyutau", "pyutau\pyutau.pyproj", "{E3532ED2-E154-42DF-A2B7-81D01642729B}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pystandalone", "pystandalone\pystandalone.vcxproj", "{9FA5C7D9-C526-40A7-9A7E-99B69CAE92FC}" 9 | EndProject 10 | Project("{888888A0-9F3D-457C-B088-3A5042F75D52}") = "pyutauplus", "pyutauplus\pyutauplus.pyproj", "{D02A0709-1C16-455B-89EC-7940FB97871E}" 11 | EndProject 12 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pyutauplus_resampler", "pyutauplus_resampler\pyutauplus_resampler.vcxproj", "{6E4A4BCE-E5BF-4CAE-A550-B2D109051363}" 13 | ProjectSection(ProjectDependencies) = postProject 14 | {9FA5C7D9-C526-40A7-9A7E-99B69CAE92FC} = {9FA5C7D9-C526-40A7-9A7E-99B69CAE92FC} 15 | EndProjectSection 16 | EndProject 17 | Global 18 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 19 | Release|Any CPU = Release|Any CPU 20 | Release|x64 = Release|x64 21 | EndGlobalSection 22 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 23 | {E3532ED2-E154-42DF-A2B7-81D01642729B}.Release|Any CPU.ActiveCfg = Release|Any CPU 24 | {E3532ED2-E154-42DF-A2B7-81D01642729B}.Release|Any CPU.Build.0 = Release|Any CPU 25 | {E3532ED2-E154-42DF-A2B7-81D01642729B}.Release|x64.ActiveCfg = Release|Any CPU 26 | {E3532ED2-E154-42DF-A2B7-81D01642729B}.Release|x64.Build.0 = Release|Any CPU 27 | {9FA5C7D9-C526-40A7-9A7E-99B69CAE92FC}.Release|Any CPU.ActiveCfg = Release|Win32 28 | {9FA5C7D9-C526-40A7-9A7E-99B69CAE92FC}.Release|x64.ActiveCfg = Release|x64 29 | {9FA5C7D9-C526-40A7-9A7E-99B69CAE92FC}.Release|x64.Build.0 = Release|x64 30 | {D02A0709-1C16-455B-89EC-7940FB97871E}.Release|Any CPU.ActiveCfg = Release|Any CPU 31 | {D02A0709-1C16-455B-89EC-7940FB97871E}.Release|Any CPU.Build.0 = Release|Any CPU 32 | {D02A0709-1C16-455B-89EC-7940FB97871E}.Release|x64.ActiveCfg = Release|Any CPU 33 | {D02A0709-1C16-455B-89EC-7940FB97871E}.Release|x64.Deploy.0 = Release|Any CPU 34 | {6E4A4BCE-E5BF-4CAE-A550-B2D109051363}.Release|Any CPU.ActiveCfg = Release|Win32 35 | {6E4A4BCE-E5BF-4CAE-A550-B2D109051363}.Release|Any CPU.Build.0 = Release|Win32 36 | {6E4A4BCE-E5BF-4CAE-A550-B2D109051363}.Release|x64.ActiveCfg = Release|x64 37 | {6E4A4BCE-E5BF-4CAE-A550-B2D109051363}.Release|x64.Build.0 = Release|x64 38 | EndGlobalSection 39 | GlobalSection(SolutionProperties) = preSolution 40 | HideSolutionNode = FALSE 41 | EndGlobalSection 42 | EndGlobal 43 | -------------------------------------------------------------------------------- /pyutau/__init__.py: -------------------------------------------------------------------------------- 1 | # PyUtau package 2 | # Copyright 2014 Toufukun 3 | 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | from base64pb import UtauBase64PitchBend 17 | from resamplerargs import UtauResamplerArguments 18 | from midikey import MidiKey 19 | __all__=["UtauBase64PitchBend","MidiKey","UtauResamplerArguments"] 20 | -------------------------------------------------------------------------------- /pyutau/base64pb.py: -------------------------------------------------------------------------------- 1 | def _bib64_to_int(s): 2 | res = 0 3 | for c in s: 4 | res*=64 5 | if 'A' <= c <= 'Z': 6 | res+=ord(c) - ord('A') 7 | elif 'a' <= c <= 'z': 8 | res+=ord(c) - ord('a') + 26 9 | elif c == '/': 10 | res+=63 11 | elif c == '+': 12 | res+=62 13 | else: 14 | res+=ord(c) - ord('0') + 52 15 | if res & (1 << 11): 16 | res = (res - 1) ^ ((1 << 12) - 1) 17 | res = -res 18 | return res 19 | def _int_to_bib64(x): 20 | s = "" 21 | if (x < 0): 22 | x = -x 23 | x = (x ^ ((1 << 12) - 1)) + 1 24 | a = [int(x / 64),x % 64] 25 | for p in a: 26 | if 0 <= p < 26: 27 | s+=chr(ord('A') + p) 28 | elif p < 52: 29 | s+=chr(ord('a') + p - 26) 30 | elif p == 63: 31 | s+='/' 32 | elif p == 62: 33 | s+='+' 34 | else: 35 | s+=chr(ord('0') + p - 52) 36 | return s 37 | class UtauBase64PitchBend: 38 | def __init__(self,str=""): 39 | self.pba = [] 40 | i = 0 41 | repetition_num = 0 42 | in_sharp = False 43 | buf = "" 44 | while i < len(str): 45 | if str[i] == '#': 46 | if in_sharp: 47 | in_sharp = False 48 | repetition_num-=1 49 | while repetition_num >= 0: 50 | self.pba.append(buf) 51 | repetition_num-=1 52 | else: 53 | in_sharp = True 54 | repetition_num = 0 55 | else: 56 | if in_sharp: 57 | repetition_num*=10 58 | repetition_num+=ord(str[i]) - ord('0') 59 | else: 60 | if isinstance(buf,int): 61 | buf = "" 62 | buf+=str[i] 63 | if len(buf) == 2: 64 | buf = _bib64_to_int(buf) 65 | if i + 1 == len(str) or str[i + 1] != '#': 66 | self.pba.append(buf) 67 | i+=1 68 | def __getitem__(self, index): 69 | if index >= len(self.pba) or index < 0: 70 | return 0 71 | else: 72 | return self.pba[index] 73 | def get_array(self): 74 | return self.pba[:] 75 | def get_base64(self): 76 | if len(self.pba) == 0: 77 | return "" 78 | str = "" 79 | prev = self.pba[0] 80 | cnt = 0 81 | for p in self.pba: 82 | if p != prev: 83 | str+=_int_to_bib64(prev) 84 | if cnt > 1: 85 | str+="#%d#" % cnt 86 | cnt = 1 87 | prev = p 88 | else: 89 | cnt+=1 90 | str+=_int_to_bib64(prev) 91 | if cnt > 1: 92 | str+="#%d#" % cnt 93 | return str 94 | def __str__(self): 95 | return str(self.pba) 96 | 97 | def _test(): 98 | while True: 99 | s = raw_input() 100 | p = UtauBase64PitchBend(s) 101 | print str(p.get_array()), str(p.get_base64()) 102 | 103 | if __name__ == '__main__': 104 | _test() 105 | -------------------------------------------------------------------------------- /pyutau/midikey.py: -------------------------------------------------------------------------------- 1 | def _isFlat(s): 2 | for c in s: 3 | if c == 'b' or c == '#': 4 | return False 5 | return True 6 | class MidiKey: 7 | key = 96 8 | def __init__(self,k): 9 | if isinstance(k,int): 10 | self.key = k 11 | elif str.isdigit(k): 12 | self.key = int(k) 13 | else: 14 | Key = [9,11,0,2,4,5,7] 15 | if 'a' <= k[0] <= 'z': 16 | k[0]-=32 17 | if _isFlat(k): 18 | letter = k[0] 19 | octave = int(k[1:]) 20 | self.key = (octave - 5) * 12 + 72 + Key[ord(letter) - ord('A')] 21 | else: 22 | letter = k[0] 23 | tone = k[1] 24 | octave = int(k[2:]) 25 | self.key = (octave - 5) * 12 + 72 + Key[ord(letter) - ord('A')] 26 | if tone == '#': 27 | self.key+=1 28 | else: 29 | self.key-=1 30 | def to_midi_key(self): 31 | return self.key 32 | def to_letter_key(self): 33 | lKey = ["C","C#","D","D#","E","F","F#","G","G#","A","A#","B"] 34 | octave = (self.key - 11) / 12 35 | return "%s%d" % (lKey[self.key % 12],octave) 36 | def __str__(self): 37 | return "%s(%d)" % (self.to_letter_key(),self.key) 38 | 39 | def _test(): 40 | while True: 41 | s = raw_input() 42 | k = MidiKey(s) 43 | print k.to_letter_key(), k.to_midi_key() 44 | 45 | if __name__ == '__main__': 46 | _test() 47 | -------------------------------------------------------------------------------- /pyutau/pyutau.pyproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | 2.0 6 | {e3532ed2-e154-42df-a2b7-81d01642729b} 7 | 8 | 9 | 10 | . 11 | . 12 | 10.0 13 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 14 | $(SolutionDir)Release\pysrc\pyutau 15 | False 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /pyutau/resamplerargs.py: -------------------------------------------------------------------------------- 1 | from base64pb import UtauBase64PitchBend 2 | from midikey import MidiKey 3 | import sys 4 | 5 | class UtauResamplerArguments: 6 | def __init__(self,args=["","","C5","100","","0","0","0","0","100","0"]): 7 | if (not isinstance(args,list)) or (len(args) != 13 and len(args) != 11): 8 | raise Exception("bad utau resampler arguments (len=%d)" % len(args)) 9 | self.arg = {} 10 | arg_name = ["in_wav","out_wav","dest_key","cons_spd","flags", 11 | "head_offset","dest_dur","cons_len","tail_offset", 12 | "vol","mod"] 13 | args[2]=MidiKey(args[2]) 14 | for i in [3] + range(5,10+1): 15 | args[i] = eval(args[i]) 16 | for i in range(11): 17 | self.arg[arg_name[i]] = args[i] 18 | self.orig_len = len(args) 19 | if len(args) > 11: 20 | self.arg["tempo"] = float(args[-2][1:]) 21 | self.arg["base64_pb"] = args[-1] 22 | else: 23 | self.arg["tempo"] = 120.0 24 | self.arg["base64_pb"] = "AA" 25 | self.arg["pb"] = UtauBase64PitchBend(args[-1]) 26 | def __getitem__(self, index): 27 | if not self.arg.has_key(index): 28 | return "" 29 | return self.arg[index] 30 | 31 | def _test(): 32 | arg = UtauResamplerArguments() 33 | print arg.arg 34 | 35 | if __name__ == '__main__': 36 | _test(sys.argv) 37 | -------------------------------------------------------------------------------- /pyutauplus/pyuppslink.py: -------------------------------------------------------------------------------- 1 | from pyutau import * 2 | import sys,locale,os,subprocess 3 | 4 | _system_encoding=locale.getdefaultlocale()[1] 5 | # _system_encoding='cp936' 6 | 7 | def _calc_synth_pos(orig_pos,cons_len,cons_spd_mul,rest_mul,msec_per_beat,pit_time_shift): 8 | # print orig_pos,cons_len,cons_spd_mul,rest_mul,msec_per_beat,pit_time_shift 9 | if orig_pos>cons_len: 10 | return int((cons_len*cons_spd_mul+(orig_pos-cons_len)*rest_mul)/msec_per_beat)-pit_time_shift 11 | else: 12 | return int((orig_pos*cons_spd_mul)/msec_per_beat)-pit_time_shift 13 | 14 | def resample(argv): 15 | dirname,filename = os.path.split(os.path.abspath(argv[0])) 16 | 17 | # constant definition 18 | verbose=True 19 | write_log=True 20 | dont_delete_temp_file=False 21 | pit_blur=3 22 | pit_blur_gate_hz=10 23 | msec_per_minute=60*1000*1.0 24 | ticks_per_beat=480*1.0 25 | in_pb_max_len=4096 26 | manip_pb_max_len=1024 27 | manip_accuracy=0.005 28 | orig_pit_floor=75 29 | orig_pit_ceiling=600 30 | 31 | # convert arguments 32 | dirname,filename=os.path.split(os.path.abspath(argv[0])) 33 | arg=UtauResamplerArguments(argv[1:]) 34 | 35 | # convert file name into utf8 (for Praat scripting) 36 | in_wav_u=arg["in_wav"].decode(_system_encoding).encode('utf-8') 37 | out_wav_u=arg["out_wav"].decode(_system_encoding).encode('utf-8') 38 | 39 | # write log 40 | if write_log: # debug 41 | log_output=open(arg["in_wav"]+".log",'a') 42 | log_output.write("Uppslink Log\n\n") 43 | log_output.write("arg: \n") 44 | for (k,v) in arg.arg.items(): 45 | log_output.write("%8s=%s\n" % (k.upper(),v)) 46 | 47 | # preprocess the file using sox 48 | dest_vol_db=-3*(20**(1-arg["vol"]/100.0)) 49 | new_in_wav="%s-2.wav" % arg["in_wav"] 50 | new_in_wav_u=new_in_wav.decode(_system_encoding).encode('utf-8') 51 | trim2=arg["tail_offset"]/1000.0 52 | if trim2>=0: 53 | trim2="-"+str(trim2) 54 | else: 55 | trim2=str(-trim2) 56 | sox_command='"%s\\sox.exe" --norm=%.4f "%s" "%s" trim %f %s pad 0 %f' %\ 57 | (dirname,dest_vol_db,arg["in_wav"],new_in_wav, 58 | arg["head_offset"]/1000.0,trim2,arg["dest_dur"]/1000.0) 59 | subprocess.call(sox_command) 60 | 61 | # process the pitch bend array 62 | utau_pb_accuracy=96 63 | full_pb_len=int(arg["dest_dur"]/(msec_per_minute/arg["tempo"])*utau_pb_accuracy) 64 | 65 | in_pb=arg["pb"].get_array()[:] 66 | for i in range(len(in_pb),full_pb_len): 67 | in_pb.append(0) 68 | 69 | pitch_tier_file_name=new_in_wav+".txt" 70 | init_script_file_name=new_in_wav+".init.praat" 71 | output=open(init_script_file_name,'w') 72 | output.write("Read from file... %s\n" % new_in_wav_u + 73 | "select 1\n" + 74 | "To Pitch... %f %d %d\n" % (manip_accuracy,orig_pit_floor,orig_pit_ceiling) + 75 | "Down to PitchTier\n" + 76 | "Save as text file... %s.txt\n" % new_in_wav_u) 77 | output.close() 78 | 79 | init_script_file_name_u=init_script_file_name.decode(_system_encoding).encode('utf-8') 80 | subprocess.call('"%s\\praatcon.exe" "%s"' % (dirname,init_script_file_name_u)) 81 | 82 | orig_pit=[] 83 | pit_pos=[] 84 | input=open("%s.txt" % new_in_wav) 85 | input_lines=input.readlines() 86 | input.close 87 | for line in input_lines: 88 | try: 89 | (k,v)=line.split(" = ") 90 | v=v[:-2] 91 | if k==" number": 92 | pit_pos.append(float(v)) 93 | elif k==" value": 94 | orig_pit.append(float(v)) 95 | elif k=="xmax": 96 | orig_dur=float(v)*1000-arg["dest_dur"] 97 | except: 98 | pass 99 | 100 | # avoid violent pitch change (Pitch Blur) 101 | refined_pit=orig_pit[:] 102 | pit_len=len(refined_pit) 103 | for i in range(pit_blur,pit_len-pit_blur): 104 | avg=sum(orig_pit[i-pit_blur:i+pit_blur+1]) 105 | avg0=avg-orig_pit[i] 106 | avg/=(2*pit_blur+1) 107 | avg0/=(2*pit_blur) 108 | if abs(refined_pit[i]-avg0)>pit_blur_gate_hz: 109 | refined_pit[i]=avg0 110 | else: 111 | refined_pit[i]=avg 112 | 113 | semitone=2.0 ** (1.0/12) 114 | cent=2.0 ** (1.0/1200) 115 | dest_base_hz=440*(semitone**(arg["dest_key"].to_midi_key()-69)) 116 | cons_spd_mul=100.0/arg["cons_spd"] 117 | rest_mul=(arg["dest_dur"]-arg["cons_len"]*cons_spd_mul)/(orig_dur-arg["cons_len"]) 118 | msec_per_beat=msec_per_minute/arg["tempo"]/utau_pb_accuracy 119 | pit_time_shift=6 120 | theoreic_pit=[] 121 | for i in range(pit_len): 122 | orig_pos=pit_pos[i]*1000 123 | synth_pos=_calc_synth_pos(orig_pos,arg["cons_len"],cons_spd_mul,rest_mul,msec_per_beat,pit_time_shift) 124 | theoreic_pit.append(dest_base_hz*(cent ** in_pb[min(synth_pos,len(in_pb)-1)])) 125 | 126 | dest_pit=[orig_pit[i]+theoreic_pit[i]-refined_pit[i] for i in range(0,pit_len)] 127 | 128 | synth_script_file_name=new_in_wav+".synth.praat" 129 | output=open(synth_script_file_name,'w') 130 | output.write("Read from file... %s\n" % new_in_wav_u+ 131 | "select 1\n"+ 132 | "To Manipulation... %f %d %d\n"%(manip_accuracy,orig_pit_floor,orig_pit_ceiling)+ 133 | "Extract pitch tier\n"+ 134 | "select 2\n"+ 135 | "Extract duration tier\n"+ 136 | "select 3\n") 137 | for i in range(0,pit_len): 138 | output.write("val[%d]=%f\npos[%d]=%f\n" % (i,dest_pit[i],i,pit_pos[i])) 139 | output.write("Remove points between... 0.0 20.0\n"+ 140 | "for i from 0 to %d\n"%(pit_len-1)+ 141 | " vali = val[i]\n"+ 142 | " posi = pos[i]\n"+ 143 | " Add point... posi vali\n"+ 144 | "endfor\n"+ 145 | "plus 2\n"+ 146 | "Replace pitch tier\n"+ 147 | "select 4\n"+ 148 | "Add point... 0 %f\n"%cons_spd_mul+ 149 | "Add point... %0.2f %f\n"%(arg["cons_len"]/1000.0,cons_spd_mul)+ 150 | "Add point... %0.2f+0.01 %f\n"%(arg["cons_len"]/1000.0,rest_mul)+ 151 | "plus 2\n"+ 152 | "Replace duration tier\n"+ 153 | "select 2\n"+ 154 | "Get resynthesis (overlap-add)\n"+ 155 | "select 5\n"+ 156 | "Save as WAV file... %s\n"%out_wav_u) 157 | output.close() 158 | 159 | synth_script_file_name_u=synth_script_file_name.decode(_system_encoding).encode('utf-8') 160 | subprocess.call('"%s\\praatcon.exe" "%s"' % (dirname,synth_script_file_name_u)) 161 | if not dont_delete_temp_file: 162 | os.remove(new_in_wav) 163 | os.remove(init_script_file_name) 164 | os.remove(synth_script_file_name) 165 | 166 | # write log 167 | if write_log: # debug 168 | log_output.write("PIT: POS ORIGINAL THEOREIC REFINED DEST ORIG_POS\n") 169 | for i in range(pit_len): 170 | orig_pos=pit_pos[i]*1000 171 | synth_pos=_calc_synth_pos(orig_pos,arg["cons_len"],cons_spd_mul,rest_mul,msec_per_beat,pit_time_shift) 172 | log_output.write("%10f %10f %10f %10f %10f %10d\n" % (pit_pos[i],orig_pit[i],theoreic_pit[i],refined_pit[i],dest_pit[i],synth_pos)) 173 | log_output.write("\n") 174 | log_output.write("Cons. Mul=%f Rest Mul=%f\n" % (cons_spd_mul,rest_mul)) 175 | log_output.write("\n") 176 | log_output.close() 177 | 178 | if __name__=="__main__": 179 | resample(sys.argv) 180 | -------------------------------------------------------------------------------- /pyutauplus/pyutauplus.py: -------------------------------------------------------------------------------- 1 | # PyUtauPlus 2 | # Copyright 2014 Toufukun 3 | 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | from pyutau import * 17 | import os,sys,subprocess 18 | 19 | def resampler(argv): 20 | verbose=True 21 | 22 | resampler_list = ["resampler.exe","fresamp.exe","TIPS.exe","pyuppslink"] 23 | arg = UtauResamplerArguments(argv[1:]) 24 | if verbose: 25 | print argv[0] 26 | for k,v in arg.arg.items(): 27 | if k == "pit": 28 | print k,v.get_array() 29 | else: 30 | print k,v 31 | ptr_sel_st = max(arg["flags"].find("\\"),arg["flags"].find("/")) 32 | if ptr_sel_st == -1: 33 | resampler_num = 0 34 | else: 35 | ptr_sel_st+=1 36 | ptr_sel_ed = ptr_sel_st 37 | while ptr_sel_ed < len(arg["flags"]) and arg["flags"][ptr_sel_ed].isdigit(): 38 | ptr_sel_ed+=1 39 | resampler_num = arg["flags"][ptr_sel_st:ptr_sel_ed] 40 | if resampler_num == "": 41 | resampler_num = 0 42 | else: 43 | resampler_num = int(resampler_num) 44 | 45 | if resampler_num > len(resampler_list): 46 | target = "resampler.exe" 47 | else: 48 | target = resampler_list[resampler_num] 49 | 50 | dirname,filename = os.path.split(os.path.abspath(argv[0])) 51 | if target.endswith("exe"): 52 | cmdarg = "" 53 | for x in argv[1:]: 54 | if str(x).find(" ") == -1: 55 | if x == "": 56 | cmdarg+="0 " 57 | else: 58 | cmdarg+=x + " " 59 | else: 60 | cmdarg+='"' + x + '" ' 61 | # print "%s\\%s %s" % (dirname,target,cmdarg) 62 | subprocess.call("%s\\%s %s" % (dirname,target,cmdarg)) 63 | else: 64 | # print target,argv 65 | exec("import %s" % target) 66 | exec("%s.resample(%s)" % (target,argv)) 67 | -------------------------------------------------------------------------------- /pyutauplus/pyutauplus.pyproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | 2.0 6 | {d02a0709-1c16-455b-89ec-7940fb97871e} 7 | 8 | pyutauplus.py 9 | .. 10 | . 11 | . 12 | 10.0 13 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 14 | $(SolutionDir)Release\pysrc 15 | False 16 | False 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /pyutauplus_resampler/main.cpp: -------------------------------------------------------------------------------- 1 | #include "pystandalone.h" 2 | using namespace std; 3 | int main(int argc, char * argv[]){ 4 | const char moduleName[] = "pyutauplus", funcName[] = "resampler"; 5 | runPython(argc, argv, moduleName, funcName); 6 | return 0; 7 | } 8 | 9 | -------------------------------------------------------------------------------- /pyutauplus_resampler/pyutauplus_resampler.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Debug 10 | x64 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {6E4A4BCE-E5BF-4CAE-A550-B2D109051363} 23 | Win32Proj 24 | pystandalone 25 | 26 | 27 | 28 | Application 29 | true 30 | v120 31 | NotSet 32 | 33 | 34 | Application 35 | true 36 | v120 37 | NotSet 38 | 39 | 40 | Application 41 | false 42 | v120 43 | true 44 | NotSet 45 | 46 | 47 | Application 48 | false 49 | v120 50 | true 51 | NotSet 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | true 71 | C:\Python27\include;$(IncludePath) 72 | C:\Python27\libs;$(LibraryPath) 73 | $(Platform)\$(Configuration)\ 74 | 75 | 76 | true 77 | C:\Python27\include;$(IncludePath) 78 | C:\Python27\libs;$(LibraryPath) 79 | $(SolutionDir)$(Configuration)\ 80 | $(Platform)\$(Configuration)\ 81 | 82 | 83 | false 84 | C:\Python27\include;$(IncludePath) 85 | C:\Python27\libs;$(LibraryPath) 86 | $(Platform)\$(Configuration)\ 87 | 88 | 89 | false 90 | C:\Python27\include;$(IncludePath) 91 | C:\Python27\libs;$(LibraryPath) 92 | $(SolutionDir)$(Configuration)\ 93 | $(ProjectName) 94 | $(Platform)\$(Configuration)\ 95 | 96 | 97 | 98 | 99 | 100 | Level3 101 | Disabled 102 | WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 103 | 104 | 105 | Console 106 | true 107 | 108 | 109 | 110 | 111 | 112 | 113 | Level3 114 | Disabled 115 | WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 116 | $(SolutionDir)\pystandalone 117 | 118 | 119 | Console 120 | false 121 | 122 | 123 | 124 | 125 | Level3 126 | 127 | 128 | MaxSpeed 129 | true 130 | true 131 | WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 132 | 133 | 134 | Console 135 | true 136 | true 137 | true 138 | C:\Python27\libs\python27.lib;%(AdditionalDependencies) 139 | 140 | 141 | 142 | 143 | Level3 144 | 145 | 146 | MaxSpeed 147 | true 148 | true 149 | WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 150 | MultiThreaded 151 | $(SolutionDir)\pystandalone 152 | 153 | 154 | Console 155 | false 156 | true 157 | true 158 | C:\Python27\libs\python27.lib;%(AdditionalDependencies) 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | -------------------------------------------------------------------------------- /pyutauplus_resampler/pyutauplus_resampler.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 源文件 20 | 21 | 22 | 源文件 23 | 24 | 25 | --------------------------------------------------------------------------------