[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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user