[fix] Better bpm
This commit is contained in:
parent
6ae754e893
commit
73f0765519
55
redilysis.py
55
redilysis.py
@ -38,8 +38,12 @@ _BPM_MIN=10
|
||||
_BPM_MAX=400
|
||||
|
||||
# Argument parsing
|
||||
# Audio Args
|
||||
parser = argparse.ArgumentParser(prog='realtime_redis')
|
||||
# Standard Args
|
||||
parser.add_argument("-v","--verbose",action="store_true",help="Verbose")
|
||||
# Redis Args
|
||||
parser.add_argument("-i","--ip",help="IP address of the Redis server ",default="127.0.0.1",type=str)
|
||||
parser.add_argument("-p","--port",help="Port of the Redis server ",default="6379",type=str)
|
||||
# Audio Capture Args
|
||||
parser.add_argument('--list-devices','-L', action='store_true', help='Which devices are detected by pyaudio')
|
||||
parser.add_argument('--mode','-m', required=False, default='spectrum', choices=['spectrum', 'bpm'], type=str, help='Which mode to use. Default=spectrum')
|
||||
@ -47,16 +51,11 @@ parser.add_argument('--device','-d', required=False, type=int, help='Which pyaud
|
||||
parser.add_argument('--sampling-frequency','-s', required=False, default=0.1, type=float, help='Which frequency, in seconds. Default={}f '.format(_SAMPLING_FREQUENCY))
|
||||
parser.add_argument('--channels','-c', required=False, default=_CHANNELS, type=int, help='How many channels. Default={} '.format(_CHANNELS))
|
||||
parser.add_argument('--rate','-r', required=False, default=44100, type=int, help='The audio capture rate in Hz. Default={} '.format(_RATE))
|
||||
#parser.add_argument('--frames','-f', required=False, default=4410, type=int, help='How many frames per buffer. Default={}'.format(_FRAMES_PER_BUFFER))
|
||||
parser.add_argument('--frames','-f', required=False, default=4410, type=int, help='How many frames per buffer. Default={}'.format(_FRAMES_PER_BUFFER))
|
||||
# BPM Mode Args
|
||||
parser.add_argument('--bpm-min', required=False, default=_BPM_MIN, type=int, help='BPM mode only. The low BPM threshold. Default={} '.format(_BPM_MIN))
|
||||
parser.add_argument('--bpm-max', required=False, default=_BPM_MAX, type=int, help='BPM mode only. The high BPM threshold. Default={} '.format(_BPM_MAX))
|
||||
|
||||
# Redis Args
|
||||
parser.add_argument("-i","--ip",help="IP address of the Redis server ",default="127.0.0.1",type=str)
|
||||
parser.add_argument("-p","--port",help="Port of the Redis server ",default="6379",type=str)
|
||||
# Standard Args
|
||||
parser.add_argument("-v","--verbose",action="store_true",help="Verbose")
|
||||
args = parser.parse_args()
|
||||
|
||||
# global
|
||||
@ -110,7 +109,6 @@ if( LIST_DEVICES ):
|
||||
list_devices()
|
||||
os._exit(1)
|
||||
|
||||
p = pyaudio.PyAudio()
|
||||
|
||||
|
||||
def m_bpm(audio_data):
|
||||
@ -122,7 +120,6 @@ def m_bpm(audio_data):
|
||||
global bpm
|
||||
global start
|
||||
|
||||
bpm_delay = SAMPLING_FREQUENCY + start - time.time()
|
||||
|
||||
# Detect tempo / bpm
|
||||
new_bpm, beats = librosa.beat.beat_track(
|
||||
@ -138,19 +135,25 @@ def m_bpm(audio_data):
|
||||
'''
|
||||
# Correct the eventual octave error
|
||||
if new_bpm < bpm_min or new_bpm > bpm_max:
|
||||
found = False
|
||||
octaveErrorList = [ 0.5, 2, 0.3333, 3 ]
|
||||
for key,factor in enumerate(octaveErrorList):
|
||||
correction = new_bpm * factor
|
||||
if correction > bpm_min and correction < bpm_max:
|
||||
debug( "Corrected bpm to:{}".format(correction))
|
||||
debug( "Corrected high/low bpm:{} to:{}".format(new_bpm, correction))
|
||||
new_bpm = correction
|
||||
found = True
|
||||
break
|
||||
if new_bpm < bpm_min :
|
||||
new_bpm = bpm_min
|
||||
else :
|
||||
new_bpm = bpm_max
|
||||
if found == False:
|
||||
if new_bpm < bpm_min :
|
||||
new_bpm = bpm_min
|
||||
else :
|
||||
new_bpm = bpm_max
|
||||
|
||||
debug("new_bpm:{}".format(new_bpm))
|
||||
'''
|
||||
How to guess the next beats based on the data sent to redis
|
||||
~~ A Dirty Graph ~~
|
||||
|
||||
|start end|
|
||||
Capture |........................|
|
||||
@ -167,22 +170,29 @@ def m_bpm(audio_data):
|
||||
. passed (...b....b....b.)
|
||||
. guessed (..b....b....b....b...
|
||||
Next Beat Calculation b....b....b....b.|..b
|
||||
Beats |last beat
|
||||
0 1 2 3 4
|
||||
|
||||
=> (Delay - last beat) + x*BPM/60 (with x >= read_delay/BPM/60)
|
||||
Redis:
|
||||
bpm_sample_interval
|
||||
|........................|
|
||||
bpm_delay
|
||||
|.........................|
|
||||
|
||||
key bpm_sample_interval
|
||||
visual |........................|
|
||||
|
||||
key bpm_delay
|
||||
visual |.........................|
|
||||
|
||||
'''
|
||||
bpm = new_bpm
|
||||
bpm_sample_interval = SAMPLING_FREQUENCY * 1000
|
||||
bpm_delay = (SAMPLING_FREQUENCY + time.time() - start ) * 1000
|
||||
pexpireat = int( 2 * bpm_sample_interval);
|
||||
# Save to Redis
|
||||
r.set( 'bpm', new_bpm, px=( 2* int(SAMPLING_FREQUENCY * 1000)))
|
||||
r.set( 'bpm_sample_interval', SAMPLING_FREQUENCY )
|
||||
r.set( 'bpm', round(bpm,2), px = pexpireat )
|
||||
r.set( 'bpm_sample_interval', bpm_sample_interval )
|
||||
r.set( 'bpm_delay', bpm_delay )
|
||||
r.set( 'beats', json.dumps( beats.tolist() ) )
|
||||
debug( "bpm:{} bpm_delay:{} beats:{}".format(bpm,bpm_delay,beats) )
|
||||
#debug( "pexpireat:{}".format(pexpireat))
|
||||
debug( "bpm:{} bpm_delay:{} bpm_sample_interval:{} beats:{}".format(bpm,bpm_delay,bpm_sample_interval,beats) )
|
||||
return True
|
||||
|
||||
def m_spectrum(audio_data):
|
||||
@ -250,6 +260,7 @@ if MODE == 'spectrum':
|
||||
elif MODE == 'bpm':
|
||||
debug("In this mode, we will set keys: onset, bpm, beats")
|
||||
|
||||
p = pyaudio.PyAudio()
|
||||
stream = p.open(format=pyaudio.paFloat32,
|
||||
channels=CHANNELS,
|
||||
rate=RATE,
|
||||
|
Loading…
Reference in New Issue
Block a user