Loading midmix.py 0 → 100644 +48 −0 Original line number Diff line number Diff line #k, 2019 import subprocess import time from player_functions import * import argparse # Arguments parser = argparse.ArgumentParser(description='a tool to play a mix of your favourite midi files') parser.add_argument('port',type=str,default="20:0",help='aplaymidi port number, can be found with `aplaymidi -l`') parser.add_argument('-d','--dir',type=dir_path,default=str(Path.home())+"/Music",help='(default: ~/Music), note: will traverse subdirectories') parser.add_argument('-p','--playlist',type=playlist,default=None,help='A playlist file') parser.add_argument('-r','--playlistrepeat',help='Repeat Playlist',action='store_true') args = parser.parse_args() # Initialize synth in GS Mode; The Roland RA30 will by default be in Electric Piano reset # mode until it either recieves a "GS Reset" or "GM System On" system exclusive # message. # Set device to GS Mode def Init(): print("Initializing synthisizer in mode") resetDevice(findAMIDIDevice()) time.sleep(1) # The Main Function. def Main(): fn_prefix="msmidi.py/Main" if(args.playlist is not None): print(fn_prefix+": opening playlist "+str(args.playlist)) playlist=open(args.playlist) while True: if(args.playlist is not None): next_track=playlist.readline() # If we have reached the end of the playlist, restart it. if not next_track: if(args.playlistrepeat==True): print(fn_prefix+": reached end of playlist. Repeat flag is true, repeating from the top.") playlist = open(args.playlist) else: print(fn_prefix+": reached end of playlist. Repeat flag is not set, terminating.") return else: next_track=queueRandom(args.dir); print(":Random selection is "+str(next_track)) playTrack(next_track,args.port) # wait just a sec time.sleep(1) Init(); Main(); player_functions.py 0 → 100644 +90 −0 Original line number Diff line number Diff line #k, 2019 import subprocess import time import requests import os import sys import random from pathlib import Path # Find the ID of the first MIDI device since I only have one def findAMIDIDevice(): # get the output of amidi -l which lists onboard midi devices result=subprocess.check_output(['amidi','-l']) # return the ID of the first one return result[result.find("hw:".encode('ascii')):result.find(",".encode('ascii'))].decode('ascii') # GM Mode= 'F07E7F0901F7' # GS Mode= 'F04110421240007F0041F7' # use amidi to send a reset command # The resetDevice function sends a GM or GS reset sysex command to the synthesizer. def resetDevice(device_id,mode='GS'): fn_prefix="player_functions.py/resetDevice" if(mode=="GM"): # send the sysex command for a GM Start to the synth using amidi subprocess.run(['amidi','-p',device_id,'-S','F07E7F0901F7']) print(fn_prefix+":Reset device to GM Mode") elif mode=="GS": # send the sysex command for a GS Reset to the synth using amidi subprocess.run(['amidi','-p',device_id,'-S','F04110421240007F0041F7']) print(fn_prefix+": Reset device to GS Mode") else: print(fn_prefix+": Invalid reset mode; must be GM or GS") return 0 return # The main player function def playTrack(track_path,port): fn_prefix="player_functions.py/playTrack" track_path=str(track_path).rstrip() if Path(track_path).is_file(): # reset the synth resetDevice(findAMIDIDevice()) print(fn_prefix+": starting aplaymidi subprocess on file "+str(track_path)) # Start the aplaymidi subprocess proc = subprocess.Popen(['aplaymidi', '--port', port, track_path], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) print(fn_prefix+": aplaymidi started, beginning playback") # Checks periodically to see if the track has ended # or if a stop command has been recieved try: retry=1 while retry==1: time.sleep(.5) if(proc.poll() is not None): retry=0 finally: # When we've stopped retrying, either because of stop command # or a finished track, terminate the subprocess if it hasn't already been proc.terminate() print(fn_prefix+": Recieved stop command") # send a GS reset to the synth resetDevice(findAMIDIDevice(),"GS") return else: print(fn_prefix+": failed to find file "+track_path+", skipping.") return # Get a random thing from the music folder # from https://codereview.stackexchange.com/questions/202749/pick-a-random-file-from-a-directory-tree def queueRandom(music_path): fn_prefix="player_functions.py/queueRandom" file_list = list(Path(music_path).glob(f"**/*.mid")) if not len(file_list): print(fn_prefix+": No files matched") return rand = random.randint(0, len(file_list) - 1) return file_list[rand] # Validate that a user-entered directory is a valid location to look for MIDIs def dir_path(string): if os.path.isdir(string): return string else: raise NotADirectoryError(string) # Validate that a user-entered playlist is a valid file def playlist(string): if os.path.isfile(string): return string else: raise NotAFile(string) Loading
midmix.py 0 → 100644 +48 −0 Original line number Diff line number Diff line #k, 2019 import subprocess import time from player_functions import * import argparse # Arguments parser = argparse.ArgumentParser(description='a tool to play a mix of your favourite midi files') parser.add_argument('port',type=str,default="20:0",help='aplaymidi port number, can be found with `aplaymidi -l`') parser.add_argument('-d','--dir',type=dir_path,default=str(Path.home())+"/Music",help='(default: ~/Music), note: will traverse subdirectories') parser.add_argument('-p','--playlist',type=playlist,default=None,help='A playlist file') parser.add_argument('-r','--playlistrepeat',help='Repeat Playlist',action='store_true') args = parser.parse_args() # Initialize synth in GS Mode; The Roland RA30 will by default be in Electric Piano reset # mode until it either recieves a "GS Reset" or "GM System On" system exclusive # message. # Set device to GS Mode def Init(): print("Initializing synthisizer in mode") resetDevice(findAMIDIDevice()) time.sleep(1) # The Main Function. def Main(): fn_prefix="msmidi.py/Main" if(args.playlist is not None): print(fn_prefix+": opening playlist "+str(args.playlist)) playlist=open(args.playlist) while True: if(args.playlist is not None): next_track=playlist.readline() # If we have reached the end of the playlist, restart it. if not next_track: if(args.playlistrepeat==True): print(fn_prefix+": reached end of playlist. Repeat flag is true, repeating from the top.") playlist = open(args.playlist) else: print(fn_prefix+": reached end of playlist. Repeat flag is not set, terminating.") return else: next_track=queueRandom(args.dir); print(":Random selection is "+str(next_track)) playTrack(next_track,args.port) # wait just a sec time.sleep(1) Init(); Main();
player_functions.py 0 → 100644 +90 −0 Original line number Diff line number Diff line #k, 2019 import subprocess import time import requests import os import sys import random from pathlib import Path # Find the ID of the first MIDI device since I only have one def findAMIDIDevice(): # get the output of amidi -l which lists onboard midi devices result=subprocess.check_output(['amidi','-l']) # return the ID of the first one return result[result.find("hw:".encode('ascii')):result.find(",".encode('ascii'))].decode('ascii') # GM Mode= 'F07E7F0901F7' # GS Mode= 'F04110421240007F0041F7' # use amidi to send a reset command # The resetDevice function sends a GM or GS reset sysex command to the synthesizer. def resetDevice(device_id,mode='GS'): fn_prefix="player_functions.py/resetDevice" if(mode=="GM"): # send the sysex command for a GM Start to the synth using amidi subprocess.run(['amidi','-p',device_id,'-S','F07E7F0901F7']) print(fn_prefix+":Reset device to GM Mode") elif mode=="GS": # send the sysex command for a GS Reset to the synth using amidi subprocess.run(['amidi','-p',device_id,'-S','F04110421240007F0041F7']) print(fn_prefix+": Reset device to GS Mode") else: print(fn_prefix+": Invalid reset mode; must be GM or GS") return 0 return # The main player function def playTrack(track_path,port): fn_prefix="player_functions.py/playTrack" track_path=str(track_path).rstrip() if Path(track_path).is_file(): # reset the synth resetDevice(findAMIDIDevice()) print(fn_prefix+": starting aplaymidi subprocess on file "+str(track_path)) # Start the aplaymidi subprocess proc = subprocess.Popen(['aplaymidi', '--port', port, track_path], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) print(fn_prefix+": aplaymidi started, beginning playback") # Checks periodically to see if the track has ended # or if a stop command has been recieved try: retry=1 while retry==1: time.sleep(.5) if(proc.poll() is not None): retry=0 finally: # When we've stopped retrying, either because of stop command # or a finished track, terminate the subprocess if it hasn't already been proc.terminate() print(fn_prefix+": Recieved stop command") # send a GS reset to the synth resetDevice(findAMIDIDevice(),"GS") return else: print(fn_prefix+": failed to find file "+track_path+", skipping.") return # Get a random thing from the music folder # from https://codereview.stackexchange.com/questions/202749/pick-a-random-file-from-a-directory-tree def queueRandom(music_path): fn_prefix="player_functions.py/queueRandom" file_list = list(Path(music_path).glob(f"**/*.mid")) if not len(file_list): print(fn_prefix+": No files matched") return rand = random.randint(0, len(file_list) - 1) return file_list[rand] # Validate that a user-entered directory is a valid location to look for MIDIs def dir_path(string): if os.path.isdir(string): return string else: raise NotADirectoryError(string) # Validate that a user-entered playlist is a valid file def playlist(string): if os.path.isfile(string): return string else: raise NotAFile(string)