public static bool Edit( VsqFile vsq ) {
using ( RenderAsUtau dlg = new RenderAsUtau() ) {
if ( dlg.ShowDialog() == DialogResult.OK ) {
Singer = dlg.txtSinger.Text;
Resampler = dlg.txtResampler.Text;
WavTool = dlg.txtWavtool.Text;
string script = Path.Combine( Application.StartupPath, Path.Combine( "script", "Render As UTAU.cs" ) );//Script.ScriptPath;
string temp_dir = Path.Combine( Path.GetDirectoryName( script ), Path.GetFileNameWithoutExtension( script ) );
#if DEBUG
if ( !Directory.Exists( temp_dir ) ) {
Directory.CreateDirectory( temp_dir );
}
StreamWriter sw = new StreamWriter( Path.Combine( temp_dir, "log.txt" ) );
#endif
// 原音設定を読み込み
Dictionary<string, OtoArgs> config = new Dictionary<string, OtoArgs>();
string singer_name = Path.GetFileName( Singer );
string config_file = Path.Combine( Singer, "oto.ini" );
#if DEBUG
sw.WriteLine( "Singer=" + Singer );
sw.WriteLine( "singer_name=" + singer_name );
sw.WriteLine( "config_file=" + config_file );
#endif
if ( File.Exists( config_file ) ) {
using ( cp932reader sr = new cp932reader( config_file ) ) {
string line;
while ( sr.Peek() >= 0 ) {
try {
line = sr.ReadLine();
String[] spl = line.Split( '=' );
String file_name = spl[0]; // あ.wav
String a2 = spl[1]; // ,0,36,64,0,0
String a1 = Path.GetFileNameWithoutExtension( file_name );
spl = a2.Split( ',' );
OtoArgs oa = new OtoArgs();
oa.Alias = spl[0];
oa.msOffset = int.Parse( spl[1] );
oa.msConsonant = int.Parse( spl[2] );
oa.msBlank = int.Parse( spl[3] );
oa.msPreUtterance = int.Parse( spl[4] );
oa.msOverwrap = int.Parse( spl[5] );
config.Add( a1, oa );
} catch {
}
}
}
}
int track = AppManager.getSelected();
List<Phon> phons = new List<Phon>();
if ( !Directory.Exists( temp_dir ) ) {
Directory.CreateDirectory( temp_dir );
}
int count = -1;
double sec_end = 0;
double sec_end_old = 0;
for ( Iterator<VsqEvent> itr = vsq.Track.get( track ).getNoteEventIterator(); itr.hasNext(); ) {
VsqEvent item = itr.next();
count++;
double sec_start = vsq.getSecFromClock( item.Clock );
sec_end_old = sec_end;
sec_end = vsq.getSecFromClock( item.Clock + item.ID.Length );
float t_temp = (float)(item.ID.Length / (sec_end - sec_start) / 8.0);
if ( (count == 0 && sec_start > 0.0) || (sec_start > sec_end_old) ) {
double sec_start2 = sec_end_old;
double sec_end2 = sec_start;
float t_temp2 = (float)(item.Clock / (sec_end2 - sec_start2) / 8.0);
phons.Add( new Phon( "R", Path.Combine( Singer, "R.wav" ), item.Clock, t_temp2, true ) );
count++;
}
string lyric = item.ID.LyricHandle.L0.Phrase;
string note = NoteStringFromNoteNumber( item.ID.Note );
#if DEBUG
sw.WriteLine( "note=" + note );
#endif
string millisec = ((int)((sec_end - sec_start) * 1000) + 50).ToString();
//4_あ_C#4_550.wav
string filename = Path.Combine( temp_dir, count + "_" + item.ID.Note + "_" + millisec + ".wav" );
#if DEBUG
sw.WriteLine( "filename=" + filename );
sw.WriteLine();
#endif
if ( File.Exists( filename ) ) {
PortUtil.deleteFile( filename );
}
phons.Add( new Phon( lyric, filename, item.ID.Length, t_temp, false ) );
OtoArgs oa = new OtoArgs();
if ( config.ContainsKey( lyric ) ) {
oa = config[lyric];
}
int velocity = 100;
int moduration = 100;
string flags = "L";
int time_percent = 100;
// C4 100 L 0 550 0 0 100 100
string arg = "\"" + Path.Combine( Singer, lyric + ".wav" ) + "\" \"" + filename + "\" \"" + note + "\" " + time_percent + " " + flags + " " + oa.msOffset + " " + millisec + " " + oa.msConsonant + " " + oa.msBlank + " " + velocity + " " + moduration;
using ( System.Diagnostics.Process p = new System.Diagnostics.Process() ) {
p.StartInfo.FileName = (InvokeWithWine ? "wine \"" : "\"") + Resampler + "\"";
p.StartInfo.Arguments = arg;
p.StartInfo.WorkingDirectory = temp_dir;
p.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
p.Start();
p.WaitForExit();
}
}
#if DEBUG
sw.Close();
#endif
string filebase = "temp.wav";
string file = Path.Combine( temp_dir, filebase );
if ( File.Exists( file ) ) {
PortUtil.deleteFile( file );
}
string file_whd = Path.Combine( temp_dir, filebase + ".whd" );
if ( File.Exists( file_whd ) ) {
PortUtil.deleteFile( file_whd );
}
string file_dat = Path.Combine( temp_dir, filebase + ".dat" );
if ( File.Exists( file_dat ) ) {
PortUtil.deleteFile( file_dat );
}
// wavtoolを呼び出す
for ( int i = 0; i < phons.Count; i++ ) {
OtoArgs oa = new OtoArgs();
if ( config.ContainsKey( phons[i].Lyric ) ) {
oa = config[phons[i].Lyric];
}
// 次の音符の先行発声とオーバーラップを取得
OtoArgs oa_next = new OtoArgs();
if ( i + 1 < phons.Count ) {
if ( config.ContainsKey( phons[i + 1].Lyric ) ) {
oa_next = config[phons[i + 1].Lyric];
}
}
int mten = oa.msPreUtterance + oa_next.msOverwrap - oa_next.msPreUtterance;
string arg = filebase + " \"" + phons[i].FileName + "\" 0 " + phons[i].ClockLength + "@" + string.Format( "{0:f2}", phons[i].Tempo ) + mten.ToString( "+#;-#;0" );
if ( phons[i].ModeR ) {
arg += " 0 0";
} else {
arg += " 0 5 35 0 100 100 100 " + oa.msOverwrap; // エンベロープ
}
using ( System.Diagnostics.Process p = new System.Diagnostics.Process() ) {
p.StartInfo.FileName = (InvokeWithWine ? "wine \"" : "\"") + WavTool + "\"";
p.StartInfo.Arguments = arg;
p.StartInfo.WorkingDirectory = temp_dir;
p.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
p.Start();
p.WaitForExit();
}
}
// 波形とヘッダを結合
using ( FileStream fs = new FileStream( file, FileMode.Create ) ) {
string[] files = new string[] { file_whd, file_dat };
int buflen = 512;
byte[] buff = new byte[buflen];
for ( int i = 0; i < files.Length; i++ ) {
using ( FileStream fs2 = new FileStream( files[i], FileMode.Open ) ) {
int len = fs2.Read( buff, 0, buflen );
while ( len > 0 ) {
fs.Write( buff, 0, len );
len = fs2.Read( buff, 0, buflen );
}
}
}
}
// 後片付け
foreach ( Phon ph in phons ) {
if ( !ph.ModeR ) {
if ( File.Exists( ph.FileName ) ) {
PortUtil.deleteFile( ph.FileName );
}
}
}
if ( File.Exists( file_whd ) ) {
PortUtil.deleteFile( file_whd );
}
if ( File.Exists( file_dat ) ) {
PortUtil.deleteFile( file_dat );
}
if ( saveFileDialog.ShowDialog() == DialogResult.OK ) {
if ( File.Exists( saveFileDialog.FileName ) ) {
PortUtil.deleteFile( saveFileDialog.FileName );
}
LastWave = saveFileDialog.FileName;
PortUtil.moveFile( file, saveFileDialog.FileName );
} else {
PortUtil.deleteFile( file );
}
return true;
} else {
return false;
}
}
}