# # THIS FILE IS PART OF THE JOKOSHER PROJECT AND LICENSED UNDER THE GPL. SEE # THE 'COPYING' FILE FOR DETAILS # # Event.py # # This module is the non-gui class the represents events. Events # represent a piece of audio such as a file or something that was recorded. # This module handles loading and saving events from xml, the gstreamer # bits event properties as well as any event specific functionality like; # audio fades, splits, joins, trims, waveform levels, etc. # #------------------------------------------------------------------------------- import xml.dom.minidom as xml import os, sys, os.path import pygst pygst.require("0.10") import gst, gobject import Utils, LevelsList import UndoSystem, IncrementalSave import Globals import gettext import urllib import PlatformUtils from elements.singledecodebin import SingleDecodeBin _ = gettext.gettext #========================================================================= class Event(gobject.GObject): """ This class handles maintaing the information for a single audio event, normally, a fragment of a recorded file. Signals: "waveform" -- The waveform date for this event has changed. "position" -- The starting position of this event has changed. "length" -- The length of this event has changed. "corrupt" -- The audio file for this event is not playable. Two strings with detailed information are sent. "loading" -- Loading has started or completed. """ __gsignals__ = { "waveform" : ( gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, () ), "position" : ( gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, () ), "length" : ( gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, () ), "corrupt" : ( gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_STRING,)), "loading" : ( gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, () ), "selected" : ( gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, () ) } """ The level sample interval in seconds """ LEVEL_INTERVAL = 0.1 LEVELS_FILE_EXTENSION = ".leveldata" #_____________________________________________________________________ def __init__(self, instrument, file=None, id=None, filelabel=None): """ Creates a new instance of Event. Parameters: instrument -- Instrument associated with this Event. file -- the file this Event should play. id -- unique ID for this Event. If it's taken, a new one will be generated. filelabel -- label to print in error messages. It can be different from the file parameter. """ gobject.GObject.__init__(self) self.id = instrument.project.GenerateUniqueID(id) #check is id is already taken, then set it. self.start = 0.0 # Time in seconds at which the event begins self.duration = 0.0 # Duration in seconds of the event # The file this event should play (without escaped characters) # If you need characters escaped, please do self.file.replace(" ", "\ ") # but **do not** assign it to this variable. self.file = file if self.file and os.path.isabs(self.file) and \ PlatformUtils.samefile(instrument.project.audio_path, os.path.dirname(self.file)): # If the file is in the audio dir, just include the filename, not the absolute path Globals.debug("Event() given absolute file, should be relative:", self.file) self.file = os.path.basename(self.file) # levels_file is a filename only, no directory information for levels here. basename = os.path.basename(self.file or "Unknown") self.levels_file = "%s_%d%s" % (basename, self.id, self.LEVELS_FILE_EXTENSION) # the label is the filename to print in error messages # if it differs from the real filename (i.e its been copied into the project) if filelabel != None: self.filelabel = filelabel else: self.filelabel = file self.isSelected = False # True if the event is currently selected self.name = "New Event" # Name of this event self.selection = [0, 0] # List start and end of selection (for fades, etc) measured in seconds self.levels_list = LevelsList.LevelsList() # LevelsList class containing array of audio levels to be drawn for this event self.instrument = instrument # The parent instrument self.gnlsrc = None # The gstreamer gnlsource object. self.single_decode_bin = None # The gstreamer file decoder element. self.offset = 0.0 # Offset through the file in seconds self.isLoading = False # True if the event is currently loading level data self.isDownloading = False # True if the event is currently loading from a remote source. self.isRecording = False # True if the event is currently loading level data from a live recording self.loadingLength = 0 # The length of the file in seconds as its being rendered self.lastEnd = 0 # The last length of the loading file - used to minimise redraws self.loadingPipeline = None # The Gstreamer pipeline used to load the waveform self.bus = None # The bus to monitor messages on the loadingPipeline self.CreateFilesource() # a private dictionary containing the audio fade point times as keys # and the volume for that point between 0 and 1 as the values. # this is private, so if someone else wants a list of audio fade points # they must use the sorted list below. self.__fadePointsDict = {} # A list of control points for the audio fades # where each tuple is (