public string toString() { string ret = "{Type=" + type; if (type == VsqIDType.Anote) { ret += ", Length=" + getLength(); ret += ", Note#=" + Note; ret += ", Dynamics=" + Dynamics; ret += ", PMBendDepth=" + PMBendDepth; ret += ", PMBendLength=" + PMBendLength; ret += ", PMbPortamentoUse=" + PMbPortamentoUse; ret += ", DEMdecGainRate=" + DEMdecGainRate; ret += ", DEMaccent=" + DEMaccent; if (LyricHandle != null) { ret += ", LyricHandle=h#" + PortUtil.formatDecimal("0000", LyricHandle_index); } if (VibratoHandle != null) { ret += ", VibratoHandle=h#" + PortUtil.formatDecimal("0000", VibratoHandle_index); ret += ", VibratoDelay=" + VibratoDelay; } } else if (type == VsqIDType.Singer) { ret += ", IconHandle=h#" + PortUtil.formatDecimal("0000", IconHandle_index); } ret += "}"; return(ret); }
private List <VsqHandle> writeEventListCor(ITextWriter writer, int eos) { List <VsqHandle> handles = buildHandleList(); writer.writeLine("[EventList]"); List <VsqEvent> temp = new List <VsqEvent>(); foreach (var @event in Events.iterator()) { temp.Add(@event); } temp.Sort(); int i = 0; while (i < temp.Count) { VsqEvent item = temp[i]; if (!item.ID.Equals(VsqID.EOS)) { string ids = "ID#" + PortUtil.formatDecimal("0000", item.ID.value); int clock = temp[i].Clock; while (i + 1 < temp.Count && clock == temp[i + 1].Clock) { i++; ids += ",ID#" + PortUtil.formatDecimal("0000", temp[i].ID.value); } writer.writeLine(clock + "=" + ids); } i++; } writer.writeLine(eos + "=EOS"); return(handles); }
/// <summary> /// このインスタンスを文字列に変換します /// </summary> /// <param name="add_quatation_mark">クォーテーションマークを付けるかどうか</param> /// <returns>変換後の文字列</returns> public string toString(bool add_quatation_mark) { string quot = (add_quatation_mark ? "\"" : ""); string result; string phrase = (this.Phrase == null) ? "" : this.Phrase.Replace("\"", "\"\""); result = quot + phrase + quot + ","; List <string> symbol = getPhoneticSymbolList(); string strSymbol = getPhoneticSymbol(); if (!add_quatation_mark) { if (strSymbol == null || (strSymbol != null && strSymbol == "")) { strSymbol = "u:"; } } result += quot + strSymbol + quot + "," + PortUtil.formatDecimal("0.000000", UnknownFloat); result = result.Replace("\\" + "\\", "\\"); if (mConsonantAdjustments == null) { mConsonantAdjustments = new List <int>(); for (int i = 0; i < symbol.Count; i++) { mConsonantAdjustments.Add(VsqPhoneticSymbol.isConsonant(symbol[i]) ? 64 : 0); } } for (int i = 0; i < mConsonantAdjustments.Count; i++) { result += "," + mConsonantAdjustments[i]; } if (PhoneticSymbolProtected) { result += ",1"; } else { result += ",0"; } return(result); }
private void writeCor(ITextWriter writer, List <string> print_targets) { writer.writeLine("[ID#" + PortUtil.formatDecimal("0000", ID.value) + "]"); writer.writeLine("Type=" + ID.type); if (ID.type == VsqIDType.Anote) { if (print_targets.Contains("Length")) { writer.writeLine("Length=" + ID.getLength()); } if (print_targets.Contains("Note#")) { writer.writeLine("Note#=" + ID.Note); } if (print_targets.Contains("Dynamics")) { writer.writeLine("Dynamics=" + ID.Dynamics); } if (print_targets.Contains("PMBendDepth")) { writer.writeLine("PMBendDepth=" + ID.PMBendDepth); } if (print_targets.Contains("PMBendLength")) { writer.writeLine("PMBendLength=" + ID.PMBendLength); } if (print_targets.Contains("PMbPortamentoUse")) { writer.writeLine("PMbPortamentoUse=" + ID.PMbPortamentoUse); } if (print_targets.Contains("DEMdecGainRate")) { writer.writeLine("DEMdecGainRate=" + ID.DEMdecGainRate); } if (print_targets.Contains("DEMaccent")) { writer.writeLine("DEMaccent=" + ID.DEMaccent); } if (print_targets.Contains("PreUtterance")) { writer.writeLine("PreUtterance=" + UstEvent.getPreUtterance()); } if (print_targets.Contains("VoiceOverlap")) { writer.writeLine("VoiceOverlap=" + UstEvent.getVoiceOverlap()); } if (ID.LyricHandle != null) { writer.writeLine("LyricHandle=h#" + PortUtil.formatDecimal("0000", ID.LyricHandle_index)); } if (ID.VibratoHandle != null) { writer.writeLine("VibratoHandle=h#" + PortUtil.formatDecimal("0000", ID.VibratoHandle_index)); writer.writeLine("VibratoDelay=" + ID.VibratoDelay); } if (ID.NoteHeadHandle != null) { writer.writeLine("NoteHeadHandle=h#" + PortUtil.formatDecimal("0000", ID.NoteHeadHandle_index)); } } else if (ID.type == VsqIDType.Singer) { writer.writeLine("IconHandle=h#" + PortUtil.formatDecimal("0000", ID.IconHandle_index)); } else if (ID.type == VsqIDType.Aicon) { writer.writeLine("IconHandle=h#" + PortUtil.formatDecimal("0000", ID.IconHandle_index)); writer.writeLine("Note#=" + ID.Note); } }
public void print(ITextWriter sw) { if (this.Index == UstFile.PREV_INDEX) { sw.write("[#PREV]"); sw.newLine(); } else if (this.Index == UstFile.NEXT_INDEX) { sw.write("[#NEXT]"); sw.newLine(); } else { sw.write("[#" + PortUtil.formatDecimal("0000", Index) + "]"); sw.newLine(); } if (isLengthSpecified()) { sw.write("Length=" + mLength); sw.newLine(); } if (isLyricSpecified()) { sw.write("Lyric=" + getLyric()); sw.newLine(); } if (isNoteSpecified()) { sw.write("NoteNum=" + getNote()); sw.newLine(); } if (isIntensitySpecified()) { sw.write("Intensity=" + getIntensity()); sw.newLine(); } if (isPitchesSpecified() && mPitches != null) { sw.write("PBType=" + getPBType()); sw.newLine(); sw.write("Piches="); for (int i = 0; i < mPitches.Length; i++) { if (i == 0) { sw.write(mPitches[i] + ""); } else { sw.write("," + mPitches[i]); } } sw.newLine(); } if (isTempoSpecified()) { sw.write("Tempo=" + getTempo()); sw.newLine(); } if (isVibratoSpecified() && mVibrato != null) { sw.write(mVibrato.ToString()); sw.newLine(); } if (isPortamentoSpecified() && mPortamento != null) { mPortamento.print(sw); } if (isPreUtteranceSpecified()) { sw.write("PreUtterance=" + getPreUtterance()); sw.newLine(); } if (isVoiceOverlapSpecified()) { sw.write("VoiceOverlap=" + getVoiceOverlap()); sw.newLine(); } if (isEnvelopeSpecified() && mEnvelope != null) { sw.write(mEnvelope.ToString()); sw.newLine(); } if (Flags != "") { sw.write("Flags=" + Flags); sw.newLine(); } if (isModurationSpecified()) { sw.write("Moduration=" + getModuration()); sw.newLine(); } if (isStartPointSpecified()) { sw.write("StartPoint=" + getStartPoint()); sw.newLine(); } if (Properties != null) { int size = Properties.Count; for (int i = 0; i < size; i++) { UstEventProperty itemi = Properties[i]; sw.write(itemi.Name + "=" + itemi.Value); sw.newLine(); } } }
/// <summary> /// vsqの指定したトラックを元に,トラックを1つだけ持つustを構築します /// </summary> /// <param name="vsq"></param> /// <param name="track_index"></param> /// <param name="id_map">UstEventのIndexフィールドと、元になったVsqEventのInternalIDを対応付けるマップ。キーがIndex、値がInternalIDを表す</param> public UstFile(VsqFile vsq, int track_index, SortedDictionary <int, int> id_map) { VsqFile work = (VsqFile)vsq.clone(); //work.removePart( 0, work.getPreMeasureClocks() ); VsqTrack vsq_track = work.Track[track_index]; // デフォルトのテンポ if (work.TempoTable.Count <= 0) { m_tempo = 120.0f; } else { m_tempo = (float)(60e6 / (double)work.TempoTable[0].Tempo); } m_tempo_table = new List <TempoTableEntry>(); m_tempo_table.Clear(); // ustには、テンポチェンジを音符の先頭にしか入れられない // あとで音符に反映させるためのテンプレートを作っておく TempoVector tempo = new TempoVector(); int last_clock = 0; int itempo = (int)(60e6 / m_tempo); foreach (var item in vsq_track.getNoteEventIterator()) { if (last_clock < item.Clock) { // 休符Rの分 tempo.Add(new TempoTableEntry(last_clock, itempo, work.getSecFromClock(last_clock))); } tempo.Add(new TempoTableEntry(item.Clock, itempo, work.getSecFromClock(item.Clock))); last_clock = item.Clock + item.ID.getLength(); } if (tempo.Count == 0) { tempo.Add(new TempoTableEntry(0, (int)(60e6 / m_tempo), 0.0)); } // tempoの中の各要素の時刻が、vsq.TempoTableから計算した時刻と合致するよう調節 #if DEBUG sout.println("UstFile#.ctor; before; list="); for (int i = 0; i < tempo.Count; i++) { TempoTableEntry item = tempo[i]; sout.println(" #" + i + "; c" + item.Clock + "; T" + item.Tempo + "; t" + (60e6 / item.Tempo) + "; sec" + item.Time); } #endif TempoTableEntry prev = tempo[0]; for (int i = 1; i < tempo.Count; i++) { TempoTableEntry item = tempo[i]; double sec = item.Time - prev.Time; int delta = item.Clock - prev.Clock; // deltaクロックでsecを表現するにはテンポをいくらにすればいいか? int draft = (int)(480.0 * sec * 1e6 / (double)delta); // 丸め誤差が入るので、Timeを更新 // ustに実際に記録されるテンポはいくらか? float act_tempo = (float)double.Parse(PortUtil.formatDecimal("0.00", 60e6 / draft)); int i_act_tempo = (int)(60e6 / act_tempo); prev.Tempo = i_act_tempo; item.Time = prev.Time + 1e-6 * delta * prev.Tempo / 480.0; prev = item; } #if DEBUG sout.println("UstFile#.ctor; after; list="); for (int i = 0; i < tempo.Count; i++) { TempoTableEntry item = tempo[i]; sout.println(" #" + i + "; c" + item.Clock + "; T" + item.Tempo + "; t" + (60e6 / item.Tempo) + "; sec" + item.Time); } sout.println("UstFile#.ctor; vsq.TempoTable="); for (int i = 0; i < work.TempoTable.Count; i++) { TempoTableEntry item = work.TempoTable[i]; sout.println(" #" + i + "; c" + item.Clock + "; T" + item.Tempo + "; t" + (60e6 / item.Tempo) + "; sec" + item.Time); } #endif // R用音符のテンプレート int PBTYPE = 5; UstEvent template = new UstEvent(); template.setLyric("R"); template.setNote(60); template.setPreUtterance(0); template.setVoiceOverlap(0); template.setIntensity(100); template.setModuration(0); // 再生秒時をとりあえず無視して,ゲートタイム基準で音符を追加 UstTrack track_add = new UstTrack(); last_clock = 0; int index = 0; foreach (var item in vsq_track.getNoteEventIterator()) { if (last_clock < item.Clock) { // ゲートタイム差あり,Rを追加 UstEvent itemust = (UstEvent)template.clone(); itemust.setLength(item.Clock - last_clock); itemust.Index = index; index++; id_map[itemust.Index] = -1; track_add.addEvent(itemust); } UstEvent item_add = (UstEvent)item.UstEvent.clone(); item_add.setLength(item.ID.getLength()); item_add.setLyric(item.ID.LyricHandle.L0.Phrase); item_add.setNote(item.ID.Note); item_add.Index = index; id_map[item_add.Index] = item.InternalID; if (item.UstEvent.getEnvelope() != null) { item_add.setEnvelope((UstEnvelope)item.UstEvent.getEnvelope().clone()); } index++; track_add.addEvent(item_add); last_clock = item.Clock + item.ID.getLength(); } // テンポを格納(イベント数はあっているはず) if (track_add.getEventCount() > 0) { int size = track_add.getEventCount(); int lasttempo = -1; // ありえない値にしておく for (int i = 0; i < size; i++) { TempoTableEntry item = tempo[i]; if (lasttempo != item.Tempo) { // テンポ値が変わっているもののみ追加 UstEvent ue = track_add.getEvent(i); ue.setTempo((float)(60e6 / item.Tempo)); lasttempo = item.Tempo; m_tempo_table.Add(item); } } } else { // tempoはどうせ破棄されるのでクローンしなくていい m_tempo_table.Add(tempo[0]); } // ピッチを反映 // まず絶対ピッチを取得 VsqBPList abs_pit = new VsqBPList("", 600000, 0, 1280000); VsqBPList cpit = vsq_track.getCurve("pit"); int clock = 0; int search_indx = 0; int pit_size = cpit.size(); foreach (var item in track_add.getNoteEventIterator()) { int c = clock; int len = item.getLength(); clock += len; if (item.getLyric() == "R") { continue; } // 音符の先頭のpitは必ず入れる abs_pit.add(c, (int)(item.getNote() * 10000 + vsq_track.getPitchAt(c) * 100)); // c~c+lenまで for (int i = search_indx; i < pit_size; i++) { int c2 = cpit.getKeyClock(i); if (c < c2 && c2 < clock) { abs_pit.add(c2, (int)(item.getNote() * 10000 + vsq_track.getPitchAt(c2) * 100)); search_indx = i; } else if (clock <= c2) { break; } } } // ピッチをピッチベンドに変換しながら反映 clock = 0; foreach (var item in track_add.getNoteEventIterator()) { double sec_at_clock = tempo.getSecFromClock(clock); double sec_pre = item.getPreUtterance() / 1000.0; double sec_stp = item.getStartPoint() / 1000.0; double sec_at_begin = sec_at_clock - sec_pre - sec_stp; int clock_begin = (int)tempo.getClockFromSec(sec_at_begin); // 音符先頭との距離がPBTYPEの倍数になるようにする clock_begin -= (clock < clock_begin) ? ((clock_begin - clock) % PBTYPE) : ((clock - clock_begin) % PBTYPE); // clock_beginがsec_at_beginより前方になるとNGなので修正する double sec_at_clock_begin = tempo.getSecFromClock(clock_begin); while (sec_at_clock_begin < sec_at_begin) { clock_begin += PBTYPE; sec_at_clock_begin = tempo.getSecFromClock(clock_begin); } int clock_end = clock + item.getLength(); List <float> pitch = new List <float>(); bool allzero = true; ByRef <int> ref_indx = new ByRef <int>(0); for (int cl = clock_begin; cl < clock_end; cl += PBTYPE) { int abs = abs_pit.getValue(cl, ref_indx); float pit = (float)(abs / 100.0) - item.getNote() * 100; if (pit != 0.0) { allzero = false; } pitch.Add(pit); } if (!allzero) { item.setPitches(PortUtil.convertFloatArray(pitch.ToArray())); item.setPBType(PBTYPE); } else { item.setPBType(-1); } clock += item.getLength(); } m_tracks.Add(track_add); }
/// <summary> /// インスタンスを文字列に変換します /// </summary> /// <returns>インスタンスを変換した文字列</returns> public string toString() { string result = ""; result += "[h#" + PortUtil.formatDecimal("0000", Index) + "]"; if (m_type == VsqHandleType.Lyric) { result += "\n" + "L0=" + L0.toString(addQuotationMark); int c = Trailing.Count; for (int i = 0; i < c; i++) { result += "\n" + "L" + (i + 1) + "=" + Trailing[i].toString(addQuotationMark); } } else if (m_type == VsqHandleType.Vibrato) { result += "\n" + "IconID=" + IconID + "\n"; result += "IDS=" + IDS + "\n"; result += "Original=" + Original + "\n"; result += "Caption=" + Caption + "\n"; result += "Length=" + Length + "\n"; result += "StartDepth=" + StartDepth + "\n"; result += "DepthBPNum=" + DepthBP.getCount() + "\n"; if (DepthBP.getCount() > 0) { result += "DepthBPX=" + PortUtil.formatDecimal("0.000000", DepthBP.getElement(0).X); for (int i = 1; i < DepthBP.getCount(); i++) { result += "," + PortUtil.formatDecimal("0.000000", DepthBP.getElement(i).X); } result += "\n" + "DepthBPY=" + DepthBP.getElement(0).Y; for (int i = 1; i < DepthBP.getCount(); i++) { result += "," + DepthBP.getElement(i).Y; } result += "\n"; } result += "StartRate=" + StartRate + "\n"; result += "RateBPNum=" + RateBP.getCount(); if (RateBP.getCount() > 0) { result += "\n" + "RateBPX=" + PortUtil.formatDecimal("0.000000", RateBP.getElement(0).X); for (int i = 1; i < RateBP.getCount(); i++) { result += "," + PortUtil.formatDecimal("0.000000", RateBP.getElement(i).X); } result += "\n" + "RateBPY=" + RateBP.getElement(0).Y; for (int i = 1; i < RateBP.getCount(); i++) { result += "," + RateBP.getElement(i).Y; } } } else if (m_type == VsqHandleType.Singer) { result += "\n" + "IconID=" + IconID + "\n"; result += "IDS=" + IDS + "\n"; result += "Original=" + Original + "\n"; result += "Caption=" + Caption + "\n"; result += "Length=" + Length + "\n"; result += "Language=" + Language + "\n"; result += "Program=" + Program; } else if (m_type == VsqHandleType.NoteHeadHandle) { result += "\n" + "IconID=" + IconID + "\n"; result += "IDS=" + IDS + "\n"; result += "Original=" + Original + "\n"; result += "Caption=" + Caption + "\n"; result += "Length=" + Length + "\n"; result += "Duration=" + Duration + "\n"; result += "Depth=" + Depth; } else if (m_type == VsqHandleType.DynamicsHandle) { result += "\n" + "IconID=" + IconID + "\n"; result += "IDS=" + IDS + "\n"; result += "Original=" + Original + "\n"; result += "Caption=" + Caption + "\n"; result += "StartDyn=" + StartDyn + "\n"; result += "EndDyn=" + EndDyn + "\n"; result += "Length=" + Length + "\n"; if (DynBP != null) { if (DynBP.getCount() <= 0) { result += "DynBPNum=0"; } else { result += "DynBPX=" + PortUtil.formatDecimal("0.000000", DynBP.getElement(0).X); int c = DynBP.getCount(); for (int i = 1; i < c; i++) { result += "," + PortUtil.formatDecimal("0.000000", DynBP.getElement(i).X); } result += "\n" + "DynBPY=" + DynBP.getElement(0).Y; for (int i = 1; i < c; i++) { result += "," + DynBP.getElement(i).Y; } } } else { result += "DynBPNum=0"; } } return(result); }