Changeset 1502
- Timestamp:
- Tue May 6 21:49:54 2008
- Files:
-
- JonoEdit/trunk/Jokosher/ProjectManager.py (modified) (diff)
- JonoEdit/trunk/Jokosher/EventViewer.py (modified) (diff)
- JonoEdit/trunk/Jokosher/Event.py (modified) (diff)
- JonoEdit/trunk/Jokosher/LevelsList.py (added)
- JonoEdit/trunk/Jokosher/Project.py (modified) (diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
JonoEdit/trunk/Jokosher/ProjectManager.py
r1501 r1502 11 11 12 12 import urlparse, os, gzip, shutil, gst 13 import Globals, Utils, UndoSystem 13 import Globals, Utils, UndoSystem, LevelsList 13 13 import Project, Instrument, Event 14 14 import xml.dom.minidom as xml … … 59 59 raise CreateProjectError(2) 60 60 else: 61 audio_dir = os.path.join(projectdir, "audio")62 61 try: 63 62 os.mkdir(projectdir) 64 os.mkdir(audio_dir) 63 os.mkdir(project.audio_path) 64 os.mkdir(project.levels_path) 65 65 except: 66 66 raise CreateProjectError(3) … … 249 249 event._Event__fadePointsDict[pos] = value 250 250 251 try: 252 levelsXML = xmlNode.getElementsByTagName("Levels")[0] 253 except IndexError: 254 Globals.debug("No event levels in project file") 255 event.GenerateWaveform() 256 else: 257 if levelsXML.nodeType == xml.Node.ELEMENT_NODE: 258 value = str(levelsXML.getAttribute("value")) 259 event.levels = map(float, value.split(",")) 260 261 if event.isLoading: 262 event.GenerateWaveform() 263 251 event.GenerateWaveform() 264 252 event._Event__UpdateAudioFadePoints() 265 253 event.CreateFilesource() … … 416 404 417 405 if not isDead: 418 if event.isLoading or event.isRecording: 419 event.GenerateWaveform() 406 #if event.isLoading or event.isRecording: 407 # we have to always generate waveform because 0.10 uses different levels format 408 event.GenerateWaveform() 420 409 event._Event__UpdateAudioFadePoints() 421 410 event.CreateFilesource() … … 510 499 class _LoadZPTenFile(_LoadZPNFile): 511 500 LOADING_VERSION = "0.10" 501 502 def LoadEvent(self, event, xmlNode, isDead=False): 503 """ 504 Restores an Event from its version 0.10 XML representation. 505 506 Parameters: 507 event -- the Event instance to apply loaded properties to. 508 xmlNode -- the XML node to retreive data from. 509 """ 510 params = xmlNode.getElementsByTagName("Parameters")[0] 511 512 Utils.LoadParametersFromXML(event, params) 513 514 if not os.path.isabs(event.file): 515 # If there is a relative path for event.file, assume it is in the audio dir 516 event.file = os.path.join(self.project.audio_path, event.file) 517 518 try: 519 xmlPoints = xmlNode.getElementsByTagName("FadePoints")[0] 520 except IndexError: 521 Globals.debug("Missing FadePoints in Event XML") 522 else: 523 event._Event__fadePointsDict = Utils.LoadDictionaryFromXML(xmlPoints) 524 525 if not isDead: 526 levels_path = os.path.join(self.project.levels_path, event.levels_file) 527 try: 528 event.levels_list.fromfile(levels_path) 529 except LevelsList.CorruptFileError: 530 Globals.debug("Cannot load levels from file", levels_path) 531 if not event.levels_list: 532 event.GenerateWaveform() 533 event._Event__UpdateAudioFadePoints() 534 event.CreateFilesource() 535 536 #_____________________________________________________________________ 512 537 513 538 #========================================================================= -
JonoEdit/trunk/Jokosher/EventViewer.py
r1490 r1502 16 16 from Project import Project 17 17 import Utils 18 import os 18 import os, sys 18 18 import gettext 19 19 _ = gettext.gettext 20 20 import Globals 21 import itertools 21 22 22 23 #========================================================================= … … 352 353 context.fill() 353 354 354 if self.event.levels and (self.event.duration or self.event.loadingLength): 355 if self.event.levels_list and (self.event.duration or self.event.loadingLength): 354 355 if self.event.loadingLength: 355 scale = (self.event.loadingLength * self.project.viewScale) / float(len(self.event.levels))356 duration = self.event.loadingLength 355 356 else: 356 scale = (self.event.duration * self.project.viewScale) / float(len(self.event.levels))357 duration = self.event.duration 356 357 357 # Draw waveform358 x_pos = int(rect.x/scale)359 x = 0360 skipFactor = max(int(self._MIN_POINT_SEPARATION / scale), 1)361 358 context.move_to(0,rect.height) 362 359 362 359 # get levels list 363 fadedLevels = self.event.GetFadeLevels() 360 #fadedLevels = self.event.GetFadeLevels() 361 362 levels = self.event.levels_list 363 length = len(levels) 364 364 365 for peak in fadedLevels[x_pos::skipFactor]: 366 x = (x_pos * scale) - rect.x 367 peakOnScreen = int(peak * rect.height) 365 # time offset of the start of the drawing area in milliseconds 366 starting_time = int(rect.x / self.project.viewScale * 1000) 367 starting_index = levels.find_endtime_index(starting_time) 368 369 last_x = -2 370 skip_list = [] 371 iterator = itertools.islice(levels, starting_index, length) 372 for endtime, peak in iterator: 373 x = int((endtime - starting_time) * self.project.viewScale / 1000) 374 375 peakOnScreen = int(peak * rect.height / sys.maxint) 376 skip_list.append(peakOnScreen) 377 if (x - last_x) < self._MIN_POINT_SEPARATION: 378 continue 379 380 peakOnScreen = sum(skip_list) / len(skip_list) 368 381 context.line_to(x, rect.height - peakOnScreen) 369 382 383 skip_list = [] 384 last_x = x 370 385 if x > rect.width: 371 386 break 372 x_pos += skipFactor373 387 374 388 context.line_to(x, rect.height) … … 1177 1191 self.redrawWaveform = True 1178 1192 self.queue_resize() 1179 self.last_num_levels = len(self.event.levels)1180 1193 self.currentScale = self.project.viewScale 1181 1194 self.queue_draw() -
JonoEdit/trunk/Jokosher/Event.py
r1501 r1502 18 18 pygst.require("0.10") 19 19 import gst, gobject 20 import Utils 20 import Utils, LevelsList 20 20 import UndoSystem 21 21 import Globals … … 90 90 91 91 self.selection = [0, 0] # List start and end of selection (for fades, etc) measured in seconds 92 self.levels = [] # Array of audio levels to be drawn for this event92 self.levels_list = LevelsList.LevelsList() # LevelsList class containing array of audio levels to be drawn for this event 92 92 93 93 self.id = instrument.project.GenerateUniqueID(id) #check is id is already taken, then set it. … … 224 224 Utils.StoreDictionaryToXML(doc, xmlPoints, self.__fadePointsDict, "FadePoint") 225 225 226 if self.levels: 227 levelsXML = doc.createElement("Levels") 228 ev.appendChild(levelsXML) 229 stringList = map(str, self.levels) 230 levelsXML.setAttribute("value", ",".join(stringList)) 226 if self.levels_list: 227 self.levels_list.tofile(os.path.join(self.instrument.project.levels_path, self.levels_file)) 231 228 232 229 #_____________________________________________________________________ … … 580 577 581 578 elif st.get_name() == "level": 582 newLevel = self.__CalculateAudioLevel(st["peak"]) 583 self.levels.append(newLevel) 584 585 end = st["endtime"] / float(gst.SECOND) 586 self.loadingLength = int(end) 579 end = st["endtime"] 580 self.levels_list.append(end, st["peak"]) 581 self.loadingLength = int(end / gst.SECOND) 587 582 588 583 # Only send events every second processed to reduce GUI load … … 722 717 self.bus.connect("message::error", self.bus_error) 723 718 724 self.levels = []719 self.levels_list = LevelsList.LevelsList() 724 719 self.isLoading = True 725 720 self.emit("loading") … … 752 747 self.bus.connect("message::error", self.bus_error) 753 748 754 self.levels = []749 self.levels_list = LevelsList.LevelsList() 754 749 self.isLoading = True 755 750 self.emit("loading") … … 809 804 st = message.structure 810 805 if st and message.src.get_name() == "recordlevel": 811 newLevel = self.__CalculateAudioLevel(st["peak"]) 812 self.levels.append(newLevel) 806 self.levels_list.append(st["endtime"], st["peak"]) 813 807 814 808 end = st["endtime"] / float(gst.SECOND) … … 824 818 #_____________________________________________________________________ 825 819 826 def __CalculateAudioLevel(self, channelLevels):827 """828 Calculates an average for all channel levels.829 830 Parameters:831 channelLevels -- list of levels from each channel.832 833 Returns:834 an average level, also taking into account negative infinity numbers,835 which will be discarded in the average.836 """837 negInf = float("-inf")838 peaktotal = 0839 peakcount = 0840 for peak in channelLevels:841 #don't add -inf values cause 500 + -inf is still -inf842 if peak != negInf:843 peaktotal += peak844 peakcount += 1845 #avoid a divide by zero here846 if peakcount > 0:847 peaktotal /= peakcount848 #it must be put back to -inf if nothing has been added to it, so that the DbToFloat conversion will work849 elif peakcount == 0:850 peaktotal = negInf851 852 #convert to 0...1 float, and return853 return Utils.DbToFloat(peaktotal)854 855 #_____________________________________________________________________856 857 820 def SetSelected(self, sel): 858 821 """ -
JonoEdit/trunk/Jokosher/Project.py
r1501 r1502 38 38 39 39 """ The Project structure version. Will be useful for handling old save files. """ 40 Globals.VERSION = " 1.0"40 Globals.VERSION = "0.10" 40 40 41 41 """ The audio playback state enum values """ … … 656 656 raise "No save path specified!" 657 657 path = self.projectfile 658 658 659 if not self.audio_path: 660 self.audio_path = os.path.join(os.path.dirname(path), "audio") 661 if not self.levels_path: 662 self.levels_path = os.path.join(os.path.dirname(path), "levels") 663 664 if os.path.exists(self.audio_path): 665 if not os.path.isdir(self.audio_path): 666 raise "Audio save location is not a directory" 667 else: 668 os.mkdir(self.audio_path) 669 670 if os.path.exists(self.levels_path): 671 if not os.path.isdir(self.levels_path): 672 raise "Levels save location is not a directory" 673 else: 674 os.mkdir(self.levels_path) 675 659 676 if not path.endswith(".jokosher"): 660 677 path = path + ".jokosher" … … 680 697 head.appendChild(params) 681 698 682 items = ["viewScale", "viewStart", "name", "author", " project_audio_path", "project_levels_path",699 items = ["viewScale", "viewStart", "name", "author", "audio_path", "levels_path", 682 699 "transportMode", "bpm", "meter_nom", "meter_denom"] 683 700
