""" | |
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) | |