1*f81fb7c4SAndroid Build Coastguard Worker""" 2*f81fb7c4SAndroid Build Coastguard Worker File: 3*f81fb7c4SAndroid Build Coastguard Worker JetFile.py 4*f81fb7c4SAndroid Build Coastguard Worker 5*f81fb7c4SAndroid Build Coastguard Worker Contents and purpose: 6*f81fb7c4SAndroid Build Coastguard Worker Auditions a jet file to simulate interactive music functions 7*f81fb7c4SAndroid Build Coastguard Worker 8*f81fb7c4SAndroid Build Coastguard Worker Copyright (c) 2008 Android Open Source Project 9*f81fb7c4SAndroid Build Coastguard Worker 10*f81fb7c4SAndroid Build Coastguard Worker Licensed under the Apache License, Version 2.0 (the "License"); 11*f81fb7c4SAndroid Build Coastguard Worker you may not use this file except in compliance with the License. 12*f81fb7c4SAndroid Build Coastguard Worker You may obtain a copy of the License at 13*f81fb7c4SAndroid Build Coastguard Worker 14*f81fb7c4SAndroid Build Coastguard Worker http://www.apache.org/licenses/LICENSE-2.0 15*f81fb7c4SAndroid Build Coastguard Worker 16*f81fb7c4SAndroid Build Coastguard Worker Unless required by applicable law or agreed to in writing, software 17*f81fb7c4SAndroid Build Coastguard Worker distributed under the License is distributed on an "AS IS" BASIS, 18*f81fb7c4SAndroid Build Coastguard Worker WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19*f81fb7c4SAndroid Build Coastguard Worker See the License for the specific language governing permissions and 20*f81fb7c4SAndroid Build Coastguard Worker limitations under the License. 21*f81fb7c4SAndroid Build Coastguard Worker""" 22*f81fb7c4SAndroid Build Coastguard Worker 23*f81fb7c4SAndroid Build Coastguard Workerfrom __future__ import with_statement 24*f81fb7c4SAndroid Build Coastguard Worker 25*f81fb7c4SAndroid Build Coastguard Workerimport logging 26*f81fb7c4SAndroid Build Coastguard Workerimport ConfigParser 27*f81fb7c4SAndroid Build Coastguard Workerimport struct 28*f81fb7c4SAndroid Build Coastguard Workerimport os 29*f81fb7c4SAndroid Build Coastguard Workerimport sys 30*f81fb7c4SAndroid Build Coastguard Workerimport midifile 31*f81fb7c4SAndroid Build Coastguard Worker 32*f81fb7c4SAndroid Build Coastguard Workerfrom JetUtils import * 33*f81fb7c4SAndroid Build Coastguard Workerfrom JetDefs import * 34*f81fb7c4SAndroid Build Coastguard Worker 35*f81fb7c4SAndroid Build Coastguard WorkerVERSION = '0.1' 36*f81fb7c4SAndroid Build Coastguard Worker 37*f81fb7c4SAndroid Build Coastguard Worker# JET file defines 38*f81fb7c4SAndroid Build Coastguard WorkerJET_HEADER_STRUCT = '<4sl' 39*f81fb7c4SAndroid Build Coastguard WorkerJET_HEADER_TAG = 'JET ' 40*f81fb7c4SAndroid Build Coastguard WorkerJET_VERSION = 0x01000000 41*f81fb7c4SAndroid Build Coastguard Worker 42*f81fb7c4SAndroid Build Coastguard Worker# JET chunk tags 43*f81fb7c4SAndroid Build Coastguard WorkerJET_INFO_CHUNK = 'JINF' 44*f81fb7c4SAndroid Build Coastguard WorkerJET_SMF_CHUNK = 'JSMF' 45*f81fb7c4SAndroid Build Coastguard WorkerJET_DLS_CHUNK = 'JDLS' 46*f81fb7c4SAndroid Build Coastguard Worker 47*f81fb7c4SAndroid Build Coastguard Worker# JINF defines 48*f81fb7c4SAndroid Build Coastguard WorkerJINF_STRUCT = '<4sl4sl4sl4sl' 49*f81fb7c4SAndroid Build Coastguard WorkerJINF_JET_VERSION = 'JVER' 50*f81fb7c4SAndroid Build Coastguard WorkerJINF_NUM_SMF_CHUNKS = 'SMF#' 51*f81fb7c4SAndroid Build Coastguard WorkerJINF_NUM_DLS_CHUNKS = 'DLS#' 52*f81fb7c4SAndroid Build Coastguard Worker 53*f81fb7c4SAndroid Build Coastguard Worker# JCOP defines 54*f81fb7c4SAndroid Build Coastguard WorkerJCOP_STRUCT = '<4sl' 55*f81fb7c4SAndroid Build Coastguard WorkerJCOP_CHUNK = 'JCOP' 56*f81fb7c4SAndroid Build Coastguard Worker 57*f81fb7c4SAndroid Build Coastguard Worker# JAPP defines 58*f81fb7c4SAndroid Build Coastguard WorkerJAPP_STRUCT = '<4sl' 59*f81fb7c4SAndroid Build Coastguard WorkerJAPP_CHUNK = 'JAPP' 60*f81fb7c4SAndroid Build Coastguard Worker 61*f81fb7c4SAndroid Build Coastguard Worker# config file defines 62*f81fb7c4SAndroid Build Coastguard WorkerOUTPUT_SECTION = 'output' 63*f81fb7c4SAndroid Build Coastguard WorkerOUTPUT_FILENAME = 'filename' 64*f81fb7c4SAndroid Build Coastguard WorkerOUTPUT_COPYRIGHT = 'copyright' 65*f81fb7c4SAndroid Build Coastguard WorkerOUTPUT_APP_DATA = 'app_data' 66*f81fb7c4SAndroid Build Coastguard WorkerOUTPUT_CHASE_CONTROLLERS = 'chase_controllers' 67*f81fb7c4SAndroid Build Coastguard WorkerOUTPUT_OMIT_EMPTY_TRACKS = 'omit_empty_tracks' 68*f81fb7c4SAndroid Build Coastguard WorkerSEGMENT_SECTION = 'segment' 69*f81fb7c4SAndroid Build Coastguard WorkerSEGMENT_FILENAME = 'filename' 70*f81fb7c4SAndroid Build Coastguard WorkerSEGMENT_DLSFILE = 'dlsfile' 71*f81fb7c4SAndroid Build Coastguard WorkerSEGMENT_NAME = 'segname' 72*f81fb7c4SAndroid Build Coastguard WorkerSEGMENT_START = 'start' 73*f81fb7c4SAndroid Build Coastguard WorkerSEGMENT_END = 'end' 74*f81fb7c4SAndroid Build Coastguard WorkerSEGMENT_END_MARKER = 'end_marker' 75*f81fb7c4SAndroid Build Coastguard WorkerSEGMENT_QUANTIZE = 'quantize' 76*f81fb7c4SAndroid Build Coastguard WorkerSEGMENT_OUTPUT = 'output' 77*f81fb7c4SAndroid Build Coastguard WorkerSEGMENT_LENGTH = 'length' 78*f81fb7c4SAndroid Build Coastguard WorkerSEGMENT_DUMP_FILE = 'dump' 79*f81fb7c4SAndroid Build Coastguard WorkerSEGMENT_TRANSPOSE = 'transpose' 80*f81fb7c4SAndroid Build Coastguard WorkerSEGMENT_REPEAT = 'repeat' 81*f81fb7c4SAndroid Build Coastguard WorkerSEGMENT_MUTE_FLAGS = 'mute_flags' 82*f81fb7c4SAndroid Build Coastguard WorkerLIBRARY_SECTION = 'libraries' 83*f81fb7c4SAndroid Build Coastguard WorkerLIBRARY_FILENAME = 'lib' 84*f81fb7c4SAndroid Build Coastguard WorkerCLIP_PREFIX = 'clip' 85*f81fb7c4SAndroid Build Coastguard WorkerAPP_PREFIX = 'app' 86*f81fb7c4SAndroid Build Coastguard Worker 87*f81fb7c4SAndroid Build Coastguard Worker# JET events 88*f81fb7c4SAndroid Build Coastguard WorkerJET_EVENT_MARKER = 102 89*f81fb7c4SAndroid Build Coastguard WorkerJET_MARKER_LOOP_END = 0 90*f81fb7c4SAndroid Build Coastguard WorkerJET_EVENT_TRIGGER_CLIP = 103 91*f81fb7c4SAndroid Build Coastguard Worker 92*f81fb7c4SAndroid Build Coastguard Workerclass JetSegment (object): 93*f81fb7c4SAndroid Build Coastguard Worker """ Class to hold segments """ 94*f81fb7c4SAndroid Build Coastguard Worker def __init__ (self, segname, filename, start=None, end=None, length=None, output=None, quantize=None, jetevents=[], dlsfile=None, dump_file=None, transpose=0, repeat=0, mute_flags=0): 95*f81fb7c4SAndroid Build Coastguard Worker self.segname = segname 96*f81fb7c4SAndroid Build Coastguard Worker self.filename = filename 97*f81fb7c4SAndroid Build Coastguard Worker self.dlsfile = dlsfile 98*f81fb7c4SAndroid Build Coastguard Worker self.start = start 99*f81fb7c4SAndroid Build Coastguard Worker self.end = end 100*f81fb7c4SAndroid Build Coastguard Worker self.length = length 101*f81fb7c4SAndroid Build Coastguard Worker self.output = output 102*f81fb7c4SAndroid Build Coastguard Worker self.quantize = quantize 103*f81fb7c4SAndroid Build Coastguard Worker self.dump_file = dump_file 104*f81fb7c4SAndroid Build Coastguard Worker self.jetevents = jetevents 105*f81fb7c4SAndroid Build Coastguard Worker #API FIELDS FOR UI 106*f81fb7c4SAndroid Build Coastguard Worker self.transpose = transpose 107*f81fb7c4SAndroid Build Coastguard Worker self.repeat = repeat 108*f81fb7c4SAndroid Build Coastguard Worker self.mute_flags = mute_flags 109*f81fb7c4SAndroid Build Coastguard Worker 110*f81fb7c4SAndroid Build Coastguard Workerclass JetEvent (object): 111*f81fb7c4SAndroid Build Coastguard Worker """ Class to hold events """ 112*f81fb7c4SAndroid Build Coastguard Worker def __init__(self, event_name, event_type, event_id, track_num, channel_num, event_start, event_end): 113*f81fb7c4SAndroid Build Coastguard Worker self.event_name = event_name 114*f81fb7c4SAndroid Build Coastguard Worker self.event_type = event_type 115*f81fb7c4SAndroid Build Coastguard Worker self.event_id = event_id 116*f81fb7c4SAndroid Build Coastguard Worker self.track_num = track_num 117*f81fb7c4SAndroid Build Coastguard Worker self.channel_num = channel_num 118*f81fb7c4SAndroid Build Coastguard Worker self.event_start = event_start 119*f81fb7c4SAndroid Build Coastguard Worker self.event_end = event_end 120*f81fb7c4SAndroid Build Coastguard Worker 121*f81fb7c4SAndroid Build Coastguard Workerclass JetFileException (Exception): 122*f81fb7c4SAndroid Build Coastguard Worker """ Exceptions class """ 123*f81fb7c4SAndroid Build Coastguard Worker def __init__ (self, msg): 124*f81fb7c4SAndroid Build Coastguard Worker self.msg = msg 125*f81fb7c4SAndroid Build Coastguard Worker def __str__ (self): 126*f81fb7c4SAndroid Build Coastguard Worker return self.msg 127*f81fb7c4SAndroid Build Coastguard Worker 128*f81fb7c4SAndroid Build Coastguard Workerclass JetSegmentFile (midifile.MIDIFile): 129*f81fb7c4SAndroid Build Coastguard Worker def ConvertMusicTimeToTicks (self, s): 130*f81fb7c4SAndroid Build Coastguard Worker measures, beats, ticks = s.split(':',3) 131*f81fb7c4SAndroid Build Coastguard Worker return self.ConvertToTicks(int(measures), int(beats), int(ticks)) 132*f81fb7c4SAndroid Build Coastguard Worker 133*f81fb7c4SAndroid Build Coastguard Worker def ExtractEvents (self, start, end, length, quantize, chase_controllers): 134*f81fb7c4SAndroid Build Coastguard Worker if (start is None) and (end is None) and (length is None): 135*f81fb7c4SAndroid Build Coastguard Worker logging.debug('ExtractEvents: No change') 136*f81fb7c4SAndroid Build Coastguard Worker return 137*f81fb7c4SAndroid Build Coastguard Worker 138*f81fb7c4SAndroid Build Coastguard Worker if start is not None: 139*f81fb7c4SAndroid Build Coastguard Worker start = self.ConvertMusicTimeToTicks(start) 140*f81fb7c4SAndroid Build Coastguard Worker else: 141*f81fb7c4SAndroid Build Coastguard Worker start = 0 142*f81fb7c4SAndroid Build Coastguard Worker if end is not None: 143*f81fb7c4SAndroid Build Coastguard Worker end = self.ConvertMusicTimeToTicks(end) 144*f81fb7c4SAndroid Build Coastguard Worker elif length is not None: 145*f81fb7c4SAndroid Build Coastguard Worker length = self.ConvertMusicTimeToTicks(length) 146*f81fb7c4SAndroid Build Coastguard Worker end = start + length 147*f81fb7c4SAndroid Build Coastguard Worker 148*f81fb7c4SAndroid Build Coastguard Worker if quantize is not None: 149*f81fb7c4SAndroid Build Coastguard Worker quantize = int(quantize) 150*f81fb7c4SAndroid Build Coastguard Worker else: 151*f81fb7c4SAndroid Build Coastguard Worker quantize = 0 152*f81fb7c4SAndroid Build Coastguard Worker 153*f81fb7c4SAndroid Build Coastguard Worker self.Trim(start, end, quantize, chase_controllers=chase_controllers) 154*f81fb7c4SAndroid Build Coastguard Worker #self.DumpTracks() 155*f81fb7c4SAndroid Build Coastguard Worker 156*f81fb7c4SAndroid Build Coastguard Worker def SyncClips (self): 157*f81fb7c4SAndroid Build Coastguard Worker """Add controller events to the start of a clip to keep it synced.""" 158*f81fb7c4SAndroid Build Coastguard Worker values = None 159*f81fb7c4SAndroid Build Coastguard Worker last_seq = 0 160*f81fb7c4SAndroid Build Coastguard Worker for track in self.tracks: 161*f81fb7c4SAndroid Build Coastguard Worker for event in track.events: 162*f81fb7c4SAndroid Build Coastguard Worker 163*f81fb7c4SAndroid Build Coastguard Worker # find start of clip and chase events from last save point 164*f81fb7c4SAndroid Build Coastguard Worker if (event.msg_type == midifile.CONTROL_CHANGE) and \ 165*f81fb7c4SAndroid Build Coastguard Worker (event.controller == JET_EVENT_TRIGGER_CLIP) and \ 166*f81fb7c4SAndroid Build Coastguard Worker ((event.value & 0x40) == 0x40): 167*f81fb7c4SAndroid Build Coastguard Worker logging.debug('Syncing clip at %d ticks' % event.ticks) 168*f81fb7c4SAndroid Build Coastguard Worker values = track.events.ChaseControllers(event.seq, last_seq, values) 169*f81fb7c4SAndroid Build Coastguard Worker 170*f81fb7c4SAndroid Build Coastguard Worker #BTH; Seems to fix chase controller bug when multiple clips within segment 171*f81fb7c4SAndroid Build Coastguard Worker #last_seq = event.seq 172*f81fb7c4SAndroid Build Coastguard Worker 173*f81fb7c4SAndroid Build Coastguard Worker # generate event list from default values 174*f81fb7c4SAndroid Build Coastguard Worker clip_events = values.GenerateEventList(event.ticks) 175*f81fb7c4SAndroid Build Coastguard Worker 176*f81fb7c4SAndroid Build Coastguard Worker #for evt in clip_events: 177*f81fb7c4SAndroid Build Coastguard Worker # logging.info(evt) 178*f81fb7c4SAndroid Build Coastguard Worker 179*f81fb7c4SAndroid Build Coastguard Worker track.events.InsertEvents(clip_events, event.seq + 1) 180*f81fb7c4SAndroid Build Coastguard Worker 181*f81fb7c4SAndroid Build Coastguard Worker def AddJetEvents (self, jetevents): 182*f81fb7c4SAndroid Build Coastguard Worker for jet_event in jetevents: 183*f81fb7c4SAndroid Build Coastguard Worker if jet_event.event_type == JetDefs.E_CLIP: 184*f81fb7c4SAndroid Build Coastguard Worker #DumpEvent(jet_event) 185*f81fb7c4SAndroid Build Coastguard Worker 186*f81fb7c4SAndroid Build Coastguard Worker # sanity check 187*f81fb7c4SAndroid Build Coastguard Worker if jet_event.track_num >= len(self.tracks): 188*f81fb7c4SAndroid Build Coastguard Worker raise JetFileException('Track number %d of out of range for clip' % jet_event.track_num) 189*f81fb7c4SAndroid Build Coastguard Worker if jet_event.channel_num > 15: 190*f81fb7c4SAndroid Build Coastguard Worker raise JetFileException('Channel number %d of out of range for clip' % jet_event.channel_num) 191*f81fb7c4SAndroid Build Coastguard Worker if jet_event.event_id > 63: 192*f81fb7c4SAndroid Build Coastguard Worker raise JetFileException('event_id %d of out of range for clip' % jet_event.event_id) 193*f81fb7c4SAndroid Build Coastguard Worker 194*f81fb7c4SAndroid Build Coastguard Worker logging.debug('Adding trigger event for clip %d @ %s and %s' % (jet_event.event_id, jet_event.event_start, jet_event.event_end)) 195*f81fb7c4SAndroid Build Coastguard Worker 196*f81fb7c4SAndroid Build Coastguard Worker events = midifile.EventList() 197*f81fb7c4SAndroid Build Coastguard Worker events.append(midifile.ControlChangeEvent( 198*f81fb7c4SAndroid Build Coastguard Worker self.ConvertMusicTimeToTicks(jet_event.event_start), 199*f81fb7c4SAndroid Build Coastguard Worker 0, 200*f81fb7c4SAndroid Build Coastguard Worker jet_event.channel_num, 201*f81fb7c4SAndroid Build Coastguard Worker JET_EVENT_TRIGGER_CLIP, 202*f81fb7c4SAndroid Build Coastguard Worker jet_event.event_id | 0x40)) 203*f81fb7c4SAndroid Build Coastguard Worker 204*f81fb7c4SAndroid Build Coastguard Worker events.append(midifile.ControlChangeEvent( 205*f81fb7c4SAndroid Build Coastguard Worker self.ConvertMusicTimeToTicks(jet_event.event_end), 206*f81fb7c4SAndroid Build Coastguard Worker sys.maxint, 207*f81fb7c4SAndroid Build Coastguard Worker jet_event.channel_num, 208*f81fb7c4SAndroid Build Coastguard Worker JET_EVENT_TRIGGER_CLIP, 209*f81fb7c4SAndroid Build Coastguard Worker jet_event.event_id)) 210*f81fb7c4SAndroid Build Coastguard Worker 211*f81fb7c4SAndroid Build Coastguard Worker # merge trigger events 212*f81fb7c4SAndroid Build Coastguard Worker self.tracks[jet_event.track_num].events.MergeEvents(events) 213*f81fb7c4SAndroid Build Coastguard Worker 214*f81fb7c4SAndroid Build Coastguard Worker elif jet_event.event_type == JetDefs.E_EOS: 215*f81fb7c4SAndroid Build Coastguard Worker if jet_event.track_num >= len(self.tracks): 216*f81fb7c4SAndroid Build Coastguard Worker raise JetFileException('Track number %d of out of range for end marker' % jet_event.track_num) 217*f81fb7c4SAndroid Build Coastguard Worker if jet_event.channel_num > 15: 218*f81fb7c4SAndroid Build Coastguard Worker raise JetFileException('Channel number %d of out of range for end marker' % jet_event.channel_num) 219*f81fb7c4SAndroid Build Coastguard Worker 220*f81fb7c4SAndroid Build Coastguard Worker events = midifile.EventList() 221*f81fb7c4SAndroid Build Coastguard Worker logging.debug('Adding end marker at %s' % jet_event.event_start) 222*f81fb7c4SAndroid Build Coastguard Worker events.append(midifile.ControlChangeEvent( 223*f81fb7c4SAndroid Build Coastguard Worker self.ConvertMusicTimeToTicks(jet_event.event_start), 224*f81fb7c4SAndroid Build Coastguard Worker 0, 225*f81fb7c4SAndroid Build Coastguard Worker jet_event.channel_num, 226*f81fb7c4SAndroid Build Coastguard Worker JET_EVENT_MARKER, 227*f81fb7c4SAndroid Build Coastguard Worker JET_MARKER_LOOP_END)) 228*f81fb7c4SAndroid Build Coastguard Worker self.tracks[jet_event.track_num].events.MergeEvents(events) 229*f81fb7c4SAndroid Build Coastguard Worker 230*f81fb7c4SAndroid Build Coastguard Worker elif jet_event.event_type == JetDefs.E_APP: 231*f81fb7c4SAndroid Build Coastguard Worker if jet_event.track_num >= len(self.tracks): 232*f81fb7c4SAndroid Build Coastguard Worker raise JetFileException('Track number %d of out of range for app marker' % jet_event.track_num) 233*f81fb7c4SAndroid Build Coastguard Worker if jet_event.channel_num > 15: 234*f81fb7c4SAndroid Build Coastguard Worker raise JetFileException('Channel number %d of out of range for app marker' % jet_event.channel_num) 235*f81fb7c4SAndroid Build Coastguard Worker if jet_event.event_id > 83 or jet_event.event_id < 80: 236*f81fb7c4SAndroid Build Coastguard Worker raise JetFileException('EventID %d out of range for application controller' % jet_event.event_id) 237*f81fb7c4SAndroid Build Coastguard Worker 238*f81fb7c4SAndroid Build Coastguard Worker events = midifile.EventList() 239*f81fb7c4SAndroid Build Coastguard Worker logging.debug('Adding application controller at %s' % jet_event.event_start) 240*f81fb7c4SAndroid Build Coastguard Worker events.append(midifile.ControlChangeEvent( 241*f81fb7c4SAndroid Build Coastguard Worker self.ConvertMusicTimeToTicks(jet_event.event_start), 242*f81fb7c4SAndroid Build Coastguard Worker 0, 243*f81fb7c4SAndroid Build Coastguard Worker jet_event.channel_num, 244*f81fb7c4SAndroid Build Coastguard Worker jet_event.event_id, 245*f81fb7c4SAndroid Build Coastguard Worker jet_event.event_id)) 246*f81fb7c4SAndroid Build Coastguard Worker self.tracks[jet_event.track_num].events.MergeEvents(events) 247*f81fb7c4SAndroid Build Coastguard Worker 248*f81fb7c4SAndroid Build Coastguard Workerclass JetFile (object): 249*f81fb7c4SAndroid Build Coastguard Worker """Write a JET file based on a configuration file.""" 250*f81fb7c4SAndroid Build Coastguard Worker def __init__ (self, config_file, options): 251*f81fb7c4SAndroid Build Coastguard Worker self.config_file = config_file 252*f81fb7c4SAndroid Build Coastguard Worker self.config = config = ConfigParser.ConfigParser() 253*f81fb7c4SAndroid Build Coastguard Worker if self.config_file == "": 254*f81fb7c4SAndroid Build Coastguard Worker self.InitializeConfig(JetDefs.UNTITLED_FILE) 255*f81fb7c4SAndroid Build Coastguard Worker if not FileExists(self.config_file): 256*f81fb7c4SAndroid Build Coastguard Worker self.InitializeConfig(self.config_file) 257*f81fb7c4SAndroid Build Coastguard Worker 258*f81fb7c4SAndroid Build Coastguard Worker config.read(self.config_file) 259*f81fb7c4SAndroid Build Coastguard Worker self.ParseConfig(options) 260*f81fb7c4SAndroid Build Coastguard Worker 261*f81fb7c4SAndroid Build Coastguard Worker def DumpConfig (self): 262*f81fb7c4SAndroid Build Coastguard Worker """Drump configuration to log file.""" 263*f81fb7c4SAndroid Build Coastguard Worker # dump configuration 264*f81fb7c4SAndroid Build Coastguard Worker config = self.config 265*f81fb7c4SAndroid Build Coastguard Worker for section in config.sections(): 266*f81fb7c4SAndroid Build Coastguard Worker logging.debug('[%s]' % section) 267*f81fb7c4SAndroid Build Coastguard Worker for option, value in config.items(section): 268*f81fb7c4SAndroid Build Coastguard Worker logging.debug('%s: %s' % (option, value)) 269*f81fb7c4SAndroid Build Coastguard Worker 270*f81fb7c4SAndroid Build Coastguard Worker def ParseConfig (self, options): 271*f81fb7c4SAndroid Build Coastguard Worker """Validate the configuration.""" 272*f81fb7c4SAndroid Build Coastguard Worker # check for output name 273*f81fb7c4SAndroid Build Coastguard Worker config = self.config 274*f81fb7c4SAndroid Build Coastguard Worker if config.has_option(OUTPUT_SECTION, OUTPUT_FILENAME): 275*f81fb7c4SAndroid Build Coastguard Worker config.filename = config.get(OUTPUT_SECTION, OUTPUT_FILENAME) 276*f81fb7c4SAndroid Build Coastguard Worker else: 277*f81fb7c4SAndroid Build Coastguard Worker raise JetFileException('No output filename in configuration file') 278*f81fb7c4SAndroid Build Coastguard Worker if config.filename == '' or config.filename == None: 279*f81fb7c4SAndroid Build Coastguard Worker config.filename = FileJustRoot(self.config_file) + ".JET" 280*f81fb7c4SAndroid Build Coastguard Worker config.chase_controllers = True 281*f81fb7c4SAndroid Build Coastguard Worker if config.has_option(OUTPUT_SECTION, OUTPUT_CHASE_CONTROLLERS): 282*f81fb7c4SAndroid Build Coastguard Worker try: 283*f81fb7c4SAndroid Build Coastguard Worker config.chase_controllers = config.getboolean(OUTPUT_SECTION, OUTPUT_CHASE_CONTROLLERS) 284*f81fb7c4SAndroid Build Coastguard Worker except: 285*f81fb7c4SAndroid Build Coastguard Worker pass 286*f81fb7c4SAndroid Build Coastguard Worker 287*f81fb7c4SAndroid Build Coastguard Worker config.delete_empty_tracks = False 288*f81fb7c4SAndroid Build Coastguard Worker if config.has_option(OUTPUT_SECTION, OUTPUT_OMIT_EMPTY_TRACKS): 289*f81fb7c4SAndroid Build Coastguard Worker try: 290*f81fb7c4SAndroid Build Coastguard Worker config.delete_empty_tracks = config.getboolean(OUTPUT_SECTION, OUTPUT_OMIT_EMPTY_TRACKS) 291*f81fb7c4SAndroid Build Coastguard Worker except: 292*f81fb7c4SAndroid Build Coastguard Worker pass 293*f81fb7c4SAndroid Build Coastguard Worker 294*f81fb7c4SAndroid Build Coastguard Worker config.copyright = None 295*f81fb7c4SAndroid Build Coastguard Worker if config.has_option(OUTPUT_SECTION, OUTPUT_COPYRIGHT): 296*f81fb7c4SAndroid Build Coastguard Worker config.copyright = config.get(OUTPUT_SECTION, OUTPUT_COPYRIGHT) 297*f81fb7c4SAndroid Build Coastguard Worker 298*f81fb7c4SAndroid Build Coastguard Worker config.app_data = None 299*f81fb7c4SAndroid Build Coastguard Worker if config.has_option(OUTPUT_SECTION, OUTPUT_APP_DATA): 300*f81fb7c4SAndroid Build Coastguard Worker config.app_data = config.get(OUTPUT_SECTION, OUTPUT_APP_DATA) 301*f81fb7c4SAndroid Build Coastguard Worker 302*f81fb7c4SAndroid Build Coastguard Worker # count segments 303*f81fb7c4SAndroid Build Coastguard Worker segments = [] 304*f81fb7c4SAndroid Build Coastguard Worker seg_num = 0 305*f81fb7c4SAndroid Build Coastguard Worker while 1: 306*f81fb7c4SAndroid Build Coastguard Worker 307*f81fb7c4SAndroid Build Coastguard Worker # check for segment section 308*f81fb7c4SAndroid Build Coastguard Worker segment_name = SEGMENT_SECTION + str(seg_num) 309*f81fb7c4SAndroid Build Coastguard Worker if not config.has_section(segment_name): 310*f81fb7c4SAndroid Build Coastguard Worker break 311*f81fb7c4SAndroid Build Coastguard Worker 312*f81fb7c4SAndroid Build Coastguard Worker # initialize some parameters 313*f81fb7c4SAndroid Build Coastguard Worker start = end = length = output = end_marker = dlsfile = dump_file = None 314*f81fb7c4SAndroid Build Coastguard Worker transpose = repeat = mute_flags = 0 315*f81fb7c4SAndroid Build Coastguard Worker jetevents = [] 316*f81fb7c4SAndroid Build Coastguard Worker 317*f81fb7c4SAndroid Build Coastguard Worker # get the segment parameters 318*f81fb7c4SAndroid Build Coastguard Worker segname = config.get(segment_name, SEGMENT_NAME) 319*f81fb7c4SAndroid Build Coastguard Worker filename = config.get(segment_name, SEGMENT_FILENAME) 320*f81fb7c4SAndroid Build Coastguard Worker if config.has_option(segment_name, SEGMENT_DLSFILE): 321*f81fb7c4SAndroid Build Coastguard Worker dlsfile = config.get(segment_name, SEGMENT_DLSFILE) 322*f81fb7c4SAndroid Build Coastguard Worker if config.has_option(segment_name, SEGMENT_START): 323*f81fb7c4SAndroid Build Coastguard Worker start = config.get(segment_name, SEGMENT_START) 324*f81fb7c4SAndroid Build Coastguard Worker if config.has_option(segment_name, SEGMENT_END): 325*f81fb7c4SAndroid Build Coastguard Worker end = config.get(segment_name, SEGMENT_END) 326*f81fb7c4SAndroid Build Coastguard Worker if config.has_option(segment_name, SEGMENT_LENGTH): 327*f81fb7c4SAndroid Build Coastguard Worker length = config.get(segment_name, SEGMENT_LENGTH) 328*f81fb7c4SAndroid Build Coastguard Worker if config.has_option(segment_name, SEGMENT_OUTPUT): 329*f81fb7c4SAndroid Build Coastguard Worker output = config.get(segment_name, SEGMENT_OUTPUT) 330*f81fb7c4SAndroid Build Coastguard Worker if config.has_option(segment_name, SEGMENT_QUANTIZE): 331*f81fb7c4SAndroid Build Coastguard Worker quantize = config.get(segment_name, SEGMENT_QUANTIZE) 332*f81fb7c4SAndroid Build Coastguard Worker if config.has_option(segment_name, SEGMENT_DUMP_FILE): 333*f81fb7c4SAndroid Build Coastguard Worker dump_file = config.get(segment_name, SEGMENT_DUMP_FILE) 334*f81fb7c4SAndroid Build Coastguard Worker #API FIELDS 335*f81fb7c4SAndroid Build Coastguard Worker if config.has_option(segment_name, SEGMENT_TRANSPOSE): 336*f81fb7c4SAndroid Build Coastguard Worker transpose = config.get(segment_name, SEGMENT_TRANSPOSE) 337*f81fb7c4SAndroid Build Coastguard Worker if config.has_option(segment_name, SEGMENT_REPEAT): 338*f81fb7c4SAndroid Build Coastguard Worker repeat = config.get(segment_name, SEGMENT_REPEAT) 339*f81fb7c4SAndroid Build Coastguard Worker if config.has_option(segment_name, SEGMENT_MUTE_FLAGS): 340*f81fb7c4SAndroid Build Coastguard Worker mute_flags = config.get(segment_name, SEGMENT_MUTE_FLAGS) 341*f81fb7c4SAndroid Build Coastguard Worker 342*f81fb7c4SAndroid Build Coastguard Worker if config.has_option(segment_name, SEGMENT_END_MARKER): 343*f81fb7c4SAndroid Build Coastguard Worker end_marker = config.get(segment_name, SEGMENT_END_MARKER) 344*f81fb7c4SAndroid Build Coastguard Worker track_num, channel_num, event_time = end_marker.split(',',2) 345*f81fb7c4SAndroid Build Coastguard Worker #jetevents.append((JetDefs.E_EOS, 0, int(track_num), int(channel_num), event_time, '')) 346*f81fb7c4SAndroid Build Coastguard Worker jetevents.append(JetEvent(JetDefs.E_EOS, JetDefs.E_EOS, 0, int(track_num), int(channel_num), event_time, event_time)) 347*f81fb7c4SAndroid Build Coastguard Worker 348*f81fb7c4SAndroid Build Coastguard Worker # check for jetevents 349*f81fb7c4SAndroid Build Coastguard Worker for jetevent, location in config.items(segment_name): 350*f81fb7c4SAndroid Build Coastguard Worker if jetevent.startswith(CLIP_PREFIX): 351*f81fb7c4SAndroid Build Coastguard Worker event_name, event_id, track_num, channel_num, event_start, event_end = location.split(',', 5) 352*f81fb7c4SAndroid Build Coastguard Worker jetevents.append(JetEvent(event_name, JetDefs.E_CLIP, int(event_id), int(track_num), int(channel_num), event_start, event_end)) 353*f81fb7c4SAndroid Build Coastguard Worker 354*f81fb7c4SAndroid Build Coastguard Worker # check for appevents 355*f81fb7c4SAndroid Build Coastguard Worker for jetevent, location in config.items(segment_name): 356*f81fb7c4SAndroid Build Coastguard Worker if jetevent.startswith(APP_PREFIX): 357*f81fb7c4SAndroid Build Coastguard Worker event_name, event_id, track_num, channel_num, event_start, event_end = location.split(',', 5) 358*f81fb7c4SAndroid Build Coastguard Worker jetevents.append(JetEvent(event_name, JetDefs.E_APP, int(event_id), int(track_num), int(channel_num), event_start, event_end)) 359*f81fb7c4SAndroid Build Coastguard Worker 360*f81fb7c4SAndroid Build Coastguard Worker segments.append(JetSegment(segname, filename, start, end, length, output, quantize, jetevents, dlsfile, dump_file, int(transpose), int(repeat), int(mute_flags))) 361*f81fb7c4SAndroid Build Coastguard Worker seg_num += 1 362*f81fb7c4SAndroid Build Coastguard Worker 363*f81fb7c4SAndroid Build Coastguard Worker self.segments = segments 364*f81fb7c4SAndroid Build Coastguard Worker if not len(segments): 365*f81fb7c4SAndroid Build Coastguard Worker #TODO: Check for segments when writing 366*f81fb7c4SAndroid Build Coastguard Worker #raise JetFileException('No segments defined in configuration file') 367*f81fb7c4SAndroid Build Coastguard Worker pass 368*f81fb7c4SAndroid Build Coastguard Worker 369*f81fb7c4SAndroid Build Coastguard Worker # count libraries 370*f81fb7c4SAndroid Build Coastguard Worker libraries = [] 371*f81fb7c4SAndroid Build Coastguard Worker lib_num = 0 372*f81fb7c4SAndroid Build Coastguard Worker while 1: 373*f81fb7c4SAndroid Build Coastguard Worker library_name = LIBRARY_FILENAME + str(lib_num) 374*f81fb7c4SAndroid Build Coastguard Worker if not config.has_option(LIBRARY_SECTION, library_name): 375*f81fb7c4SAndroid Build Coastguard Worker break 376*f81fb7c4SAndroid Build Coastguard Worker libraries.append(config.get(LIBRARY_SECTION, library_name)) 377*f81fb7c4SAndroid Build Coastguard Worker lib_num += 1 378*f81fb7c4SAndroid Build Coastguard Worker self.libraries = libraries 379*f81fb7c4SAndroid Build Coastguard Worker 380*f81fb7c4SAndroid Build Coastguard Worker def WriteJetFileFromConfig (self, options): 381*f81fb7c4SAndroid Build Coastguard Worker """Write JET file from config file.""" 382*f81fb7c4SAndroid Build Coastguard Worker 383*f81fb7c4SAndroid Build Coastguard Worker # open the output file and write the header 384*f81fb7c4SAndroid Build Coastguard Worker output_file = open(self.config.filename, 'wb') 385*f81fb7c4SAndroid Build Coastguard Worker jet_header = struct.pack(JET_HEADER_STRUCT, JET_HEADER_TAG, 0) 386*f81fb7c4SAndroid Build Coastguard Worker output_file.write(jet_header) 387*f81fb7c4SAndroid Build Coastguard Worker 388*f81fb7c4SAndroid Build Coastguard Worker # write the JINF chunk 389*f81fb7c4SAndroid Build Coastguard Worker jet_info = struct.pack(JINF_STRUCT, 390*f81fb7c4SAndroid Build Coastguard Worker JET_INFO_CHUNK, struct.calcsize(JINF_STRUCT) - 8, 391*f81fb7c4SAndroid Build Coastguard Worker JINF_JET_VERSION, JET_VERSION, 392*f81fb7c4SAndroid Build Coastguard Worker JINF_NUM_SMF_CHUNKS, len(self.segments), 393*f81fb7c4SAndroid Build Coastguard Worker JINF_NUM_DLS_CHUNKS, len(self.libraries)) 394*f81fb7c4SAndroid Build Coastguard Worker output_file.write(jet_info) 395*f81fb7c4SAndroid Build Coastguard Worker 396*f81fb7c4SAndroid Build Coastguard Worker # write the JCOP chunk (if any) 397*f81fb7c4SAndroid Build Coastguard Worker if self.config.copyright is not None: 398*f81fb7c4SAndroid Build Coastguard Worker size = len(self.config.copyright) + 1 399*f81fb7c4SAndroid Build Coastguard Worker if size & 1: 400*f81fb7c4SAndroid Build Coastguard Worker size += 1 401*f81fb7c4SAndroid Build Coastguard Worker extra_byte = True 402*f81fb7c4SAndroid Build Coastguard Worker else: 403*f81fb7c4SAndroid Build Coastguard Worker extra_byte = False 404*f81fb7c4SAndroid Build Coastguard Worker jet_copyright = struct.pack(JCOP_STRUCT, JCOP_CHUNK, size) 405*f81fb7c4SAndroid Build Coastguard Worker output_file.write(jet_copyright) 406*f81fb7c4SAndroid Build Coastguard Worker output_file.write(self.config.copyright) 407*f81fb7c4SAndroid Build Coastguard Worker output_file.write(chr(0)) 408*f81fb7c4SAndroid Build Coastguard Worker if extra_byte: 409*f81fb7c4SAndroid Build Coastguard Worker output_file.write(chr(0)) 410*f81fb7c4SAndroid Build Coastguard Worker 411*f81fb7c4SAndroid Build Coastguard Worker # write the app data chunk (if any) 412*f81fb7c4SAndroid Build Coastguard Worker if self.config.app_data is not None: 413*f81fb7c4SAndroid Build Coastguard Worker size = os.path.getsize(self.config.app_data) 414*f81fb7c4SAndroid Build Coastguard Worker if size & 1: 415*f81fb7c4SAndroid Build Coastguard Worker size += 1 416*f81fb7c4SAndroid Build Coastguard Worker extra_byte = True 417*f81fb7c4SAndroid Build Coastguard Worker else: 418*f81fb7c4SAndroid Build Coastguard Worker extra_byte = False 419*f81fb7c4SAndroid Build Coastguard Worker jet_app_data = struct.pack(JAPP_STRUCT, JAPP_CHUNK, size) 420*f81fb7c4SAndroid Build Coastguard Worker output_file.write(jet_app_data) 421*f81fb7c4SAndroid Build Coastguard Worker with open(self.config.app_data, 'rb') as f: 422*f81fb7c4SAndroid Build Coastguard Worker output_file.write(f.read()) 423*f81fb7c4SAndroid Build Coastguard Worker if extra_byte: 424*f81fb7c4SAndroid Build Coastguard Worker output_file.write(chr(0)) 425*f81fb7c4SAndroid Build Coastguard Worker 426*f81fb7c4SAndroid Build Coastguard Worker # copy the MIDI segments 427*f81fb7c4SAndroid Build Coastguard Worker seg_num = 0 428*f81fb7c4SAndroid Build Coastguard Worker for segment in self.segments: 429*f81fb7c4SAndroid Build Coastguard Worker logging.debug('Writing segment %d' % seg_num) 430*f81fb7c4SAndroid Build Coastguard Worker 431*f81fb7c4SAndroid Build Coastguard Worker # open SMF file and read it 432*f81fb7c4SAndroid Build Coastguard Worker jet_segfile = JetSegmentFile(segment.filename, 'rb') 433*f81fb7c4SAndroid Build Coastguard Worker jet_segfile.ReadFromStream() 434*f81fb7c4SAndroid Build Coastguard Worker 435*f81fb7c4SAndroid Build Coastguard Worker # insert events 436*f81fb7c4SAndroid Build Coastguard Worker jet_segfile.AddJetEvents(segment.jetevents) 437*f81fb7c4SAndroid Build Coastguard Worker 438*f81fb7c4SAndroid Build Coastguard Worker # trim to length specified in config file 439*f81fb7c4SAndroid Build Coastguard Worker jet_segfile.ExtractEvents(segment.start, segment.end, segment.length, segment.quantize, self.config.chase_controllers) 440*f81fb7c4SAndroid Build Coastguard Worker 441*f81fb7c4SAndroid Build Coastguard Worker # chase controller events and fix them 442*f81fb7c4SAndroid Build Coastguard Worker if self.config.chase_controllers: 443*f81fb7c4SAndroid Build Coastguard Worker jet_segfile.SyncClips() 444*f81fb7c4SAndroid Build Coastguard Worker 445*f81fb7c4SAndroid Build Coastguard Worker # delete empty tracks 446*f81fb7c4SAndroid Build Coastguard Worker if self.config.delete_empty_tracks: 447*f81fb7c4SAndroid Build Coastguard Worker jet_segfile.DeleteEmptyTracks() 448*f81fb7c4SAndroid Build Coastguard Worker 449*f81fb7c4SAndroid Build Coastguard Worker # write separate output file if requested 450*f81fb7c4SAndroid Build Coastguard Worker if segment.output is not None: 451*f81fb7c4SAndroid Build Coastguard Worker jet_segfile.SaveAs(segment.output) 452*f81fb7c4SAndroid Build Coastguard Worker 453*f81fb7c4SAndroid Build Coastguard Worker # write dump file 454*f81fb7c4SAndroid Build Coastguard Worker if segment.dump_file is not None: 455*f81fb7c4SAndroid Build Coastguard Worker with open(segment.dump_file, 'w') as f: 456*f81fb7c4SAndroid Build Coastguard Worker jet_segfile.DumpTracks(f) 457*f81fb7c4SAndroid Build Coastguard Worker 458*f81fb7c4SAndroid Build Coastguard Worker # write the segment header 459*f81fb7c4SAndroid Build Coastguard Worker header_pos = output_file.tell() 460*f81fb7c4SAndroid Build Coastguard Worker smf_header = struct.pack(JET_HEADER_STRUCT, JET_SMF_CHUNK, 0) 461*f81fb7c4SAndroid Build Coastguard Worker output_file.write(smf_header) 462*f81fb7c4SAndroid Build Coastguard Worker start_pos = output_file.tell() 463*f81fb7c4SAndroid Build Coastguard Worker 464*f81fb7c4SAndroid Build Coastguard Worker # write SMF file to output file 465*f81fb7c4SAndroid Build Coastguard Worker jet_segfile.Write(output_file, offset=start_pos) 466*f81fb7c4SAndroid Build Coastguard Worker jet_segfile.close() 467*f81fb7c4SAndroid Build Coastguard Worker 468*f81fb7c4SAndroid Build Coastguard Worker # return to segment header and write actual size 469*f81fb7c4SAndroid Build Coastguard Worker end_pos = output_file.tell() 470*f81fb7c4SAndroid Build Coastguard Worker file_size = end_pos - start_pos 471*f81fb7c4SAndroid Build Coastguard Worker if file_size & 1: 472*f81fb7c4SAndroid Build Coastguard Worker file_size += 1 473*f81fb7c4SAndroid Build Coastguard Worker end_pos += 1 474*f81fb7c4SAndroid Build Coastguard Worker output_file.seek(header_pos, 0) 475*f81fb7c4SAndroid Build Coastguard Worker smf_header = struct.pack(JET_HEADER_STRUCT, JET_SMF_CHUNK, file_size) 476*f81fb7c4SAndroid Build Coastguard Worker output_file.write(smf_header) 477*f81fb7c4SAndroid Build Coastguard Worker output_file.seek(end_pos, 0) 478*f81fb7c4SAndroid Build Coastguard Worker 479*f81fb7c4SAndroid Build Coastguard Worker seg_num += 1 480*f81fb7c4SAndroid Build Coastguard Worker 481*f81fb7c4SAndroid Build Coastguard Worker # copy the DLS segments 482*f81fb7c4SAndroid Build Coastguard Worker for library in self.libraries: 483*f81fb7c4SAndroid Build Coastguard Worker if FileExists(library): 484*f81fb7c4SAndroid Build Coastguard Worker # open SMF file and get size 485*f81fb7c4SAndroid Build Coastguard Worker lib_file = (open(library,'rb')) 486*f81fb7c4SAndroid Build Coastguard Worker lib_file.seek(0,2) 487*f81fb7c4SAndroid Build Coastguard Worker file_size = lib_file.tell() 488*f81fb7c4SAndroid Build Coastguard Worker lib_file.seek(0) 489*f81fb7c4SAndroid Build Coastguard Worker 490*f81fb7c4SAndroid Build Coastguard Worker # write the library header 491*f81fb7c4SAndroid Build Coastguard Worker dls_header = struct.pack(JET_HEADER_STRUCT, JET_DLS_CHUNK, file_size) 492*f81fb7c4SAndroid Build Coastguard Worker output_file.write(dls_header) 493*f81fb7c4SAndroid Build Coastguard Worker 494*f81fb7c4SAndroid Build Coastguard Worker # copy DLS file to output file 495*f81fb7c4SAndroid Build Coastguard Worker output_file.write(lib_file.read()) 496*f81fb7c4SAndroid Build Coastguard Worker lib_file.close() 497*f81fb7c4SAndroid Build Coastguard Worker 498*f81fb7c4SAndroid Build Coastguard Worker # write the header with the read data size 499*f81fb7c4SAndroid Build Coastguard Worker file_size = output_file.tell() 500*f81fb7c4SAndroid Build Coastguard Worker output_file.seek(0) 501*f81fb7c4SAndroid Build Coastguard Worker jet_header = struct.pack(JET_HEADER_STRUCT, JET_HEADER_TAG, file_size - struct.calcsize(JET_HEADER_STRUCT)) 502*f81fb7c4SAndroid Build Coastguard Worker output_file.write(jet_header) 503*f81fb7c4SAndroid Build Coastguard Worker output_file.close() 504*f81fb7c4SAndroid Build Coastguard Worker 505*f81fb7c4SAndroid Build Coastguard Worker def GetMidiFiles(self): 506*f81fb7c4SAndroid Build Coastguard Worker """ Gets a list of midifiles """ 507*f81fb7c4SAndroid Build Coastguard Worker midiFiles = [] 508*f81fb7c4SAndroid Build Coastguard Worker for segment in self.segments: 509*f81fb7c4SAndroid Build Coastguard Worker if segment.filename not in midiFiles: 510*f81fb7c4SAndroid Build Coastguard Worker midiFiles.append(segment.filename) 511*f81fb7c4SAndroid Build Coastguard Worker return midiFiles 512*f81fb7c4SAndroid Build Coastguard Worker 513*f81fb7c4SAndroid Build Coastguard Worker def GetLibraries(self): 514*f81fb7c4SAndroid Build Coastguard Worker """ Gets the libraries """ 515*f81fb7c4SAndroid Build Coastguard Worker return self.libraries 516*f81fb7c4SAndroid Build Coastguard Worker 517*f81fb7c4SAndroid Build Coastguard Worker def GetEvents(self, segName): 518*f81fb7c4SAndroid Build Coastguard Worker """ Gets the events for a segment """ 519*f81fb7c4SAndroid Build Coastguard Worker for segment in self.segments: 520*f81fb7c4SAndroid Build Coastguard Worker if segment.segname == segName: 521*f81fb7c4SAndroid Build Coastguard Worker return segment.jetevents 522*f81fb7c4SAndroid Build Coastguard Worker return None 523*f81fb7c4SAndroid Build Coastguard Worker 524*f81fb7c4SAndroid Build Coastguard Worker def GetEvent(self, segName, eventName): 525*f81fb7c4SAndroid Build Coastguard Worker """ Gets a single event from a segment """ 526*f81fb7c4SAndroid Build Coastguard Worker for segment in self.segments: 527*f81fb7c4SAndroid Build Coastguard Worker if segment.segname == segName: 528*f81fb7c4SAndroid Build Coastguard Worker for event in segment.jetevents: 529*f81fb7c4SAndroid Build Coastguard Worker if event.event_name == eventName: 530*f81fb7c4SAndroid Build Coastguard Worker return event 531*f81fb7c4SAndroid Build Coastguard Worker return None 532*f81fb7c4SAndroid Build Coastguard Worker 533*f81fb7c4SAndroid Build Coastguard Worker def AddEvent(self, segname, event_name, event_type, event_id, track_num, channel_num, event_start, event_end): 534*f81fb7c4SAndroid Build Coastguard Worker """ Adds an event """ 535*f81fb7c4SAndroid Build Coastguard Worker for segment in self.segments: 536*f81fb7c4SAndroid Build Coastguard Worker if segment.segname == segname: 537*f81fb7c4SAndroid Build Coastguard Worker segment.jetevents.append(JetEvent(event_name, event_type, int(event_id), int(track_num), int(channel_num), event_start, event_end)) 538*f81fb7c4SAndroid Build Coastguard Worker 539*f81fb7c4SAndroid Build Coastguard Worker def ReplaceEvents(self, segname, newEvents): 540*f81fb7c4SAndroid Build Coastguard Worker """ Replaces all events """ 541*f81fb7c4SAndroid Build Coastguard Worker for segment in self.segments: 542*f81fb7c4SAndroid Build Coastguard Worker if segment.segname == segname: 543*f81fb7c4SAndroid Build Coastguard Worker segment.jetevents = newEvents 544*f81fb7c4SAndroid Build Coastguard Worker return segment 545*f81fb7c4SAndroid Build Coastguard Worker 546*f81fb7c4SAndroid Build Coastguard Worker def UpdateEvent(self, segname, orgeventname, event_name, event_type, event_id, track_num, channel_num, event_start, event_end): 547*f81fb7c4SAndroid Build Coastguard Worker """ Updates an event """ 548*f81fb7c4SAndroid Build Coastguard Worker for segment in self.segments: 549*f81fb7c4SAndroid Build Coastguard Worker if segment.segname == segname: 550*f81fb7c4SAndroid Build Coastguard Worker for jetevent in segment.jetevents: 551*f81fb7c4SAndroid Build Coastguard Worker if jetevent.event_name == orgeventname: 552*f81fb7c4SAndroid Build Coastguard Worker jetevent.event_name = event_name 553*f81fb7c4SAndroid Build Coastguard Worker jetevent.event_type = event_type 554*f81fb7c4SAndroid Build Coastguard Worker jetevent.event_id = event_id 555*f81fb7c4SAndroid Build Coastguard Worker jetevent.track_num = track_num 556*f81fb7c4SAndroid Build Coastguard Worker jetevent.channel_num = channel_num 557*f81fb7c4SAndroid Build Coastguard Worker jetevent.event_start = event_start 558*f81fb7c4SAndroid Build Coastguard Worker jetevent.event_end = event_end 559*f81fb7c4SAndroid Build Coastguard Worker 560*f81fb7c4SAndroid Build Coastguard Worker def DeleteSegmentsMatchingPrefix(self, prefix): 561*f81fb7c4SAndroid Build Coastguard Worker """ Deletes all segments matching name """ 562*f81fb7c4SAndroid Build Coastguard Worker iOnce = True 563*f81fb7c4SAndroid Build Coastguard Worker iAgain = False 564*f81fb7c4SAndroid Build Coastguard Worker while(iOnce or iAgain): 565*f81fb7c4SAndroid Build Coastguard Worker iOnce = False 566*f81fb7c4SAndroid Build Coastguard Worker iAgain = False 567*f81fb7c4SAndroid Build Coastguard Worker for segment in self.segments: 568*f81fb7c4SAndroid Build Coastguard Worker if segment.segname[0:len(prefix)].upper() == prefix.upper(): 569*f81fb7c4SAndroid Build Coastguard Worker self.segments.remove(segment) 570*f81fb7c4SAndroid Build Coastguard Worker iAgain = True 571*f81fb7c4SAndroid Build Coastguard Worker 572*f81fb7c4SAndroid Build Coastguard Worker def DeleteEvent(self, segname, event_name): 573*f81fb7c4SAndroid Build Coastguard Worker """ Deletes an event """ 574*f81fb7c4SAndroid Build Coastguard Worker for segment in self.segments: 575*f81fb7c4SAndroid Build Coastguard Worker if segment.segname == segname: 576*f81fb7c4SAndroid Build Coastguard Worker for jetevent in segment.jetevents: 577*f81fb7c4SAndroid Build Coastguard Worker if jetevent.event_name == event_name: 578*f81fb7c4SAndroid Build Coastguard Worker segment.jetevents.remove(jetevent) 579*f81fb7c4SAndroid Build Coastguard Worker 580*f81fb7c4SAndroid Build Coastguard Worker def DeleteEventsMatchingPrefix(self, segname, prefix): 581*f81fb7c4SAndroid Build Coastguard Worker """ Deletes all events matching name """ 582*f81fb7c4SAndroid Build Coastguard Worker for segment in self.segments: 583*f81fb7c4SAndroid Build Coastguard Worker if segment.segname == segname: 584*f81fb7c4SAndroid Build Coastguard Worker iOnce = True 585*f81fb7c4SAndroid Build Coastguard Worker iAgain = False 586*f81fb7c4SAndroid Build Coastguard Worker while(iOnce or iAgain): 587*f81fb7c4SAndroid Build Coastguard Worker iOnce = False 588*f81fb7c4SAndroid Build Coastguard Worker iAgain = False 589*f81fb7c4SAndroid Build Coastguard Worker for jetevent in segment.jetevents: 590*f81fb7c4SAndroid Build Coastguard Worker if jetevent.event_name[0:len(prefix)].upper() == prefix.upper(): 591*f81fb7c4SAndroid Build Coastguard Worker segment.jetevents.remove(jetevent) 592*f81fb7c4SAndroid Build Coastguard Worker iAgain = True 593*f81fb7c4SAndroid Build Coastguard Worker 594*f81fb7c4SAndroid Build Coastguard Worker def MoveEvent(self, segname, movename, event_start, event_end): 595*f81fb7c4SAndroid Build Coastguard Worker """ Move an event """ 596*f81fb7c4SAndroid Build Coastguard Worker for segment in self.segments: 597*f81fb7c4SAndroid Build Coastguard Worker if segment.segname == segname: 598*f81fb7c4SAndroid Build Coastguard Worker for jetevent in segment.jetevents: 599*f81fb7c4SAndroid Build Coastguard Worker if jetevent.event_name == movename: 600*f81fb7c4SAndroid Build Coastguard Worker jetevent.event_start = event_start 601*f81fb7c4SAndroid Build Coastguard Worker jetevent.event_end = event_end 602*f81fb7c4SAndroid Build Coastguard Worker return 603*f81fb7c4SAndroid Build Coastguard Worker 604*f81fb7c4SAndroid Build Coastguard Worker def GetSegments(self): 605*f81fb7c4SAndroid Build Coastguard Worker """ Gets all segments """ 606*f81fb7c4SAndroid Build Coastguard Worker return self.segments 607*f81fb7c4SAndroid Build Coastguard Worker 608*f81fb7c4SAndroid Build Coastguard Worker def GetSegment(self, segName): 609*f81fb7c4SAndroid Build Coastguard Worker """ Gets one segment by name """ 610*f81fb7c4SAndroid Build Coastguard Worker for segment in self.segments: 611*f81fb7c4SAndroid Build Coastguard Worker if segment.segname == segName: 612*f81fb7c4SAndroid Build Coastguard Worker return segment 613*f81fb7c4SAndroid Build Coastguard Worker return None 614*f81fb7c4SAndroid Build Coastguard Worker 615*f81fb7c4SAndroid Build Coastguard Worker def AddSegment(self, segname, filename, start, end, length, output, quantize, jetevents, dlsfile, dump_file, transpose, repeat, mute_flags): 616*f81fb7c4SAndroid Build Coastguard Worker """ Adds a segment """ 617*f81fb7c4SAndroid Build Coastguard Worker if length == JetDefs.MBT_ZEROSTR: 618*f81fb7c4SAndroid Build Coastguard Worker length = None 619*f81fb7c4SAndroid Build Coastguard Worker if end == JetDefs.MBT_ZEROSTR: 620*f81fb7c4SAndroid Build Coastguard Worker end = None 621*f81fb7c4SAndroid Build Coastguard Worker self.segments.append(JetSegment(segname, filename, start, end, length, output, quantize, jetevents, dlsfile, dump_file, transpose, repeat, mute_flags)) 622*f81fb7c4SAndroid Build Coastguard Worker 623*f81fb7c4SAndroid Build Coastguard Worker def UpdateSegment(self, orgsegname, segname, filename, start, end, length, output, quantize, jetevents, dlsfile, dump_file, transpose, repeat, mute_flags): 624*f81fb7c4SAndroid Build Coastguard Worker """ Updates a segment """ 625*f81fb7c4SAndroid Build Coastguard Worker if length == JetDefs.MBT_ZEROSTR: 626*f81fb7c4SAndroid Build Coastguard Worker length = None 627*f81fb7c4SAndroid Build Coastguard Worker if end == JetDefs.MBT_ZEROSTR: 628*f81fb7c4SAndroid Build Coastguard Worker end = None 629*f81fb7c4SAndroid Build Coastguard Worker for segment in self.segments: 630*f81fb7c4SAndroid Build Coastguard Worker if segment.segname == orgsegname: 631*f81fb7c4SAndroid Build Coastguard Worker segment.segname = segname 632*f81fb7c4SAndroid Build Coastguard Worker segment.filename = filename 633*f81fb7c4SAndroid Build Coastguard Worker segment.start = start 634*f81fb7c4SAndroid Build Coastguard Worker segment.end = end 635*f81fb7c4SAndroid Build Coastguard Worker segment.length = length 636*f81fb7c4SAndroid Build Coastguard Worker segment.output = output 637*f81fb7c4SAndroid Build Coastguard Worker segment.quantize = quantize 638*f81fb7c4SAndroid Build Coastguard Worker segment.dlsfile = dlsfile 639*f81fb7c4SAndroid Build Coastguard Worker segment.transpose = transpose 640*f81fb7c4SAndroid Build Coastguard Worker segment.repeat = repeat 641*f81fb7c4SAndroid Build Coastguard Worker segment.mute_flags = mute_flags 642*f81fb7c4SAndroid Build Coastguard Worker 643*f81fb7c4SAndroid Build Coastguard Worker def MoveSegment(self, segname, start, end): 644*f81fb7c4SAndroid Build Coastguard Worker """ Moves a segment """ 645*f81fb7c4SAndroid Build Coastguard Worker for segment in self.segments: 646*f81fb7c4SAndroid Build Coastguard Worker if segment.segname == segname: 647*f81fb7c4SAndroid Build Coastguard Worker segment.start = start 648*f81fb7c4SAndroid Build Coastguard Worker segment.end = end 649*f81fb7c4SAndroid Build Coastguard Worker return 650*f81fb7c4SAndroid Build Coastguard Worker 651*f81fb7c4SAndroid Build Coastguard Worker def DeleteSegment(self, segname): 652*f81fb7c4SAndroid Build Coastguard Worker """ Deletes a segment """ 653*f81fb7c4SAndroid Build Coastguard Worker for segment in self.segments: 654*f81fb7c4SAndroid Build Coastguard Worker if segment.segname == segname: 655*f81fb7c4SAndroid Build Coastguard Worker self.segments.remove(segment) 656*f81fb7c4SAndroid Build Coastguard Worker 657*f81fb7c4SAndroid Build Coastguard Worker def SaveJetConfig(self, configFile): 658*f81fb7c4SAndroid Build Coastguard Worker """ Saves the jet config file """ 659*f81fb7c4SAndroid Build Coastguard Worker if self.config.filename == '' or self.config.filename == None: 660*f81fb7c4SAndroid Build Coastguard Worker self.config.filename = FileJustRoot(configFile) + ".JET" 661*f81fb7c4SAndroid Build Coastguard Worker config = ConfigParser.ConfigParser() 662*f81fb7c4SAndroid Build Coastguard Worker config.add_section(OUTPUT_SECTION) 663*f81fb7c4SAndroid Build Coastguard Worker config.set(OUTPUT_SECTION, OUTPUT_FILENAME, self.config.filename) 664*f81fb7c4SAndroid Build Coastguard Worker config.set(OUTPUT_SECTION, OUTPUT_CHASE_CONTROLLERS, self.config.chase_controllers) 665*f81fb7c4SAndroid Build Coastguard Worker config.set(OUTPUT_SECTION, OUTPUT_OMIT_EMPTY_TRACKS, self.config.delete_empty_tracks) 666*f81fb7c4SAndroid Build Coastguard Worker if self.config.copyright is not None: 667*f81fb7c4SAndroid Build Coastguard Worker config.set(OUTPUT_SECTION, OUTPUT_COPYRIGHT, self.config.copyright) 668*f81fb7c4SAndroid Build Coastguard Worker if self.config.app_data is not None: 669*f81fb7c4SAndroid Build Coastguard Worker config.set(OUTPUT_SECTION, OUTPUT_APP_DATA, self.config.app_data) 670*f81fb7c4SAndroid Build Coastguard Worker 671*f81fb7c4SAndroid Build Coastguard Worker self.libraries = [] 672*f81fb7c4SAndroid Build Coastguard Worker seg_num = 0 673*f81fb7c4SAndroid Build Coastguard Worker for segment in self.segments: 674*f81fb7c4SAndroid Build Coastguard Worker segment_name = SEGMENT_SECTION + str(seg_num) 675*f81fb7c4SAndroid Build Coastguard Worker config.add_section(segment_name) 676*f81fb7c4SAndroid Build Coastguard Worker config.set(segment_name, SEGMENT_NAME, segment.segname) 677*f81fb7c4SAndroid Build Coastguard Worker config.set(segment_name, SEGMENT_FILENAME, segment.filename) 678*f81fb7c4SAndroid Build Coastguard Worker 679*f81fb7c4SAndroid Build Coastguard Worker config.set(segment_name, SEGMENT_DLSFILE, segment.dlsfile) 680*f81fb7c4SAndroid Build Coastguard Worker if FileExists(segment.dlsfile): 681*f81fb7c4SAndroid Build Coastguard Worker if not segment.dlsfile in self.libraries: 682*f81fb7c4SAndroid Build Coastguard Worker self.libraries.append(segment.dlsfile) 683*f81fb7c4SAndroid Build Coastguard Worker config.set(segment_name, SEGMENT_START, segment.start) 684*f81fb7c4SAndroid Build Coastguard Worker if segment.end > JetDefs.MBT_ZEROSTR and len(segment.end) > 0: 685*f81fb7c4SAndroid Build Coastguard Worker config.set(segment_name, SEGMENT_END, segment.end) 686*f81fb7c4SAndroid Build Coastguard Worker if segment.length > JetDefs.MBT_ZEROSTR and len(segment.length) > 0: 687*f81fb7c4SAndroid Build Coastguard Worker config.set(segment_name, SEGMENT_LENGTH, segment.length) 688*f81fb7c4SAndroid Build Coastguard Worker config.set(segment_name, SEGMENT_OUTPUT, segment.output) 689*f81fb7c4SAndroid Build Coastguard Worker config.set(segment_name, SEGMENT_QUANTIZE, segment.quantize) 690*f81fb7c4SAndroid Build Coastguard Worker if segment.dump_file is not None: 691*f81fb7c4SAndroid Build Coastguard Worker config.set(segment_name, SEGMENT_DUMP_FILE, segment.dump_file) 692*f81fb7c4SAndroid Build Coastguard Worker config.set(segment_name, SEGMENT_TRANSPOSE, segment.transpose) 693*f81fb7c4SAndroid Build Coastguard Worker config.set(segment_name, SEGMENT_REPEAT, segment.repeat) 694*f81fb7c4SAndroid Build Coastguard Worker config.set(segment_name, SEGMENT_MUTE_FLAGS, segment.mute_flags) 695*f81fb7c4SAndroid Build Coastguard Worker 696*f81fb7c4SAndroid Build Coastguard Worker clip_num = 0 697*f81fb7c4SAndroid Build Coastguard Worker app_num = 0 698*f81fb7c4SAndroid Build Coastguard Worker for jet_event in segment.jetevents: 699*f81fb7c4SAndroid Build Coastguard Worker if jet_event.event_type == JetDefs.E_CLIP: 700*f81fb7c4SAndroid Build Coastguard Worker clip_name = CLIP_PREFIX + str(clip_num) 701*f81fb7c4SAndroid Build Coastguard Worker s = "%s,%s,%s,%s,%s,%s" % (jet_event.event_name, jet_event.event_id, jet_event.track_num, jet_event.channel_num, jet_event.event_start, jet_event.event_end) 702*f81fb7c4SAndroid Build Coastguard Worker config.set(segment_name, clip_name, s) 703*f81fb7c4SAndroid Build Coastguard Worker clip_num += 1 704*f81fb7c4SAndroid Build Coastguard Worker elif jet_event.event_type == JetDefs.E_APP: 705*f81fb7c4SAndroid Build Coastguard Worker app_name = APP_PREFIX + str(app_num) 706*f81fb7c4SAndroid Build Coastguard Worker s = "%s,%s,%s,%s,%s,%s" % (jet_event.event_name, jet_event.event_id, jet_event.track_num, jet_event.channel_num, jet_event.event_start, jet_event.event_end) 707*f81fb7c4SAndroid Build Coastguard Worker config.set(segment_name, app_name, s) 708*f81fb7c4SAndroid Build Coastguard Worker app_num += 1 709*f81fb7c4SAndroid Build Coastguard Worker elif jet_event.event_type == JetDefs.E_EOS: 710*f81fb7c4SAndroid Build Coastguard Worker s = "%s,%s,%s" % (jet_event.track_num, jet_event.channel_num, jet_event.event_start) 711*f81fb7c4SAndroid Build Coastguard Worker config.set(segment_name, SEGMENT_END_MARKER, s) 712*f81fb7c4SAndroid Build Coastguard Worker 713*f81fb7c4SAndroid Build Coastguard Worker seg_num += 1 714*f81fb7c4SAndroid Build Coastguard Worker 715*f81fb7c4SAndroid Build Coastguard Worker lib_num = 0 716*f81fb7c4SAndroid Build Coastguard Worker config.add_section(LIBRARY_SECTION) 717*f81fb7c4SAndroid Build Coastguard Worker for library in self.libraries: 718*f81fb7c4SAndroid Build Coastguard Worker library_name = LIBRARY_FILENAME + str(lib_num) 719*f81fb7c4SAndroid Build Coastguard Worker config.set(LIBRARY_SECTION, library_name, library) 720*f81fb7c4SAndroid Build Coastguard Worker lib_num += 1 721*f81fb7c4SAndroid Build Coastguard Worker 722*f81fb7c4SAndroid Build Coastguard Worker FileKillClean(configFile) 723*f81fb7c4SAndroid Build Coastguard Worker cfgfile = open(configFile,'w') 724*f81fb7c4SAndroid Build Coastguard Worker config.write(cfgfile) 725*f81fb7c4SAndroid Build Coastguard Worker cfgfile.close() 726*f81fb7c4SAndroid Build Coastguard Worker 727*f81fb7c4SAndroid Build Coastguard Worker def InitializeConfig(self, configFile): 728*f81fb7c4SAndroid Build Coastguard Worker """ Initializes the values for an empty flag """ 729*f81fb7c4SAndroid Build Coastguard Worker self.config.filename = FileJustRoot(configFile) + ".JET" 730*f81fb7c4SAndroid Build Coastguard Worker self.config.chase_controllers = True 731*f81fb7c4SAndroid Build Coastguard Worker self.config.delete_empty_tracks = False 732*f81fb7c4SAndroid Build Coastguard Worker self.config.copyright = None 733*f81fb7c4SAndroid Build Coastguard Worker self.config.app_data = None 734*f81fb7c4SAndroid Build Coastguard Worker self.segments = [] 735*f81fb7c4SAndroid Build Coastguard Worker self.libraries = [] 736*f81fb7c4SAndroid Build Coastguard Worker self.config_file = configFile 737*f81fb7c4SAndroid Build Coastguard Worker self.SaveJetConfig(configFile) 738*f81fb7c4SAndroid Build Coastguard Worker 739*f81fb7c4SAndroid Build Coastguard Worker 740*f81fb7c4SAndroid Build Coastguard Worker 741*f81fb7c4SAndroid Build Coastguard Worker#--------------------------------------------------------------- 742*f81fb7c4SAndroid Build Coastguard Worker# main 743*f81fb7c4SAndroid Build Coastguard Worker#--------------------------------------------------------------- 744*f81fb7c4SAndroid Build Coastguard Workerif __name__ == '__main__': 745*f81fb7c4SAndroid Build Coastguard Worker sys = __import__('sys') 746*f81fb7c4SAndroid Build Coastguard Worker optparse = __import__('optparse') 747*f81fb7c4SAndroid Build Coastguard Worker 748*f81fb7c4SAndroid Build Coastguard Worker # parse command line options 749*f81fb7c4SAndroid Build Coastguard Worker parser = optparse.OptionParser(version=VERSION) 750*f81fb7c4SAndroid Build Coastguard Worker parser.set_defaults(log_level=logging.INFO, log_file=None) 751*f81fb7c4SAndroid Build Coastguard Worker parser.add_option('-d', '--debug', action="store_const", const=logging.DEBUG, dest='log_level', help='Enable debug output') 752*f81fb7c4SAndroid Build Coastguard Worker parser.add_option('-l', '--log_file', dest='log_file', help='Write debug output to log file') 753*f81fb7c4SAndroid Build Coastguard Worker (options, args) = parser.parse_args() 754*f81fb7c4SAndroid Build Coastguard Worker 755*f81fb7c4SAndroid Build Coastguard Worker # get master logger 756*f81fb7c4SAndroid Build Coastguard Worker logger = logging.getLogger('') 757*f81fb7c4SAndroid Build Coastguard Worker logger.setLevel(options.log_level) 758*f81fb7c4SAndroid Build Coastguard Worker 759*f81fb7c4SAndroid Build Coastguard Worker # create console logger 760*f81fb7c4SAndroid Build Coastguard Worker console_logger = logging.StreamHandler() 761*f81fb7c4SAndroid Build Coastguard Worker console_logger.setFormatter(logging.Formatter('%(message)s')) 762*f81fb7c4SAndroid Build Coastguard Worker logger.addHandler(console_logger) 763*f81fb7c4SAndroid Build Coastguard Worker 764*f81fb7c4SAndroid Build Coastguard Worker # create rotating file logger 765*f81fb7c4SAndroid Build Coastguard Worker if options.log_file is not None: 766*f81fb7c4SAndroid Build Coastguard Worker file_logger = logging.FileHandler(options.log_file, 'w') 767*f81fb7c4SAndroid Build Coastguard Worker file_logger.setFormatter(logging.Formatter('%(message)s')) 768*f81fb7c4SAndroid Build Coastguard Worker logger.addHandler(file_logger) 769*f81fb7c4SAndroid Build Coastguard Worker 770*f81fb7c4SAndroid Build Coastguard Worker # process files 771*f81fb7c4SAndroid Build Coastguard Worker for arg in args: 772*f81fb7c4SAndroid Build Coastguard Worker print arg 773*f81fb7c4SAndroid Build Coastguard Worker jet_file = JetFile(arg, options) 774*f81fb7c4SAndroid Build Coastguard Worker jet_file.WriteJetFileFromConfig(options) 775*f81fb7c4SAndroid Build Coastguard Worker 776