/// <summary> /// クレッシェンド,デクレッシェンド,および強弱記号をダイナミクスカーブに反映させます. /// この操作によって,ダイナミクスカーブに設定されたデータは全て削除されます. /// </summary> public void reflectDynamics() { VsqBPList dyn = getCurve("dyn"); dyn.clear(); for (Iterator <VsqEvent> itr = getDynamicsEventIterator(); itr.hasNext();) { VsqEvent item = itr.next(); IconDynamicsHandle handle = item.ID.IconDynamicsHandle; if (handle == null) { continue; } int clock = item.Clock; int length = item.ID.getLength(); if (handle.isDynaffType()) { // 強弱記号 dyn.add(clock, handle.getStartDyn()); } else { // クレッシェンド,デクレッシェンド int start_dyn = dyn.getValue(clock); // 範囲内のアイテムを削除 int count = dyn.size(); for (int i = count - 1; i >= 0; i--) { int c = dyn.getKeyClock(i); if (clock <= c && c <= clock + length) { dyn.removeElementAt(i); } else if (c < clock) { break; } } VibratoBPList bplist = handle.getDynBP(); if (bplist == null || (bplist != null && bplist.getCount() <= 0)) { // カーブデータが無い場合 double a = 0.0; if (length > 0) { a = (handle.getEndDyn() - handle.getStartDyn()) / (double)length; } int last_val = start_dyn; for (int i = clock; i < clock + length; i++) { int val = start_dyn + (int)(a * (i - clock)); if (val < dyn.getMinimum()) { val = dyn.getMinimum(); } else if (dyn.getMaximum() < val) { val = dyn.getMaximum(); } if (last_val != val) { dyn.add(i, val); last_val = val; } } } else { // カーブデータがある場合 int last_val = handle.getStartDyn(); int last_clock = clock; int bpnum = bplist.getCount(); int last = start_dyn; // bplistに指定されている分のデータ点を追加 for (int i = 0; i < bpnum; i++) { VibratoBPPair point = bplist.getElement(i); int pointClock = clock + (int)(length * point.X); if (pointClock <= last_clock) { continue; } int pointValue = point.Y; double a = (pointValue - last_val) / (double)(pointClock - last_clock); for (int j = last_clock; j <= pointClock; j++) { int val = start_dyn + (int)((j - last_clock) * a); if (val < dyn.getMinimum()) { val = dyn.getMinimum(); } else if (dyn.getMaximum() < val) { val = dyn.getMaximum(); } if (val != last) { dyn.add(j, val); last = val; } } last_val = point.Y; last_clock = pointClock; } // bplistの末尾から,clock => clock + lengthまでのデータ点を追加 int last2 = last; if (last_clock < clock + length) { double a = (handle.getEndDyn() - last_val) / (double)(clock + length - last_clock); for (int j = last_clock; j < clock + length; j++) { int val = last2 + (int)((j - last_clock) * a); if (val < dyn.getMinimum()) { val = dyn.getMinimum(); } else if (dyn.getMaximum() < val) { val = dyn.getMaximum(); } if (val != last) { dyn.add(j, val); last = val; } } } } } } }
/// <summary> /// このトラックの指定した範囲を削除し,削除範囲以降の部分を削除開始位置までシフトします /// </summary> /// <param name="clock_start"></param> /// <param name="clock_end"></param> public void removePart(int clock_start, int clock_end) { int dclock = clock_end - clock_start; // 削除する範囲に歌手変更イベントが存在するかどうかを検査。 VsqEvent t_last_singer = null; for (Iterator <VsqEvent> itr = getSingerEventIterator(); itr.hasNext();) { VsqEvent ve = itr.next(); if (clock_start <= ve.Clock && ve.Clock < clock_end) { t_last_singer = ve; } if (ve.Clock == clock_end) { t_last_singer = null; // 後でclock_endの位置に補うが、そこにに既に歌手変更イベントがあるとまずいので。 } } VsqEvent last_singer = null; if (t_last_singer != null) { last_singer = (VsqEvent)t_last_singer.clone(); last_singer.Clock = clock_end; } bool changed = true; // イベントの削除 while (changed) { changed = false; int numEvents = getEventCount(); for (int i = 0; i < numEvents; i++) { VsqEvent itemi = getEvent(i); if (clock_start <= itemi.Clock && itemi.Clock < clock_end) { removeEvent(i); changed = true; break; } } } // クロックのシフト if (last_singer != null) { addEvent(last_singer); //歌手変更イベントを補う } int num_events = getEventCount(); for (int i = 0; i < num_events; i++) { VsqEvent itemi = getEvent(i); if (clock_end <= itemi.Clock) { itemi.Clock -= dclock; } } for (int i = 0; i < VsqTrack.CURVES.Length; i++) { string curve = VsqTrack.CURVES[i]; VsqBPList bplist = getCurve(curve); if (bplist == null) { continue; } VsqBPList buf_bplist = (VsqBPList)bplist.clone(); bplist.clear(); int value_at_end = buf_bplist.getValue(clock_end); bool at_end_added = false; foreach (var key in buf_bplist.keyClockIterator()) { if (key < clock_start) { bplist.add(key, buf_bplist.getValue(key)); } else if (clock_end <= key) { if (key == clock_end) { at_end_added = true; } bplist.add(key - dclock, buf_bplist.getValue(key)); } } if (!at_end_added) { bplist.add(clock_end - dclock, value_at_end); } } }