我正在尝试找到一种算法来消除一些半随机数之间的间隙,例如,如果存在具有close值的间隙,它们将是相同的。 例如,如果我们将“ 109 102 212 198 99 802”作为空白,则四舍五入为“ 100 100 200 200 100 100 800”。 假定所有舍入的间隙将为(2 ^ n)*(最小间隙),其中n是一个非负整数。在上面的示例中,间隙大约为100(最小),200、400、800。
答案 0 :(得分:1)
实际上,我想编写代码将唱歌曲目转换为乐谱。为此,我找到了相邻音符之间的间隔,然后我需要算法来舍入这些间隔。 我已经做到了,而且我认为效果很好。 首先,我发现主要差距的值,例如在“ 102 103 402 409 390 398 100 200 408”中,主要差距约为400(平均值为402 409 390 398 408),然后我将其持续时间设为1并进行比较另一个。 102的持续时间将为0.25,依此类推。
编辑:第一,我使用了一些python库来处理.mp3文件,并以毫秒为单位查找频率变化的时刻及其对应的持续时间。由于这些时间并不精确,因此我需要四舍五入,因此可以为它们指定一种音符符号。
def roundOff(diffs):
global major_element, ref_offset, divide_flag, measured_time, measured_note
major_element = findMajor(diffs)
for element in diffs:
divide_flag = False
measured_time = 0
measured_note = 0
note_duration.append(noteFinder(element, ref_offset))
return note_duration
上面的函数获取间隙作为输入并返回其相应的音符持续时间。 我发现主要差距如下:
def findMajor(diffs):
diffs_copy = diffs.copy()
diffs_copy.sort()
this = 0
for element in diffs_copy:
if isNear(element, this):
temp_this = (this*elements_in_gap[this] + element)/(elements_in_gap[this] + 1)
elements_in_gap[this] += 1
elements_in_gap[temp_this] = elements_in_gap.pop(this)
this = temp_this
else:
this = element
elements_in_gap[this] = 1
return max(elements_in_gap, key = element_in_gap.get)
首先,它对间隙列表进行排序,并将“ this”作为我们要检查的间隙的代表值(初始值为0),在每个步骤中,它检查新间隙是否在“ this”附近然后修改“ this”并增加“ this”集中的间隔数,但是如果不接近,则将“ this”更改为新元素,并将新“ this”的初始数量(:|)更改为1并执行相同的操作。 最后,将值最大的键作为主要空白返回。
isNear函数是这样的:
def isNear(a, b):
if a < b+b*tolerance and a > b-b*tolerance:
return True
return False
在这种情况下,将公差设置为0.1是适当的。 noteFinder查找与主要差距为1(ref_offset)有关的每个差距的音符。
def noteFinder(diff_time, offset):
global measured_time, measured_note, divide_flag, major_element
if isNear(diff_time, measured_time):
return measured_note
else:
if not divide_flag:
if diff_time > measured_time:
measured_time += offset*major_element
measured_note += offset
return noteFinder(diff_time, offset)
else:
offset /= 2
measured_time -= offset*major_element
measured_note -= offset
divide_flag = True
return noteFinder(diff_time, offset)
else:
offset /= 2
if diff_time > measured_time:
measured_time += offset*major_element
measured_note += offset
return noteFinder(diff_time, offset)
else:
measured_time -= offset*major_element
measured_note -= offset
return noteFinder(diff_time, offset)
在每个步骤中将偏移量添加到被测音符上,并将偏移量*主要间隙值添加到测量时间(首先,偏移量为1),直到其间隙值小于测量时间,然后打开divid_flag在每一步中将偏移量除以2,并尝试使其接近于差距值,然后返回多人注释。
这是我建议的方案,如果您有更好的方案,请告诉我。