我正在開發的一個程式涉及將一首歌曲的 BPM(每分鐘節拍數)調整為另一首目標歌曲的 BPM 的功能。
問題是,有時將歌曲調整到目標歌曲的精確 BPM并不是一個好主意,因為第一首歌曲可能會被加速或減速太多,所以聽起來太快或太慢。在這些情況下,將歌曲的 BPM 調整為另一個更接近但仍與目標歌曲的 BPM 兼容的 BPM 是有意義的。
下面是一個例子:
BPM of song 1: 150BPM
BPM of target song: 84BPM
在這種情況下,將 150BPM 的歌曲減慢到 84BPM 并不是很實用 - 音頻會變得過于失真并且聽起來很奇怪。將歌曲 1 調整為 168BPM 更有意義——將目標歌曲的 BPM加倍,因為這需要對歌曲 1 的修改顯著減少,并且聽起來更自然。
再看同一個例子:
BPM of song 1: 84BPM
BPM of target song: 150BPM
在這種情況下,將歌曲 1 減慢到 75BPM,即 150 的一半,而不是將歌曲一直加速到 150是有意義的。
在這個程式中,歌曲 1 和目標歌曲的 BPM 因它所提供的歌曲而異(顯然)。這個函式想要做的是總是轉到與目標 BPM 兼容的最接近的數字 - 我需要什么數學?我正在使用 Python。今天我在制作整個程式的其余部分時非常頭疼。
uj5u.com熱心網友回復:
我想你有你需要的一切。你可以把它當作一個人來理解,所以把它寫進代碼中。問題往往是你不完全知道你在做什么,因為你太習慣了。
讓我們從函式定義開始:
def targetbpm(bpmPlaying: int, bpmTarget: int) -> int:
pass
以及您提供的兩個示例的給定預期結果
assert(targetbpm(150, 84) == 168)
assert(targetbpm(84, 150) == 75)
讓我們處理第一個斷言。有哪些選擇?就像你說的,你可以去84,但最好加倍。
def targetbpm(bpmPlaying: int, bpmTarget: int) -> int:
choices = [bpmTarget, bpmTarget*2]
選擇哪一個?與當前播放的內容差異最小的那個。因此,讓我們了解這些差異以及其中的最小值:
bpmdiff = [abs(bpmPlaying - choice) for choice in choices]
minimum = min(bpmdiff)
現在讓我們回到原來的選擇,選擇對應的
index = bpmdiff.index(minimum)
return choices[index]
現在你會發現第二個斷言還沒有通過。原因是您在這里還有另一個選擇:BPM 的一半。所以讓我們補充一點:
choices = [bpmTarget, bpmTarget*2, bpmTarget // 2]
問題解決了。
uj5u.com熱心網友回復:
這將是一種快速的方法。
def get_BPM_multiple(base, target):
distance = abs(target - base)
multiple = 1
for i in range(2, 8): # 8 or whatever
if base < target:
newdist = abs(target - base * i)
else:
newdist = abs(target - base / i)
if newdist < distance:
distance = newdist
multiple = i
else:
break
if base < target:
print(f"Multiply base {base}BPM by {multiple}: {base * multiple}BPM, "
f"close to target {target}BPM.")
return base * multiple
else:
print(f"Divide base {base}BPM by {multiple}: {base / multiple}BPM, "
f"close to target {target}BPM.")
return base / multiple
get_BPM_multiple(base=300, target=84)
# Divide base 300BPM by 4: 75.0BPM, close to target 84BPM.
get_BPM_multiple(base=84, target=150)
# Multiply base 84BPM by 2: 168BPM, close to target 150BPM.
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/323480.html
上一篇:我有一個(x,y)坐標(int8_t)并且需要在C中相對于(0,0)將它們旋轉“x”度(無法訪問浮點數或數學庫)
