summaryrefslogtreecommitdiffstats
path: root/jet_tools/JetCreator/JetFile.py
diff options
context:
space:
mode:
Diffstat (limited to 'jet_tools/JetCreator/JetFile.py')
-rwxr-xr-xjet_tools/JetCreator/JetFile.py775
1 files changed, 775 insertions, 0 deletions
diff --git a/jet_tools/JetCreator/JetFile.py b/jet_tools/JetCreator/JetFile.py
new file mode 100755
index 0000000..d29db7e
--- /dev/null
+++ b/jet_tools/JetCreator/JetFile.py
@@ -0,0 +1,775 @@
+"""
+ File:
+ JetFile.py
+
+ Contents and purpose:
+ Auditions a jet file to simulate interactive music functions
+
+ Copyright (c) 2008 Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+"""
+
+from __future__ import with_statement
+
+import logging
+import ConfigParser
+import struct
+import os
+import sys
+import midifile
+
+from JetUtils import *
+from JetDefs import *
+
+VERSION = '0.1'
+
+# JET file defines
+JET_HEADER_STRUCT = '<4sl'
+JET_HEADER_TAG = 'JET '
+JET_VERSION = 0x01000000
+
+# JET chunk tags
+JET_INFO_CHUNK = 'JINF'
+JET_SMF_CHUNK = 'JSMF'
+JET_DLS_CHUNK = 'JDLS'
+
+# JINF defines
+JINF_STRUCT = '<4sl4sl4sl4sl'
+JINF_JET_VERSION = 'JVER'
+JINF_NUM_SMF_CHUNKS = 'SMF#'
+JINF_NUM_DLS_CHUNKS = 'DLS#'
+
+# JCOP defines
+JCOP_STRUCT = '<4sl'
+JCOP_CHUNK = 'JCOP'
+
+# JAPP defines
+JAPP_STRUCT = '<4sl'
+JAPP_CHUNK = 'JAPP'
+
+# config file defines
+OUTPUT_SECTION = 'output'
+OUTPUT_FILENAME = 'filename'
+OUTPUT_COPYRIGHT = 'copyright'
+OUTPUT_APP_DATA = 'app_data'
+OUTPUT_CHASE_CONTROLLERS = 'chase_controllers'
+OUTPUT_OMIT_EMPTY_TRACKS = 'omit_empty_tracks'
+SEGMENT_SECTION = 'segment'
+SEGMENT_FILENAME = 'filename'
+SEGMENT_DLSFILE = 'dlsfile'
+SEGMENT_NAME = 'segname'
+SEGMENT_START = 'start'
+SEGMENT_END = 'end'
+SEGMENT_END_MARKER = 'end_marker'
+SEGMENT_QUANTIZE = 'quantize'
+SEGMENT_OUTPUT = 'output'
+SEGMENT_LENGTH = 'length'
+SEGMENT_DUMP_FILE = 'dump'
+SEGMENT_TRANSPOSE = 'transpose'
+SEGMENT_REPEAT = 'repeat'
+SEGMENT_MUTE_FLAGS = 'mute_flags'
+LIBRARY_SECTION = 'libraries'
+LIBRARY_FILENAME = 'lib'
+CLIP_PREFIX = 'clip'
+APP_PREFIX = 'app'
+
+# JET events
+JET_EVENT_MARKER = 102
+JET_MARKER_LOOP_END = 0
+JET_EVENT_TRIGGER_CLIP = 103
+
+class JetSegment (object):
+ """ Class to hold segments """
+ 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):
+ self.segname = segname
+ self.filename = filename
+ self.dlsfile = dlsfile
+ self.start = start
+ self.end = end
+ self.length = length
+ self.output = output
+ self.quantize = quantize
+ self.dump_file = dump_file
+ self.jetevents = jetevents
+ #API FIELDS FOR UI
+ self.transpose = transpose
+ self.repeat = repeat
+ self.mute_flags = mute_flags
+
+class JetEvent (object):
+ """ Class to hold events """
+ def __init__(self, event_name, event_type, event_id, track_num, channel_num, event_start, event_end):
+ self.event_name = event_name
+ self.event_type = event_type
+ self.event_id = event_id
+ self.track_num = track_num
+ self.channel_num = channel_num
+ self.event_start = event_start
+ self.event_end = event_end
+
+class JetFileException (Exception):
+ """ Exceptions class """
+ def __init__ (self, msg):
+ self.msg = msg
+ def __str__ (self):
+ return self.msg
+
+class JetSegmentFile (midifile.MIDIFile):
+ def ConvertMusicTimeToTicks (self, s):
+ measures, beats, ticks = s.split(':',3)
+ return self.ConvertToTicks(int(measures), int(beats), int(ticks))
+
+ def ExtractEvents (self, start, end, length, quantize, chase_controllers):
+ if (start is None) and (end is None) and (length is None):
+ logging.debug('ExtractEvents: No change')
+ return
+
+ if start is not None:
+ start = self.ConvertMusicTimeToTicks(start)
+ else:
+ start = 0
+ if end is not None:
+ end = self.ConvertMusicTimeToTicks(end)
+ elif length is not None:
+ length = self.ConvertMusicTimeToTicks(length)
+ end = start + length
+
+ if quantize is not None:
+ quantize = int(quantize)
+ else:
+ quantize = 0
+
+ self.Trim(start, end, quantize, chase_controllers=chase_controllers)
+ #self.DumpTracks()
+
+ def SyncClips (self):
+ """Add controller events to the start of a clip to keep it synced."""
+ values = None
+ last_seq = 0
+ for track in self.tracks:
+ for event in track.events:
+
+ # find start of clip and chase events from last save point
+ if (event.msg_type == midifile.CONTROL_CHANGE) and \
+ (event.controller == JET_EVENT_TRIGGER_CLIP) and \
+ ((event.value & 0x40) == 0x40):
+ logging.debug('Syncing clip at %d ticks' % event.ticks)
+ values = track.events.ChaseControllers(event.seq, last_seq, values)
+
+ #BTH; Seems to fix chase controller bug when multiple clips within segment
+ #last_seq = event.seq
+
+ # generate event list from default values
+ clip_events = values.GenerateEventList(event.ticks)
+
+ #for evt in clip_events:
+ # logging.info(evt)
+
+ track.events.InsertEvents(clip_events, event.seq + 1)
+
+ def AddJetEvents (self, jetevents):
+ for jet_event in jetevents:
+ if jet_event.event_type == JetDefs.E_CLIP:
+ #DumpEvent(jet_event)
+
+ # sanity check
+ if jet_event.track_num >= len(self.tracks):
+ raise JetFileException('Track number %d of out of range for clip' % jet_event.track_num)
+ if jet_event.channel_num > 15:
+ raise JetFileException('Channel number %d of out of range for clip' % jet_event.channel_num)
+ if jet_event.event_id > 63:
+ raise JetFileException('event_id %d of out of range for clip' % jet_event.event_id)
+
+ logging.debug('Adding trigger event for clip %d @ %s and %s' % (jet_event.event_id, jet_event.event_start, jet_event.event_end))
+
+ events = midifile.EventList()
+ events.append(midifile.ControlChangeEvent(
+ self.ConvertMusicTimeToTicks(jet_event.event_start),
+ 0,
+ jet_event.channel_num,
+ JET_EVENT_TRIGGER_CLIP,
+ jet_event.event_id | 0x40))
+
+ events.append(midifile.ControlChangeEvent(
+ self.ConvertMusicTimeToTicks(jet_event.event_end),
+ sys.maxint,
+ jet_event.channel_num,
+ JET_EVENT_TRIGGER_CLIP,
+ jet_event.event_id))
+
+ # merge trigger events
+ self.tracks[jet_event.track_num].events.MergeEvents(events)
+
+ elif jet_event.event_type == JetDefs.E_EOS:
+ if jet_event.track_num >= len(self.tracks):
+ raise JetFileException('Track number %d of out of range for end marker' % jet_event.track_num)
+ if jet_event.channel_num > 15:
+ raise JetFileException('Channel number %d of out of range for end marker' % jet_event.channel_num)
+
+ events = midifile.EventList()
+ logging.debug('Adding end marker at %s' % jet_event.event_start)
+ events.append(midifile.ControlChangeEvent(
+ self.ConvertMusicTimeToTicks(jet_event.event_start),
+ 0,
+ jet_event.channel_num,
+ JET_EVENT_MARKER,
+ JET_MARKER_LOOP_END))
+ self.tracks[jet_event.track_num].events.MergeEvents(events)
+
+ elif jet_event.event_type == JetDefs.E_APP:
+ if jet_event.track_num >= len(self.tracks):
+ raise JetFileException('Track number %d of out of range for app marker' % jet_event.track_num)
+ if jet_event.channel_num > 15:
+ raise JetFileException('Channel number %d of out of range for app marker' % jet_event.channel_num)
+ if jet_event.event_id > 83 or jet_event.event_id < 80:
+ raise JetFileException('EventID %d out of range for application controller' % jet_event.event_id)
+
+ events = midifile.EventList()
+ logging.debug('Adding application controller at %s' % jet_event.event_start)
+ events.append(midifile.ControlChangeEvent(
+ self.ConvertMusicTimeToTicks(jet_event.event_start),
+ 0,
+ jet_event.channel_num,
+ jet_event.event_id,
+ jet_event.event_id))
+ self.tracks[jet_event.track_num].events.MergeEvents(events)
+
+class JetFile (object):
+ """Write a JET file based on a configuration file."""
+ def __init__ (self, config_file, options):
+ self.config_file = config_file
+ self.config = config = ConfigParser.ConfigParser()
+ if self.config_file == "":
+ self.InitializeConfig(JetDefs.UNTITLED_FILE)
+ if not FileExists(self.config_file):
+ self.InitializeConfig(self.config_file)
+
+ config.read(self.config_file)
+ self.ParseConfig(options)
+
+ def DumpConfig (self):
+ """Drump configuration to log file."""
+ # dump configuration
+ config = self.config
+ for section in config.sections():
+ logging.debug('[%s]' % section)
+ for option, value in config.items(section):
+ logging.debug('%s: %s' % (option, value))
+
+ def ParseConfig (self, options):
+ """Validate the configuration."""
+ # check for output name
+ config = self.config
+ if config.has_option(OUTPUT_SECTION, OUTPUT_FILENAME):
+ config.filename = config.get(OUTPUT_SECTION, OUTPUT_FILENAME)
+ else:
+ raise JetFileException('No output filename in configuration file')
+ if config.filename == '' or config.filename == None:
+ config.filename = FileJustRoot(self.config_file) + ".JET"
+ config.chase_controllers = True
+ if config.has_option(OUTPUT_SECTION, OUTPUT_CHASE_CONTROLLERS):
+ try:
+ config.chase_controllers = config.getboolean(OUTPUT_SECTION, OUTPUT_CHASE_CONTROLLERS)
+ except:
+ pass
+
+ config.delete_empty_tracks = False
+ if config.has_option(OUTPUT_SECTION, OUTPUT_OMIT_EMPTY_TRACKS):
+ try:
+ config.delete_empty_tracks = config.getboolean(OUTPUT_SECTION, OUTPUT_OMIT_EMPTY_TRACKS)
+ except:
+ pass
+
+ config.copyright = None
+ if config.has_option(OUTPUT_SECTION, OUTPUT_COPYRIGHT):
+ config.copyright = config.get(OUTPUT_SECTION, OUTPUT_COPYRIGHT)
+
+ config.app_data = None
+ if config.has_option(OUTPUT_SECTION, OUTPUT_APP_DATA):
+ config.app_data = config.get(OUTPUT_SECTION, OUTPUT_APP_DATA)
+
+ # count segments
+ segments = []
+ seg_num = 0
+ while 1:
+
+ # check for segment section
+ segment_name = SEGMENT_SECTION + str(seg_num)
+ if not config.has_section(segment_name):
+ break
+
+ # initialize some parameters
+ start = end = length = output = end_marker = dlsfile = dump_file = None
+ transpose = repeat = mute_flags = 0
+ jetevents = []
+
+ # get the segment parameters
+ segname = config.get(segment_name, SEGMENT_NAME)
+ filename = config.get(segment_name, SEGMENT_FILENAME)
+ if config.has_option(segment_name, SEGMENT_DLSFILE):
+ dlsfile = config.get(segment_name, SEGMENT_DLSFILE)
+ if config.has_option(segment_name, SEGMENT_START):
+ start = config.get(segment_name, SEGMENT_START)
+ if config.has_option(segment_name, SEGMENT_END):
+ end = config.get(segment_name, SEGMENT_END)
+ if config.has_option(segment_name, SEGMENT_LENGTH):
+ length = config.get(segment_name, SEGMENT_LENGTH)
+ if config.has_option(segment_name, SEGMENT_OUTPUT):
+ output = config.get(segment_name, SEGMENT_OUTPUT)
+ if config.has_option(segment_name, SEGMENT_QUANTIZE):
+ quantize = config.get(segment_name, SEGMENT_QUANTIZE)
+ if config.has_option(segment_name, SEGMENT_DUMP_FILE):
+ dump_file = config.get(segment_name, SEGMENT_DUMP_FILE)
+ #API FIELDS
+ if config.has_option(segment_name, SEGMENT_TRANSPOSE):
+ transpose = config.get(segment_name, SEGMENT_TRANSPOSE)
+ if config.has_option(segment_name, SEGMENT_REPEAT):
+ repeat = config.get(segment_name, SEGMENT_REPEAT)
+ if config.has_option(segment_name, SEGMENT_MUTE_FLAGS):
+ mute_flags = config.get(segment_name, SEGMENT_MUTE_FLAGS)
+
+ if config.has_option(segment_name, SEGMENT_END_MARKER):
+ end_marker = config.get(segment_name, SEGMENT_END_MARKER)
+ track_num, channel_num, event_time = end_marker.split(',',2)
+ #jetevents.append((JetDefs.E_EOS, 0, int(track_num), int(channel_num), event_time, ''))
+ jetevents.append(JetEvent(JetDefs.E_EOS, JetDefs.E_EOS, 0, int(track_num), int(channel_num), event_time, event_time))
+
+ # check for jetevents
+ for jetevent, location in config.items(segment_name):
+ if jetevent.startswith(CLIP_PREFIX):
+ event_name, event_id, track_num, channel_num, event_start, event_end = location.split(',', 5)
+ jetevents.append(JetEvent(event_name, JetDefs.E_CLIP, int(event_id), int(track_num), int(channel_num), event_start, event_end))
+
+ # check for appevents
+ for jetevent, location in config.items(segment_name):
+ if jetevent.startswith(APP_PREFIX):
+ event_name, event_id, track_num, channel_num, event_start, event_end = location.split(',', 5)
+ jetevents.append(JetEvent(event_name, JetDefs.E_APP, int(event_id), int(track_num), int(channel_num), event_start, event_end))
+
+ segments.append(JetSegment(segname, filename, start, end, length, output, quantize, jetevents, dlsfile, dump_file, int(transpose), int(repeat), int(mute_flags)))
+ seg_num += 1
+
+ self.segments = segments
+ if not len(segments):
+ #TODO: Check for segments when writing
+ #raise JetFileException('No segments defined in configuration file')
+ pass
+
+ # count libraries
+ libraries = []
+ lib_num = 0
+ while 1:
+ library_name = LIBRARY_FILENAME + str(lib_num)
+ if not config.has_option(LIBRARY_SECTION, library_name):
+ break
+ libraries.append(config.get(LIBRARY_SECTION, library_name))
+ lib_num += 1
+ self.libraries = libraries
+
+ def WriteJetFileFromConfig (self, options):
+ """Write JET file from config file."""
+
+ # open the output file and write the header
+ output_file = open(self.config.filename, 'wb')
+ jet_header = struct.pack(JET_HEADER_STRUCT, JET_HEADER_TAG, 0)
+ output_file.write(jet_header)
+
+ # write the JINF chunk
+ jet_info = struct.pack(JINF_STRUCT,
+ JET_INFO_CHUNK, struct.calcsize(JINF_STRUCT) - 8,
+ JINF_JET_VERSION, JET_VERSION,
+ JINF_NUM_SMF_CHUNKS, len(self.segments),
+ JINF_NUM_DLS_CHUNKS, len(self.libraries))
+ output_file.write(jet_info)
+
+ # write the JCOP chunk (if any)
+ if self.config.copyright is not None:
+ size = len(self.config.copyright) + 1
+ if size & 1:
+ size += 1
+ extra_byte = True
+ else:
+ extra_byte = False
+ jet_copyright = struct.pack(JCOP_STRUCT, JCOP_CHUNK, size)
+ output_file.write(jet_copyright)
+ output_file.write(self.config.copyright)
+ output_file.write(chr(0))
+ if extra_byte:
+ output_file.write(chr(0))
+
+ # write the app data chunk (if any)
+ if self.config.app_data is not None:
+ size = os.path.getsize(self.config.app_data)
+ if size & 1:
+ size += 1
+ extra_byte = True
+ else:
+ extra_byte = False
+ jet_app_data = struct.pack(JAPP_STRUCT, JAPP_CHUNK, size)
+ output_file.write(jet_app_data)
+ with open(self.config.app_data, 'rb') as f:
+ output_file.write(f.read())
+ if extra_byte:
+ output_file.write(chr(0))
+
+ # copy the MIDI segments
+ seg_num = 0
+ for segment in self.segments:
+ logging.debug('Writing segment %d' % seg_num)
+
+ # open SMF file and read it
+ jet_segfile = JetSegmentFile(segment.filename, 'rb')
+ jet_segfile.ReadFromStream()
+
+ # insert events
+ jet_segfile.AddJetEvents(segment.jetevents)
+
+ # trim to length specified in config file
+ jet_segfile.ExtractEvents(segment.start, segment.end, segment.length, segment.quantize, self.config.chase_controllers)
+
+ # chase controller events and fix them
+ if self.config.chase_controllers:
+ jet_segfile.SyncClips()
+
+ # delete empty tracks
+ if self.config.delete_empty_tracks:
+ jet_segfile.DeleteEmptyTracks()
+
+ # write separate output file if requested
+ if segment.output is not None:
+ jet_segfile.SaveAs(segment.output)
+
+ # write dump file
+ if segment.dump_file is not None:
+ with open(segment.dump_file, 'w') as f:
+ jet_segfile.DumpTracks(f)
+
+ # write the segment header
+ header_pos = output_file.tell()
+ smf_header = struct.pack(JET_HEADER_STRUCT, JET_SMF_CHUNK, 0)
+ output_file.write(smf_header)
+ start_pos = output_file.tell()
+
+ # write SMF file to output file
+ jet_segfile.Write(output_file, offset=start_pos)
+ jet_segfile.close()
+
+ # return to segment header and write actual size
+ end_pos = output_file.tell()
+ file_size = end_pos - start_pos
+ if file_size & 1:
+ file_size += 1
+ end_pos += 1
+ output_file.seek(header_pos, 0)
+ smf_header = struct.pack(JET_HEADER_STRUCT, JET_SMF_CHUNK, file_size)
+ output_file.write(smf_header)
+ output_file.seek(end_pos, 0)
+
+ seg_num += 1
+
+ # copy the DLS segments
+ for library in self.libraries:
+ if FileExists(library):
+ # open SMF file and get size
+ lib_file = (open(library,'rb'))
+ lib_file.seek(0,2)
+ file_size = lib_file.tell()
+ lib_file.seek(0)
+
+ # write the library header
+ dls_header = struct.pack(JET_HEADER_STRUCT, JET_DLS_CHUNK, file_size)
+ output_file.write(dls_header)
+
+ # copy DLS file to output file
+ output_file.write(lib_file.read())
+ lib_file.close()
+
+ # write the header with the read data size
+ file_size = output_file.tell()
+ output_file.seek(0)
+ jet_header = struct.pack(JET_HEADER_STRUCT, JET_HEADER_TAG, file_size - struct.calcsize(JET_HEADER_STRUCT))
+ output_file.write(jet_header)
+ output_file.close()
+
+ def GetMidiFiles(self):
+ """ Gets a list of midifiles """
+ midiFiles = []
+ for segment in self.segments:
+ if segment.filename not in midiFiles:
+ midiFiles.append(segment.filename)
+ return midiFiles
+
+ def GetLibraries(self):
+ """ Gets the libraries """
+ return self.libraries
+
+ def GetEvents(self, segName):
+ """ Gets the events for a segment """
+ for segment in self.segments:
+ if segment.segname == segName:
+ return segment.jetevents
+ return None
+
+ def GetEvent(self, segName, eventName):
+ """ Gets a single event from a segment """
+ for segment in self.segments:
+ if segment.segname == segName:
+ for event in segment.jetevents:
+ if event.event_name == eventName:
+ return event
+ return None
+
+ def AddEvent(self, segname, event_name, event_type, event_id, track_num, channel_num, event_start, event_end):
+ """ Adds an event """
+ for segment in self.segments:
+ if segment.segname == segname:
+ segment.jetevents.append(JetEvent(event_name, event_type, int(event_id), int(track_num), int(channel_num), event_start, event_end))
+
+ def ReplaceEvents(self, segname, newEvents):
+ """ Replaces all events """
+ for segment in self.segments:
+ if segment.segname == segname:
+ segment.jetevents = newEvents
+ return segment
+
+ def UpdateEvent(self, segname, orgeventname, event_name, event_type, event_id, track_num, channel_num, event_start, event_end):
+ """ Updates an event """
+ for segment in self.segments:
+ if segment.segname == segname:
+ for jetevent in segment.jetevents:
+ if jetevent.event_name == orgeventname:
+ jetevent.event_name = event_name
+ jetevent.event_type = event_type
+ jetevent.event_id = event_id
+ jetevent.track_num = track_num
+ jetevent.channel_num = channel_num
+ jetevent.event_start = event_start
+ jetevent.event_end = event_end
+
+ def DeleteSegmentsMatchingPrefix(self, prefix):
+ """ Deletes all segments matching name """
+ iOnce = True
+ iAgain = False
+ while(iOnce or iAgain):
+ iOnce = False
+ iAgain = False
+ for segment in self.segments:
+ if segment.segname[0:len(prefix)].upper() == prefix.upper():
+ self.segments.remove(segment)
+ iAgain = True
+
+ def DeleteEvent(self, segname, event_name):
+ """ Deletes an event """
+ for segment in self.segments:
+ if segment.segname == segname:
+ for jetevent in segment.jetevents:
+ if jetevent.event_name == event_name:
+ segment.jetevents.remove(jetevent)
+
+ def DeleteEventsMatchingPrefix(self, segname, prefix):
+ """ Deletes all events matching name """
+ for segment in self.segments:
+ if segment.segname == segname:
+ iOnce = True
+ iAgain = False
+ while(iOnce or iAgain):
+ iOnce = False
+ iAgain = False
+ for jetevent in segment.jetevents:
+ if jetevent.event_name[0:len(prefix)].upper() == prefix.upper():
+ segment.jetevents.remove(jetevent)
+ iAgain = True
+
+ def MoveEvent(self, segname, movename, event_start, event_end):
+ """ Move an event """
+ for segment in self.segments:
+ if segment.segname == segname:
+ for jetevent in segment.jetevents:
+ if jetevent.event_name == movename:
+ jetevent.event_start = event_start
+ jetevent.event_end = event_end
+ return
+
+ def GetSegments(self):
+ """ Gets all segments """
+ return self.segments
+
+ def GetSegment(self, segName):
+ """ Gets one segment by name """
+ for segment in self.segments:
+ if segment.segname == segName:
+ return segment
+ return None
+
+ def AddSegment(self, segname, filename, start, end, length, output, quantize, jetevents, dlsfile, dump_file, transpose, repeat, mute_flags):
+ """ Adds a segment """
+ if length == JetDefs.MBT_ZEROSTR:
+ length = None
+ if end == JetDefs.MBT_ZEROSTR:
+ end = None
+ self.segments.append(JetSegment(segname, filename, start, end, length, output, quantize, jetevents, dlsfile, dump_file, transpose, repeat, mute_flags))
+
+ def UpdateSegment(self, orgsegname, segname, filename, start, end, length, output, quantize, jetevents, dlsfile, dump_file, transpose, repeat, mute_flags):
+ """ Updates a segment """
+ if length == JetDefs.MBT_ZEROSTR:
+ length = None
+ if end == JetDefs.MBT_ZEROSTR:
+ end = None
+ for segment in self.segments:
+ if segment.segname == orgsegname:
+ segment.segname = segname
+ segment.filename = filename
+ segment.start = start
+ segment.end = end
+ segment.length = length
+ segment.output = output
+ segment.quantize = quantize
+ segment.dlsfile = dlsfile
+ segment.transpose = transpose
+ segment.repeat = repeat
+ segment.mute_flags = mute_flags
+
+ def MoveSegment(self, segname, start, end):
+ """ Moves a segment """
+ for segment in self.segments:
+ if segment.segname == segname:
+ segment.start = start
+ segment.end = end
+ return
+
+ def DeleteSegment(self, segname):
+ """ Deletes a segment """
+ for segment in self.segments:
+ if segment.segname == segname:
+ self.segments.remove(segment)
+
+ def SaveJetConfig(self, configFile):
+ """ Saves the jet config file """
+ if self.config.filename == '' or self.config.filename == None:
+ self.config.filename = FileJustRoot(configFile) + ".JET"
+ config = ConfigParser.ConfigParser()
+ config.add_section(OUTPUT_SECTION)
+ config.set(OUTPUT_SECTION, OUTPUT_FILENAME, self.config.filename)
+ config.set(OUTPUT_SECTION, OUTPUT_CHASE_CONTROLLERS, self.config.chase_controllers)
+ config.set(OUTPUT_SECTION, OUTPUT_OMIT_EMPTY_TRACKS, self.config.delete_empty_tracks)
+ if self.config.copyright is not None:
+ config.set(OUTPUT_SECTION, OUTPUT_COPYRIGHT, self.config.copyright)
+ if self.config.app_data is not None:
+ config.set(OUTPUT_SECTION, OUTPUT_APP_DATA, self.config.app_data)
+
+ self.libraries = []
+ seg_num = 0
+ for segment in self.segments:
+ segment_name = SEGMENT_SECTION + str(seg_num)
+ config.add_section(segment_name)
+ config.set(segment_name, SEGMENT_NAME, segment.segname)
+ config.set(segment_name, SEGMENT_FILENAME, segment.filename)
+
+ config.set(segment_name, SEGMENT_DLSFILE, segment.dlsfile)
+ if FileExists(segment.dlsfile):
+ if not segment.dlsfile in self.libraries:
+ self.libraries.append(segment.dlsfile)
+ config.set(segment_name, SEGMENT_START, segment.start)
+ if segment.end > JetDefs.MBT_ZEROSTR and len(segment.end) > 0:
+ config.set(segment_name, SEGMENT_END, segment.end)
+ if segment.length > JetDefs.MBT_ZEROSTR and len(segment.length) > 0:
+ config.set(segment_name, SEGMENT_LENGTH, segment.length)
+ config.set(segment_name, SEGMENT_OUTPUT, segment.output)
+ config.set(segment_name, SEGMENT_QUANTIZE, segment.quantize)
+ if segment.dump_file is not None:
+ config.set(segment_name, SEGMENT_DUMP_FILE, segment.dump_file)
+ config.set(segment_name, SEGMENT_TRANSPOSE, segment.transpose)
+ config.set(segment_name, SEGMENT_REPEAT, segment.repeat)
+ config.set(segment_name, SEGMENT_MUTE_FLAGS, segment.mute_flags)
+
+ clip_num = 0
+ app_num = 0
+ for jet_event in segment.jetevents:
+ if jet_event.event_type == JetDefs.E_CLIP:
+ clip_name = CLIP_PREFIX + str(clip_num)
+ 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)
+ config.set(segment_name, clip_name, s)
+ clip_num += 1
+ elif jet_event.event_type == JetDefs.E_APP:
+ app_name = APP_PREFIX + str(app_num)
+ 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)
+ config.set(segment_name, app_name, s)
+ app_num += 1
+ elif jet_event.event_type == JetDefs.E_EOS:
+ s = "%s,%s,%s" % (jet_event.track_num, jet_event.channel_num, jet_event.event_start)
+ config.set(segment_name, SEGMENT_END_MARKER, s)
+
+ seg_num += 1
+
+ lib_num = 0
+ config.add_section(LIBRARY_SECTION)
+ for library in self.libraries:
+ library_name = LIBRARY_FILENAME + str(lib_num)
+ config.set(LIBRARY_SECTION, library_name, library)
+ lib_num += 1
+
+ FileKillClean(configFile)
+ cfgfile = open(configFile,'w')
+ config.write(cfgfile)
+ cfgfile.close()
+
+ def InitializeConfig(self, configFile):
+ """ Initializes the values for an empty flag """
+ self.config.filename = FileJustRoot(configFile) + ".JET"
+ self.config.chase_controllers = True
+ self.config.delete_empty_tracks = False
+ self.config.copyright = None
+ self.config.app_data = None
+ self.segments = []
+ self.libraries = []
+ self.config_file = configFile
+ self.SaveJetConfig(configFile)
+
+
+
+#---------------------------------------------------------------
+# main
+#---------------------------------------------------------------
+if __name__ == '__main__':
+ sys = __import__('sys')
+ optparse = __import__('optparse')
+
+ # parse command line options
+ parser = optparse.OptionParser(version=VERSION)
+ parser.set_defaults(log_level=logging.INFO, log_file=None)
+ parser.add_option('-d', '--debug', action="store_const", const=logging.DEBUG, dest='log_level', help='Enable debug output')
+ parser.add_option('-l', '--log_file', dest='log_file', help='Write debug output to log file')
+ (options, args) = parser.parse_args()
+
+ # get master logger
+ logger = logging.getLogger('')
+ logger.setLevel(options.log_level)
+
+ # create console logger
+ console_logger = logging.StreamHandler()
+ console_logger.setFormatter(logging.Formatter('%(message)s'))
+ logger.addHandler(console_logger)
+
+ # create rotating file logger
+ if options.log_file is not None:
+ file_logger = logging.FileHandler(options.log_file, 'w')
+ file_logger.setFormatter(logging.Formatter('%(message)s'))
+ logger.addHandler(file_logger)
+
+ # process files
+ for arg in args:
+ print arg
+ jet_file = JetFile(arg, options)
+ jet_file.WriteJetFileFromConfig(options)
+