Итак, я создал эту программу для распознавания высоты тона, используя модуль parselmouth. Он отлично работает для таких инструментов, как пианино, тромбон и флейта, но не слишком хорош для пения (лалала, ааа, татата и т. Д.), Гудения или свиста.
import parselmouth as pm
import winsound
from midiutil import MIDIFile
from math import log
def getmidinote(frequency):
return 69+round(12*log(frequency/440, 2)) #using the formula piano key = 12log2(frequency/440) + 49
def midify(path, bpm):
notelength = int(1500/bpm) #one quarter beat per 15/bpm sec or 15000/bpm ms. each element in frequency is 10ms. 1500/bpm element per 1/4 beat
sound = pm.Sound(path)
time, frequency = sound.xs(), sound.to_pitch().selected_array['frequency'][::notelength]
pitch = [getmidinote(f) if f>0 else 0 for f in frequency]
#combine duplicate note as one
duration = 1
notes = []
for i in range(1, len(pitch)):
if pitch[i]==pitch[i-1]: #if the previous note and current note is the same
duration += 1
else:
if duration!=1:
notes.append([pitch[i-1], duration])
else:
notes[-1][1] += 1 #if the note is only 1 duration, just add it to last note's duration
duration = 1
notes.append((pitch[-1], duration)) #this makes sure the last note gets added
print(notes)
#play output
for i in notes:
p, d = i[0]-20, i[1]
if p==-20:
winsound.Beep(50, d*10*notelength)
else:
winsound.Beep(int(440*(2**((p-49)/12))), d*10*notelength)
#convert to midi
midi = MIDIFile(1, file_format=1, ticks_per_quarternote=960)
#blah blah
midify('test8.wav', 100)
Может кто-нибудь сказать мне, как я могу улучшить это, чтобы это работало и для голоса? Я также попытался удвоить выходную частоту, так как высота была слишком низкой, чтобы слышать, но он в основном думает, что мой голос тих. Спасибо.