xref: /aosp_15_r20/external/sonivox/jet_tools/JetCreator/JetFile.py (revision f81fb7c475c4b71ff83bdcc517de2a8c174e4e5c)
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