public string __DEBUG__toString() { string phase = ""; for (int i = 0; i < track.getEventCount(); i++) { VsqEvent itemi = track.getEvent(i); if (itemi.ID.type == VsqIDType.Anote) { phase += itemi.ID.LyricHandle.L0.Phrase; } } return(phase); }
public Object getElementAt2(int index) { return(track2.getEvent(index)); }
public void readFromVsqx() { VsqFile vsq = VsqxReader.readFromVsqx("./fixture/track1.vsqx"); // トラック数 Assert.AreEqual(2, vsq.Track.size()); // プリメジャー Assert.AreEqual(4, vsq.getPreMeasure()); // イベント数 // 最初のmusicalPartには歌手変更1個と音符2個 // 2つ目のmusicalPartには歌手変更1個と音符1個が入っているはず VsqTrack track = vsq.Track.get(1); Assert.AreEqual(6, track.getEventCount()); // 歌手変更が正しく読み込まれているか // 1個目はデフォルトの歌手変更なのでスルー var singerChange = track.getEvent(1); Assert.AreEqual(7680, singerChange.Clock); Assert.Null(singerChange.ID.IconDynamicsHandle); Assert.Null(singerChange.ID.LyricHandle); Assert.Null(singerChange.ID.NoteHeadHandle); Assert.Null(singerChange.ID.VibratoHandle); Assert.AreEqual("VY1V3", singerChange.ID.IconHandle.IDS); Assert.AreEqual("$07010000", singerChange.ID.IconHandle.IconID); Assert.AreEqual(0, singerChange.ID.IconHandle.Language); Assert.AreEqual(0, singerChange.ID.IconHandle.Program); // 1つめの音符イベントが正しく読み込まれているか var firstEvent = track.getEvent(2); Assert.AreEqual(7680 + 0, firstEvent.Clock); Assert.AreEqual(48, firstEvent.ID.Note); Assert.AreEqual(480, firstEvent.ID.getLength()); Assert.AreEqual(62, firstEvent.ID.Dynamics); Assert.AreEqual(50, firstEvent.ID.DEMaccent); Assert.AreEqual(8, firstEvent.ID.PMBendDepth); Assert.AreEqual(0, firstEvent.ID.PMBendLength); Assert.AreEqual(50, firstEvent.ID.DEMdecGainRate); Assert.AreEqual(false, firstEvent.ID.isFallPortamento()); Assert.AreEqual(false, firstEvent.ID.isRisePortamento()); Assert.Null(firstEvent.ID.IconDynamicsHandle); Assert.AreEqual("わ", firstEvent.ID.LyricHandle.L0.Phrase); Assert.AreEqual("w a", firstEvent.ID.LyricHandle.L0.getPhoneticSymbol()); Assert.AreEqual(true, firstEvent.ID.LyricHandle.L0.PhoneticSymbolProtected); Assert.Null(firstEvent.ID.NoteHeadHandle); Assert.AreEqual("$04040000", firstEvent.ID.VibratoHandle.IconID); Assert.AreEqual(316, firstEvent.ID.VibratoHandle.getLength()); var depthBP = firstEvent.ID.VibratoHandle.getDepthBP(); Assert.AreEqual(1, depthBP.getCount()); Assert.AreEqual(0.0f, depthBP.getElement(0).X); Assert.AreEqual(64, depthBP.getElement(0).Y); var rateBP = firstEvent.ID.VibratoHandle.getRateBP(); Assert.AreEqual(1, rateBP.getCount()); Assert.AreEqual(0.0f, rateBP.getElement(0).X); Assert.AreEqual(50, rateBP.getElement(0).Y); Assert.AreEqual(164, firstEvent.ID.VibratoDelay); Assert.Null(firstEvent.ID.IconHandle); // 2つめの音符イベントが正しく読み込まれているか var secondEvent = track.getEvent(3); Assert.AreEqual(7680 + 480, secondEvent.Clock); Assert.AreEqual(50, secondEvent.ID.Note); Assert.AreEqual(960, secondEvent.ID.getLength()); Assert.AreEqual(63, secondEvent.ID.Dynamics); Assert.AreEqual(50, secondEvent.ID.DEMaccent); Assert.AreEqual(8, secondEvent.ID.PMBendDepth); Assert.AreEqual(0, secondEvent.ID.PMBendLength); Assert.AreEqual(50, secondEvent.ID.DEMdecGainRate); Assert.AreEqual(true, secondEvent.ID.isFallPortamento()); Assert.AreEqual(false, secondEvent.ID.isRisePortamento()); Assert.Null(secondEvent.ID.IconDynamicsHandle); Assert.AreEqual("は", secondEvent.ID.LyricHandle.L0.Phrase); Assert.AreEqual("h a", secondEvent.ID.LyricHandle.L0.getPhoneticSymbol()); Assert.AreEqual(false, secondEvent.ID.LyricHandle.L0.PhoneticSymbolProtected); Assert.Null(secondEvent.ID.NoteHeadHandle); Assert.AreEqual("$04040004", secondEvent.ID.VibratoHandle.IconID); Assert.AreEqual(624, secondEvent.ID.VibratoHandle.getLength()); depthBP = secondEvent.ID.VibratoHandle.getDepthBP(); Assert.AreEqual(1, depthBP.getCount()); Assert.AreEqual(0.0f, depthBP.getElement(0).X); Assert.AreEqual(64, depthBP.getElement(0).Y); rateBP = secondEvent.ID.VibratoHandle.getRateBP(); Assert.AreEqual(1, secondEvent.ID.VibratoHandle.getRateBP().getCount()); Assert.AreEqual(0.0f, rateBP.getElement(0).X); Assert.AreEqual(64, rateBP.getElement(0).Y); Assert.AreEqual(336, secondEvent.ID.VibratoDelay); Assert.Null(secondEvent.ID.IconHandle); // 2つ目の歌手変更 var singerChange2 = track.getEvent(4); Assert.AreEqual(10560, singerChange2.Clock); Assert.Null(singerChange2.ID.IconDynamicsHandle); Assert.Null(singerChange2.ID.LyricHandle); Assert.Null(singerChange2.ID.NoteHeadHandle); Assert.Null(singerChange2.ID.VibratoHandle); Assert.AreEqual("Miku(V2)", singerChange2.ID.IconHandle.IDS); Assert.AreEqual("$07010001", singerChange2.ID.IconHandle.IconID); Assert.AreEqual(0, singerChange2.ID.IconHandle.Language); Assert.AreEqual(1, singerChange2.ID.IconHandle.Program); // 3つめの音符イベントが正しく読み込まれているか var thirdEvent = track.getEvent(5); Assert.AreEqual(10560 + 665, thirdEvent.Clock); Assert.AreEqual(60, thirdEvent.ID.Note); Assert.AreEqual(480, thirdEvent.ID.getLength()); Assert.AreEqual(64, thirdEvent.ID.Dynamics); Assert.AreEqual(50, thirdEvent.ID.DEMaccent); Assert.AreEqual(8, thirdEvent.ID.PMBendDepth); Assert.AreEqual(0, thirdEvent.ID.PMBendLength); Assert.AreEqual(50, thirdEvent.ID.DEMdecGainRate); Assert.AreEqual(false, thirdEvent.ID.isFallPortamento()); Assert.AreEqual(false, thirdEvent.ID.isRisePortamento()); Assert.Null(thirdEvent.ID.IconDynamicsHandle); Assert.AreEqual("a", thirdEvent.ID.LyricHandle.L0.Phrase); Assert.AreEqual("a", thirdEvent.ID.LyricHandle.L0.getPhoneticSymbol()); Assert.AreEqual(false, thirdEvent.ID.LyricHandle.L0.PhoneticSymbolProtected); Assert.Null(thirdEvent.ID.NoteHeadHandle); Assert.AreEqual("$04040000", thirdEvent.ID.VibratoHandle.IconID); Assert.AreEqual(316, thirdEvent.ID.VibratoHandle.getLength()); depthBP = thirdEvent.ID.VibratoHandle.getDepthBP(); Assert.AreEqual(1, depthBP.getCount()); Assert.AreEqual(0.0f, depthBP.getElement(0).X); Assert.AreEqual(64, depthBP.getElement(0).Y); rateBP = thirdEvent.ID.VibratoHandle.getRateBP(); Assert.AreEqual(1, thirdEvent.ID.VibratoHandle.getRateBP().getCount()); Assert.AreEqual(0.0f, rateBP.getElement(0).X); Assert.AreEqual(50, rateBP.getElement(0).Y); Assert.AreEqual(164, thirdEvent.ID.VibratoDelay); Assert.Null(thirdEvent.ID.IconHandle); // トラック名 Assert.AreEqual("Track", track.getName()); // テンポ変更 Assert.AreEqual(2, vsq.TempoTable.size()); Assert.AreEqual(0, vsq.TempoTable.get(0).Clock); Assert.AreEqual(500000, vsq.TempoTable.get(0).Tempo); Assert.AreEqual(8640, vsq.TempoTable.get(1).Clock); Assert.AreEqual(1199760, vsq.TempoTable.get(1).Tempo); // 拍子変更 Assert.AreEqual(2, vsq.TimesigTable.size()); Assert.AreEqual(0, vsq.TimesigTable.get(0).Clock); Assert.AreEqual(4, vsq.TimesigTable.get(0).Numerator); Assert.AreEqual(4, vsq.TimesigTable.get(0).Denominator); Assert.AreEqual(9600, vsq.TimesigTable.get(1).Clock); Assert.AreEqual(3, vsq.TimesigTable.get(1).Numerator); Assert.AreEqual(4, vsq.TimesigTable.get(1).Denominator); // コントロールカーブ // DYN var dyn = track.getCurve("DYN"); Assert.AreEqual(1, dyn.size()); Assert.AreEqual(720, dyn.getKeyClock(0)); Assert.AreEqual(96, dyn.getElement(0)); // BRE var bre = track.getCurve("BRE"); Assert.AreEqual(1, bre.size()); Assert.AreEqual(720, bre.getKeyClock(0)); Assert.AreEqual(102, bre.getElement(0)); // BRI // CLE // OPE var ope = track.getCurve("OPE"); Assert.AreEqual(3, ope.size()); Assert.AreEqual(7680 + 0, ope.getKeyClock(0)); Assert.AreEqual(127, ope.getElement(0)); Assert.AreEqual(7680 + 480, ope.getKeyClock(1)); Assert.AreEqual(127, ope.getElement(1)); Assert.AreEqual(10560 + 665, ope.getKeyClock(2)); Assert.AreEqual(127, ope.getElement(2)); // GEN // POR // PIT // PBS // Mixerが正しく読み込まれているか Assert.AreEqual(2, vsq.Mixer.MasterFeder); Assert.AreEqual(1, vsq.Mixer.Slave.size()); Assert.AreEqual(1, vsq.Mixer.Slave.get(0).Solo); Assert.AreEqual(0, vsq.Mixer.Slave.get(0).Mute); Assert.AreEqual(64, vsq.Mixer.Slave.get(0).Panpot); Assert.AreEqual(1, vsq.Mixer.Slave.get(0).Feder); }
public void patchWork(WorkerState state, Object arg) { #if DEBUG sout.println("SynthesizeWorker#patchWork"); #endif VsqFileEx vsq = AppManager.getVsqFile(); Object[] args = (Object[])arg; List <PatchWorkQueue> queue = (List <PatchWorkQueue>)args[0]; List <int> tracks = (List <int>)args[1]; int finished = queue.Count; string temppath = AppManager.getTempWaveDir(); for (int k = 0; k < tracks.Count; k++) { int track = tracks[k]; string wavePath = Path.Combine(temppath, track + ".wav"); List <int> queueIndex = new List <int>(); for (int i = 0; i < queue.Count; i++) { if (queue[i].track == track) { queueIndex.Add(i); } } if (queueIndex.Count <= 0) { // 第trackトラックに対してパッチワークを行う必要無し continue; } #if DEBUG sout.println("AppManager#pathWorkToFreeze; wavePath=" + wavePath + "; queue.get( queueIndex.get( 0 ) ).file=" + queue[queueIndex[0]].file); sout.println("AppManager#pathWorkToFreeze; queueIndex.size()=" + queueIndex.Count); #endif if (queueIndex.Count == 1 && wavePath.Equals(queue[queueIndex[0]].file)) { // 第trackトラック全体の合成を指示するキューだった場合. // このとき,パッチワークを行う必要なし. AppManager.mLastRenderedStatus[track - 1] = new RenderedStatus((VsqTrack)vsq.Track[track].clone(), vsq.TempoTable, (SequenceConfig)vsq.config.clone()); AppManager.serializeRenderingStatus(temppath, track); AppManager.invokeWaveViewReloadRequiredEvent(track, wavePath, 1, -1); continue; } WaveWriter writer = null; try { int sampleRate = vsq.config.SamplingRate; long totalLength = (long)((vsq.getSecFromClock(vsq.TotalClocks) + 1.0) * sampleRate); writer = new WaveWriter(wavePath, vsq.config.WaveFileOutputChannel, 16, sampleRate); int BUFLEN = 1024; double[] bufl = new double[BUFLEN]; double[] bufr = new double[BUFLEN]; double total = 0.0; for (int m = 0; m < queueIndex.Count; m++) { int i = queueIndex[m]; if (finished <= i) { break; } // パッチワークの開始秒時 double secStart = vsq.getSecFromClock(queue[i].clockStart); long sampleStart = (long)(secStart * sampleRate); // パッチワークの終了秒時 int clockEnd = queue[i].clockEnd; if (clockEnd == int.MaxValue) { clockEnd = vsq.TotalClocks + 240; } double secEnd = vsq.getSecFromClock(clockEnd); long sampleEnd = (long)(secEnd * sampleRate); WaveReader wr = null; try { wr = new WaveReader(queue[i].file); long remain2 = sampleEnd - sampleStart; long proc = 0; while (remain2 > 0) { int delta = remain2 > BUFLEN ? BUFLEN : (int)remain2; wr.read(proc, delta, bufl, bufr); writer.replace(sampleStart + proc, delta, bufl, bufr); proc += delta; remain2 -= delta; total += delta; state.reportProgress(total); } } catch (Exception ex) { Logger.write(typeof(AppManager) + ".patchWorkToFreeze; ex=" + ex + "\n"); serr.println("AppManager#patchWorkToFreeze; ex=" + ex); } finally { if (wr != null) { try { wr.close(); } catch (Exception ex2) { Logger.write(typeof(AppManager) + ".patchWorkToFreeze; ex=" + ex2 + "\n"); serr.println("AppManager#patchWorkToFreeze; ex2=" + ex2); } } } try { PortUtil.deleteFile(queue[i].file); } catch (Exception ex) { Logger.write(typeof(AppManager) + ".patchWorkToFreeze; ex=" + ex + "\n"); serr.println("AppManager#patchWorkToFreeze; ex=" + ex); } } VsqTrack vsq_track = vsq.Track[track]; if (queueIndex[queueIndex.Count - 1] <= finished) { // 途中で終了せず,このトラックの全てのパッチワークが完了した. AppManager.mLastRenderedStatus[track - 1] = new RenderedStatus((VsqTrack)vsq_track.clone(), vsq.TempoTable, (SequenceConfig)vsq.config.clone()); AppManager.serializeRenderingStatus(temppath, track); AppManager.setRenderRequired(track, false); } else { // パッチワークの作成途中で,キャンセルされた // キャンセルされたやつ以降の範囲に、プログラムチェンジ17の歌手変更イベントを挿入する。→AppManager#detectTrackDifferenceに必ず検出してもらえる。 VsqTrack copied = (VsqTrack)vsq_track.clone(); VsqEvent dumy = new VsqEvent(); dumy.ID.type = VsqIDType.Singer; dumy.ID.IconHandle = new IconHandle(); dumy.ID.IconHandle.Program = 17; for (int m = 0; m < queueIndex.Count; m++) { int i = queueIndex[m]; if (i < finished) { continue; } int start = queue[i].clockStart; int end = queue[i].clockEnd; VsqEvent singerAtEnd = vsq_track.getSingerEventAt(end); // startの位置に歌手変更が既に指定されていないかどうかを検査 int foundStart = -1; int foundEnd = -1; for (Iterator <int> itr = copied.indexIterator(IndexIteratorKind.SINGER); itr.hasNext();) { int j = itr.next(); VsqEvent ve = copied.getEvent(j); if (ve.Clock == start) { foundStart = j; } if (ve.Clock == end) { foundEnd = j; } if (end < ve.Clock) { break; } } VsqEvent dumyStart = (VsqEvent)dumy.clone(); dumyStart.Clock = start; if (foundStart >= 0) { copied.setEvent(foundStart, dumyStart); } else { copied.addEvent(dumyStart); } if (end != int.MaxValue) { VsqEvent dumyEnd = (VsqEvent)singerAtEnd.clone(); dumyEnd.Clock = end; if (foundEnd >= 0) { copied.setEvent(foundEnd, dumyEnd); } else { copied.addEvent(dumyEnd); } } copied.sortEvent(); } AppManager.mLastRenderedStatus[track - 1] = new RenderedStatus(copied, vsq.TempoTable, (SequenceConfig)vsq.config.clone()); AppManager.serializeRenderingStatus(temppath, track); } state.reportComplete(); } catch (Exception ex) { Logger.write(typeof(AppManager) + ".patchWorkToFreeze; ex=" + ex + "\n"); serr.println("AppManager#patchWorkToFreeze; ex=" + ex); } finally { if (writer != null) { try { writer.close(); } catch (Exception ex2) { Logger.write(typeof(AppManager) + ".patchWorkToFreeze; ex=" + ex2 + "\n"); serr.println("AppManager#patchWorkToFreeze; ex2=" + ex2); } } } // 波形表示用のWaveDrawContextの内容を更新する。 /*for ( int j = 0; j < queueIndex.size(); j++ ) { * int i = queueIndex.get( j ); * if ( i >= finished ) { * continue; * } * double secStart = mVsq.getSecFromClock( queue.get( i ).clockStart ); * int clockEnd = queue.get( i ).clockEnd; * if ( clockEnd == int.MaxValue ) { * clockEnd = mVsq.TotalClocks + 240; * } * double secEnd = mVsq.getSecFromClock( clockEnd ); * * invokeWaveViewReloadRequiredEvent( tracks.get( k ), wavePath, secStart, secEnd ); * }*/ AppManager.invokeWaveViewReloadRequiredEvent(track, wavePath, 1, -1); } #if DEBUG sout.println("SynthesizeWorker#patchWork; done"); #endif state.reportComplete(); }