@@ -45,7 +45,7 @@ public Rational Bar
4545 case Type . Bar :
4646 return _data ;
4747 case Type . InvariantBar :
48- return ConvertTime ( _data , ( Rational ) InvariantBpm , null ) ;
48+ return ConvertTime ( _data , InvariantBpm , null ) ;
4949 case Type . Seconds :
5050 return ConvertTime ( _data , 240 , null ) ; // seconds秒数可以等效为240bpm下的小节数
5151 default :
@@ -68,9 +68,9 @@ public Rational InvariantBar
6868 case Type . InvariantBar :
6969 return _data ;
7070 case Type . Bar :
71- return ConvertTime ( _data , null , ( Rational ) InvariantBpm ) ;
71+ return ConvertTime ( _data , null , InvariantBpm ) ;
7272 case Type . Seconds :
73- return ConvertTime ( _data , 240 , ( Rational ) InvariantBpm ) ; // seconds秒数可以等效为240bpm下的小节数
73+ return ConvertTime ( _data , 240 , InvariantBpm ) ; // seconds秒数可以等效为240bpm下的小节数
7474 default :
7575 throw new InvalidOperationException ( ) ;
7676 }
@@ -93,7 +93,7 @@ public Rational Seconds
9393 case Type . Bar :
9494 return ConvertTime ( _data , null , 240 ) ; // seconds秒数可以等效为240bpm下的小节数
9595 case Type . InvariantBar :
96- return ConvertTime ( _data , ( Rational ) InvariantBpm , 240 ) ;
96+ return ConvertTime ( _data , InvariantBpm , 240 ) ;
9797 default :
9898 throw new InvalidOperationException ( ) ;
9999 }
@@ -105,69 +105,14 @@ public Rational Seconds
105105 }
106106 }
107107
108- /**
109- * 用于在不同格式的时间数值之间转换的函数。
110- *
111- * 首先指出一个重要原理:Seconds格式下以秒为单位的时间,在数值上实际等价于 240bpm下的不变小节时间。这就是为什么可以构造一个通用的转换函数的原理。
112- *
113- * <param name="value">要被转换的时间值</param>
114- * <param name="srcBpm">指定value所对应的源bpm。若为None,表示使用BPMList中动态的bpm(对应把Bar转换为其他类型的情况)</param>
115- * <param name="dstBpm">转换的目标bpm。若为None,表示使用BPMList中动态的bpm(对应把其他类型转换为Bar的情况)</param>
116- */
117- private Rational ConvertTime ( Rational value , Rational ? srcBpm , Rational ? dstBpm )
108+ private Rational ConvertTime ( Rational value , decimal ? srcBpm , decimal ? dstBpm )
118109 {
119110 var startTime = _note . Time ;
120111 if ( _note is Slide slide && slide . WaitTime != this )
121112 { // 如果我不是WaitTime,则我是Duration,则应加上等待时间
122113 startTime += slide . WaitTime . Bar ;
123114 }
124- return ConvertTime ( startTime , value , srcBpm , dstBpm , BpmList ) ;
125- }
126-
127- internal static Rational ConvertTime ( Rational startTime , Rational value , Rational ? srcBpm , Rational ? dstBpm , BPMList bpmList )
128- {
129- if ( srcBpm != null && dstBpm != null )
130- {
131- // 静态的src和dst,直接算一下即可,无需遍历bpm表
132- return ( value * ( dstBpm . Value / srcBpm . Value ) ) . CanonicalForm ;
133- }
134- else
135- {
136- var rangeStart = startTime ;
137- var bpmIndex = bpmList . FindIndex ( rangeStart ) ;
138- Rational result = 0 ;
139- Rational remain = value ;
140- while ( remain > 0 )
141- {
142- // 当前所处bpm区间的结束位置。如果当前已经是最后一个区间了,则结束位置写成一个很大的数就可以了,反正本轮remain一定会被清空
143- var bpmRangeEnd = bpmIndex < bpmList . Count - 1 ? bpmList [ bpmIndex + 1 ] . Time : 9999999 ;
144- // 本区间可以消耗掉remain的最大数量,以src的bpm为单位。
145- Rational curRangeCapacity = bpmRangeEnd - rangeStart ;
146-
147- var srcBpmNow = srcBpm ; // 每次循环要复制一份srcBpm,不然直接改了srcBpm的话,再次循环时逻辑就不对了
148- var dstBpmNow = dstBpm ;
149- if ( srcBpmNow == null )
150- { // 如果srcBpm传入的是None,说明应该使用当前的实时bpm作为srcBpm
151- srcBpmNow = ( Rational ) bpmList [ bpmIndex ] . Bpm ;
152- // 此时capacity已经是以srcBpm为单位了,无需再转换
153- }
154- else if ( dstBpmNow == null )
155- {
156- dstBpmNow = ( Rational ) bpmList [ bpmIndex ] . Bpm ;
157- // 此时capacity是基于可变bpm即dstBpm的,需要换算到srcBpm上
158- curRangeCapacity *= ( srcBpmNow . Value / dstBpmNow . Value ) ;
159- }
160-
161- Rational toSubtract = curRangeCapacity < remain ? curRangeCapacity : remain ; // 要从remain中减掉的量,应该是(剩余量,本bpm区间允许消耗量)的最小值
162- remain -= toSubtract ;
163- result += toSubtract * ( dstBpmNow ! . Value / srcBpmNow . Value ) ;
164-
165- bpmIndex += 1 ;
166- rangeStart = bpmRangeEnd ;
167- }
168-
169- return result . CanonicalForm ;
170- }
115+ return BpmList . ConvertTime ( startTime , value , srcBpm , dstBpm ) ;
171116 }
172117
173118 public static Duration operator + ( Duration a , Duration b )
0 commit comments