midi_write.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 import pygame
00003 import pygame.midi
00004 import select
00005 import sys
00006 import yaml
00007 import rospy
00008 import roslib
00009 import time
00010 import re
00011 from optparse import OptionParser
00012 
00013 roslib.load_manifest('jsk_teleop_joy')
00014 from jsk_teleop_joy.midi_util import MIDICommand, MIDIParse
00015 
00016 class MIDIWriteError(Exception):
00017   pass
00018 
00019 def parseRangedNumber(string):
00020   """
00021   string = 0-9 or [number-number] and this returns list of the numbers
00022   """
00023   try:                                    #0-0
00024     val = int(string)
00025     return [val]
00026   except ValueError:                      
00027     if string.startswith("[") and string.endswith("]"):
00028       # range representation
00029       r = re.compile("\[([0-9]+)-([0-9]+)\]")
00030       m = r.search(string)
00031       if m:
00032         first_number = m.group(1)
00033         last_number = m.group(2)
00034         return range(int(first_number), int(last_number) + 1)
00035       else:
00036         raise MIDIWriteError("failed to parse string: %s" % (string))
00037     else:
00038       raise MIDIWriteError("failed to parse string: %s" % (string))
00039     
00040 
00041 def main():
00042 
00043   all_midi_commands = ""
00044   for c in MIDICommand.allCommands():
00045     midi_command_str = "%s (%d)" % (MIDICommand.toStr(c), c)
00046     if len(all_midi_commands) > 0:
00047       all_midi_commands = "%s, %s (%d)" % (all_midi_commands, MIDICommand.toStr(c),
00048                                            c)
00049     else:
00050       all_midi_commands = midi_command_str
00051   parser = OptionParser()
00052   parser.add_option("--device_index", "-d", help="device index", type="int")
00053   parser.add_option("--midi_command", "-m", 
00054                     help="midi command: candidates are: " + all_midi_commands)
00055   parser.add_option("--channel", "-c", help="channel. You can specify the number in 0-9 or [from-to] format", default="0")
00056   parser.add_option("--param1", "-p", help="param1. You can specify the number in 0-9 or [from-to] format")
00057   parser.add_option("--param2", "-P", help="param2. You can specify the number in 0-9 or [from-to] format")
00058   parser.add_option("--interval", "-i", help="interval between each command", default=0.1, type="float")
00059   parser.add_option("--write", "-w", help="insert this output configuration into the configuration yaml")
00060   parser.add_option("--use-param1", help="this option is only available with -w option. It specifies to use parameter1 for the intensity", action="store_true")
00061   parser.add_option("--verbose", "-v", help="verbose", action="store_true")
00062   (options, args) = parser.parse_args()
00063 
00064   # check the argument
00065   if options.device_index == None:
00066     raise MIDIWriteError("You need to specify --device_index option")
00067   if options.midi_command == None:
00068     raise MIDIWriteError("You need to specify --midi_command option")
00069   if not options.write:
00070     if options.param1 == None:
00071       raise MIDIWriteError("You need to specify --param1 option")
00072     if options.param2 == None:
00073       raise MIDIWriteError("You need to specify --param2 option")
00074   else:
00075     pass
00076 
00077   # parse midi command
00078   midi_command = None
00079   try:
00080     midi_command = int(options.midi_command)
00081   except ValueError:
00082     # failed to parse integer, it might be a string
00083     for candidate in MIDICommand.allCommands():
00084       if MIDICommand.toStr(candidate).lower() == options.midi_command.lower():
00085         midi_command = candidate
00086 
00087   if midi_command == None:
00088     raise MIDIWriteError("Unknown midi command: %s" % (options.midi_command))
00089 
00090   # adding channel to midi_command
00091   pygame.midi.init()
00092   controller = pygame.midi.Output(options.device_index)
00093   if not options.write:
00094     for channel in parseRangedNumber(options.channel):
00095       midi_command_w_channel = midi_command | channel
00096       for param1 in parseRangedNumber(options.param1):
00097         for param2 in parseRangedNumber(options.param2):
00098           if options.verbose:
00099             print "Writing [%d, %d, %d] ([0x%X, 0x%X, 0x%X])" % (midi_command_w_channel, param1, param2,
00100                                                                  midi_command_w_channel, param1, param2)
00101           controller.write_short(midi_command_w_channel, param1, param2)
00102           rospy.sleep(options.interval)
00103   else:
00104     # open the yaml
00105     # type, id, intensity
00106     # configuration := command, channel, use_param1[, param1_value]
00107     with open(options.write, "r+") as f:
00108       config = yaml.load(f)
00109       if config.has_key("output"):
00110         output = config["output"]
00111       else:
00112         output = []
00113       for channel in parseRangedNumber(options.channel):
00114         if options.use_param1:
00115           configuration = (midi_command, channel, True)
00116           if configuration not in output:
00117             output.append(configuration)
00118         else:
00119           for param1 in parseRangedNumber(options.param1):
00120             configuration = (midi_command, channel, False, param1)
00121             if configuration not in output:
00122               output.append(configuration)
00123               print configuration
00124       config["output"] = output
00125       f.write(yaml.dump(config))
00126       f.close()
00127 if __name__ == "__main__":
00128   main()


jsk_teleop_joy
Author(s): Ryohei Ueda
autogenerated on Wed Jul 19 2017 02:54:50