public static bool CheckSymbolExists(string symbol, cadencii.utau.UtauVoiceDB db, int note)
        {
            if (symbol == "-" || symbol == "—")
            {
                return(true);
            }
            List <string> OtoNames = new List <string>();

            if (symbol.IndexOf(',') > 0)
            {
                OtoNames.AddRange(symbol.Split(','));
            }
            else
            {
                OtoNames.Add(symbol);
            }
            bool Ret = true;

            foreach (string lyric in OtoNames)
            {
                OtoArgs oa = db.attachFileNameFromLyric(lyric, note);
                if (oa.fileName == null ||
                    (oa.fileName != null && oa.fileName == ""))
                {
                    Ret = false;
                    break;
                }
                else
                {
                    Ret = Ret && System.IO.File.Exists(Path.Combine(db.getVOICEIDSTR(), oa.fileName));
                }
            }
            return(Ret);
        }
Esempio n. 2
0
        /// <summary>
        /// 原音設定ファイルを読み込みます.
        /// </summary>
        /// <param name="oto_ini">原音設定のパス</param>
        private void readOtoIni(string oto_ini, string encoding_name, string db_root_directory)
        {
            // oto.ini読込み
            string dir = Path.GetDirectoryName(oto_ini);
            var encoding = Encoding.GetEncoding(encoding_name);
            using (var sr = new StreamReader(oto_ini, encoding)) {
                while (!sr.EndOfStream) {
                    var line = sr.ReadLine();
                    string[] spl = line.Split('=');
                    if (spl.Length < 2) {
                        continue;
                    }
                    string file_name = spl[0]; // あ.wav
                    string a2 = spl[1]; // ,0,36,64,0,0
                    string a1 = Path.GetFileNameWithoutExtension(file_name);
                    spl = a2.Split(',');
                    if (spl.Length < 6) {
                        continue;
                    }

                    // ファイルがちゃんとあるかどうか?
                    string fullpath = Path.Combine(dir, file_name);
                    if (!File.Exists(fullpath)) {
                        continue;
                    }

                    OtoArgs oa = new OtoArgs();
                    var full_file_name = Path.GetFullPath(Path.Combine(dir, file_name));
                    var full_root_directory = Path.GetFullPath(db_root_directory) + @"\";
                    oa.fileName = full_file_name.StartsWith(full_root_directory) ? full_file_name.Substring(full_root_directory.Length) : file_name;
                    oa.Alias = spl[0];

                    oa.msOffset = parseOrDefault(spl[1]);
                    oa.msConsonant = parseOrDefault(spl[2]);
                    oa.msBlank = parseOrDefault(spl[3]);
                    oa.msPreUtterance = parseOrDefault(spl[4]);
                    oa.msOverlap = parseOrDefault(spl[5]);

                    // 重複登録が無いかチェック
                    if (configs_.All((item) => !item.equals(oa))) {
                        configs_.Add(oa);
                    }
                }
            }
        }
Esempio n. 3
0
    /// <summary>
    /// スクリプトの本体
    /// </summary>
    /// <param name="vsq"></param>
    /// <returns></returns>
    public static ScriptReturnStatus Edit(VsqFileEx vsq)
    {
        int          selected  = AppManager.getSelected();
        VsqTrack     vsq_track = vsq.Track[selected];
        RendererKind kind      = VsqFileEx.getTrackRendererKind(vsq_track);

        if (kind != RendererKind.UTAU)
        {
            return(ScriptReturnStatus.NOT_EDITED);
        }
        bool edited = false;

        foreach (var item in AppManager.itemSelection.getEventIterator())
        {
            VsqEvent original = item.original;
            if (original.ID.type != VsqIDType.Anote)
            {
                continue;
            }
            VsqEvent     singer = vsq_track.getSingerEventAt(original.Clock);
            SingerConfig sc     = AppManager.getSingerInfoUtau(singer.ID.IconHandle.Language, singer.ID.IconHandle.Program);
            if (sc != null && AppManager.mUtauVoiceDB.ContainsKey(sc.VOICEIDSTR))
            {
                string      phrase    = original.ID.LyricHandle.L0.Phrase;
                UtauVoiceDB db        = AppManager.mUtauVoiceDB[sc.VOICEIDSTR];
                int         CheckNote = original.ID.Note;
                if (original.UstEvent != null)
                {
                    CheckNote = original.UstEvent.ReplaceNoteID > 0 ? original.UstEvent.ReplaceNoteID : original.ID.Note;
                }
                OtoArgs  oa      = db.attachFileNameFromLyric(phrase, CheckNote);
                VsqEvent editing = vsq_track.findEventFromID(original.InternalID);
                if (editing.UstEvent == null)
                {
                    editing.UstEvent = new UstEvent();
                }
                editing.UstEvent.setVoiceOverlap(oa.msOverlap);
                editing.UstEvent.setPreUtterance(oa.msPreUtterance);
                edited = true;
            }
        }

        return(edited ? ScriptReturnStatus.EDITED : ScriptReturnStatus.NOT_EDITED);
    }
    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);
            }
        }
    }
        /*private int round5(float X)
         * {
         *  return (int)(Math.Round(X / 5, 0) * 5);
         * }*/
        public void SplitIt()
        {
            dstVibstrBrustEvents.Clear();
            dstPitchBrust.Clear();
            dstParentTable.Clear();
            string PRO = oriEvent.ID.LyricHandle.L0.getPhoneticSymbol();

            if (PRO.IndexOf(',') > 0)
            {
                if (oriEvent.UstEvent.SplitLength > 0)
                {
                    int Len1      = 0;
                    int Len2      = 0;
                    int SplitTime = 0;
                    Len2 = (int)oriEvent.UstEvent.SplitLength;
                    Len1 = oriEvent.ID.getLength() - Len2;

                    /*if (oriEvent.UstEvent.SplitisPercent)
                     * {
                     *  Len2 = (int)(oriEvent.ID.getLength() * (oriEvent.UstEvent.SplitLength / 100.0));
                     *  Len1 = oriEvent.ID.getLength() - Len2;
                     * }
                     * else
                     * {
                     *  Len2 = (int)oriEvent.UstEvent.SplitLength;
                     *  Len1 = oriEvent.ID.getLength() - Len2;
                     * }
                     * if (Len1 <= 0)
                     * {
                     *  Len1 = oriEvent.ID.getLength() / 2;
                     *  Len2 = oriEvent.ID.getLength() - Len1;
                     * }*/

                    /*int PitchCountStartPoint=(int)Math.Round(oriEvent.Clock-oriEvent.UstEvent.getPreUtterance(),0);
                     * Len1 = Cell5(PitchCountStartPoint + Len1) - PitchCountStartPoint;
                     * Len2 = oriEvent.ID.getLength() - Len1;
                     * SplitTime=(Len1 + oriEvent.Clock);
                     */

                    OtoArgs oa = new OtoArgs();
                    if (vdb != null)
                    {
                        int CheckNote = oriEvent.ID.Note;
                        if (oriEvent.UstEvent != null)
                        {
                            CheckNote = oriEvent.UstEvent.ReplaceNoteID > 0 ? oriEvent.UstEvent.ReplaceNoteID : oriEvent.ID.Note;
                        }
                        oa = vdb.attachFileNameFromLyric(PRO.Split(',')[1], CheckNote);
                    }
                    if (oa.fileName == null ||
                        (oa.fileName != null && oa.fileName == ""))
                    {
                        oriEvent.ID.LyricHandle.L0.setPhoneticSymbol(PRO.Split(',')[0]);
                        //oriEvent.UstEvent.setVoiceOverlap(oriEvent.UstEvent.getVoiceOverlap() + preover);
                        dstVibstrBrustEvents.Add(oriEvent, oriVibstrBrustEvents);
                        dstPitchBrust.Add(oriEvent, oriPitchBrust);
                        dstParentTable.Add(oriEvent, oriEvent);
                        return;
                    }
                    int SplitLen = (int)oriEvent.UstEvent.SplitLength;
                    if (oriEvent.UstEvent.SplitisPercent)
                    {
                        SplitLen = (int)(oriEvent.ID.getLength() * SplitLen / 100.0);
                    }

                    float V2PreUttr   = oa.msPreUtterance + oriEvent.UstEvent.SplitSTP;
                    float V1PreUttr   = oriEvent.UstEvent.getPreUtterance() + oriEvent.UstEvent.getStartPoint();
                    int   RealV1Start = (int)mVsq.getClockFromSec(mVsq.getSecFromClock(oriEvent.Clock) - V1PreUttr / 1000.0);
                    int   RealV2Start = (int)mVsq.getClockFromSec(mVsq.getSecFromClock(oriEvent.Clock + Len1) - V2PreUttr / 1000.0);
                    int   R           = Cell5(RealV2Start - RealV1Start);
                    int   Dert        = (RealV2Start - RealV1Start) - R;
                    if (Dert > 3)
                    {
                        Len1 = Len1 + ((5 - Dert) > 0 ? (5 - Dert) : 0);
                    }
                    else
                    {
                        Len1 = Len1 - Dert;
                    }
                    Len2      = oriEvent.ID.getLength() - Len1;
                    SplitTime = (Len1 + oriEvent.Clock);
                    int CrossLen = (int)((oa.msOverlap) + oriEvent.UstEvent.SplitVoiceOverlap);


                    VsqEvent V1 = (VsqEvent)oriEvent.clone();
                    V1.ID.LyricHandle.L0.setPhoneticSymbol(PRO.Split(',')[0]);
                    V1.Clock = oriEvent.Clock;
                    V1.ID.setLength(Len1);
                    V1.UstEvent.setVoiceOverlap(V1.UstEvent.getVoiceOverlap() + V1.UstEvent.NotePreOverlap);
                    UstEnvelope env = oriEvent.UstEvent.getEnvelope();
                    if (env == null)
                    {
                        env = new UstEnvelope();
                    }
                    env.p3 = CrossLen;
                    env.p4 = 0;
                    env.v4 = 0;
                    V1.UstEvent.setEnvelope(env);

                    VsqEvent V2 = (VsqEvent)oriEvent.clone();
                    V2.ID.LyricHandle.L0.setPhoneticSymbol(PRO.Split(',')[1]);
                    V2.Clock = SplitTime;
                    V2.ID.setLength(Len2);
                    V2.UstEvent.setVoiceOverlap(CrossLen);
                    V2.UstEvent.setPreUtterance(oa.msPreUtterance);
                    V2.UstEvent.setStartPoint(V2.UstEvent.SplitSTP);
                    V2.UstEvent.LeftLimit = 0;
                    env = oriEvent.UstEvent.getEnvelope();
                    if (env == null)
                    {
                        env = new UstEnvelope();
                    }
                    env.p2 = CrossLen;
                    env.v2 = env.v2 - V1.UstEvent.MoreOver;
                    if (env.v2 < 0)
                    {
                        env.v2 = 0;
                    }
                    env.p1 = 0;
                    env.v1 = 0;
                    if (env.p5 > 0)
                    {
                        env.p5 = env.p5 - Len1;
                    }
                    V2.UstEvent.setEnvelope(env);


                    dstVibstrBrustEvents.Add(V1, oriVibstrBrustEvents);
                    dstPitchBrust.Add(V1, oriPitchBrust);
                    dstParentTable.Add(V1, oriEvent);
                    dstVibstrBrustEvents.Add(V2, oriVibstrBrustEvents);
                    dstPitchBrust.Add(V2, oriPitchBrust);
                    dstParentTable.Add(V2, oriEvent);
                }
                else
                {
                    if (oriEvent.ID.LyricHandle.L0.getPhoneticSymbol().IndexOf(",") > 0)
                    {
                        oriEvent.ID.LyricHandle.L0.setPhoneticSymbol(PRO.Split(',')[0]);
                    }
                    dstVibstrBrustEvents.Add(oriEvent, oriVibstrBrustEvents);
                    oriEvent.UstEvent.setVoiceOverlap(oriEvent.UstEvent.getVoiceOverlap() + oriEvent.UstEvent.NotePreOverlap);
                    dstPitchBrust.Add(oriEvent, oriPitchBrust);
                    dstParentTable.Add(oriEvent, oriEvent);
                }
            }
            else
            {
                dstVibstrBrustEvents.Add(oriEvent, oriVibstrBrustEvents);
                oriEvent.UstEvent.setVoiceOverlap(oriEvent.UstEvent.getVoiceOverlap() + oriEvent.UstEvent.NotePreOverlap);
                dstPitchBrust.Add(oriEvent, oriPitchBrust);
                dstParentTable.Add(oriEvent, oriEvent);
            }
        }
Esempio n. 6
0
    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;
            }
        }
    }