| @@ -0,0 +1,143 @@ | |||
| #!/usr/bin/env python | |||
| # Copyright (C) 2013 Jonathan Moore Liles # | |||
| # # | |||
| # This program is free software; you can redistribute it and/or modify it # | |||
| # under the terms of the GNU General Public License as published by the # | |||
| # Free Software Foundation; either version 2 of the License, or (at your # | |||
| # option) any later version. # | |||
| # # | |||
| # This program is distributed in the hope that it will be useful, but WITHOUT # | |||
| # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # | |||
| # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # | |||
| # more details. # | |||
| # # | |||
| # You should have received a copy of the GNU General Public License along # | |||
| # with This program; see the file COPYING. If not,write to the Free Software # | |||
| # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # | |||
| import xml.etree.ElementTree as et | |||
| import random | |||
| import sys | |||
| import os | |||
| from datetime import date | |||
| import shutil | |||
| if len(sys.argv) != 3: | |||
| print "Usage: import-ardour-session [PATH_TO_ARDOUR_FILE] [NAME_OF_NON_TIMELINE_PROJECT]" | |||
| sys.exit( 1 ) | |||
| ArdourFilePath = sys.argv[1]; | |||
| NonTimelineProjectPath = sys.argv[2]; | |||
| try: | |||
| os.makedirs( NonTimelineProjectPath ); | |||
| os.makedirs( NonTimelineProjectPath + "/sources"); | |||
| except: | |||
| print "Output path already exists" | |||
| sys.exit( 1 ) | |||
| History = open( NonTimelineProjectPath + "/history", 'w' ); | |||
| try: | |||
| tree = et.parse( ArdourFilePath ); | |||
| except: | |||
| print "Invalid XML input" | |||
| sys.exit( 1 ) | |||
| root = tree.getroot(); | |||
| Sources = {} | |||
| DiskStreams = {} | |||
| print "Gathering session info" | |||
| if root.tag != "Session": | |||
| print "Not an Ardour session?" | |||
| sys.exit(1) | |||
| if root.attrib["version"][0] != "2": | |||
| print "Only known to work with version 2 projects..." | |||
| sys.exit(1) | |||
| ProjectName = root.attrib["name"] | |||
| print "Converting Ardour session \"" + ProjectName + "\" to Non Timeline format. Please be patient." | |||
| Info = open( NonTimelineProjectPath + "/info", 'w' ) | |||
| Info.write( "created by\n\tNon-Timeline 1.2.0\ncreated on\n\t" + date.today().ctime() + "\nversion\n\t2\nsample rate\n\t" + root.attrib["sample-rate"] + "\n" ) | |||
| print "Gathering sources." | |||
| for node in root.findall( "./Sources/Source" ): | |||
| Sources[node.attrib["id"]] = node; | |||
| # print "\tFound source " + node.attrib["name"] | |||
| print "Gathering diskstreams." | |||
| for node in root.findall( "./DiskStreams/AudioDiskstream" ): | |||
| DiskStreams[node.attrib["id"]] = node; | |||
| # print "\tFound diskstream " + node.attrib["name"]; | |||
| LoggableID = 1; | |||
| def NewID(): | |||
| global LoggableID | |||
| ID="0x%x" % LoggableID | |||
| LoggableID = LoggableID + 1 | |||
| return ID | |||
| print "Processing tempo." | |||
| for node in root.findall("./TempoMap/Tempo"): | |||
| TempoID = NewID() | |||
| History.write( "Tempo_Point " + TempoID + " create :start 0 :tempo " + node.attrib["beats-per-minute"] + "\n") | |||
| for node in root.findall("./TempoMap/Meter"): | |||
| TimeID = NewID() | |||
| History.write( "Time_Point " + TimeID + " create :start 0 :beats_per_bar " + node.attrib["beats-per-bar"] + " :beat_type " + node.attrib["note-type"] + "\n") | |||
| print "Processing playlists." | |||
| for node in root.findall( "./Playlists/Playlist" ): | |||
| try: | |||
| Track = DiskStreams[node.attrib["orig_diskstream_id"]] | |||
| except: | |||
| print "\tSkipping playlist " + node.attrib["name"] + " for unknown diskstream" | |||
| continue | |||
| if node.attrib["name"] == Track.attrib["playlist"]: | |||
| print "\tFound playlist " + node.attrib["name"] | |||
| for chan in range(0, int( Track.attrib["channels"] )): | |||
| TrackID = NewID() | |||
| SequenceID = NewID() | |||
| if int(Track.attrib["channels"]) > 1: | |||
| TrackName = Track.attrib["name"] + "-" + ( "%i" % chan ) | |||
| else: | |||
| TrackName = Track.attrib["name"] | |||
| History.write( "Track " + TrackID + " create :name \"" + TrackName + "\"" + ( " :sequence " + SequenceID ) + " :color " + ( "%i" % random.randint(256,123123123)) + " :inputs 1 :outputs 1\n" ) | |||
| History.write( "Audio_Sequence " + SequenceID + " create :track " + TrackID + " :name \"" + node.attrib["name"] + "\"\n" ) | |||
| for n2 in node.findall("./Region"): | |||
| RegionID = NewID(); | |||
| SourceName = Sources[n2.attrib["source-" + ( "%i" % chan )]].attrib["name"]; | |||
| if not os.path.exists( NonTimelineProjectPath + "/sources/" + SourceName ): | |||
| print "\t\tCopying source: " + SourceName; | |||
| shutil.copy( os.path.dirname(ArdourFilePath) + "/interchange/" + ProjectName + "/audiofiles/" + SourceName, | |||
| NonTimelineProjectPath + "/sources/" ) | |||
| History.write ("Audio_Region " + RegionID + | |||
| " create :source \"" + Sources[n2.attrib["source-" + ( "%i" % chan )]].attrib["name"] + | |||
| "\" :start " + n2.attrib["position"] + | |||
| " :length " + n2.attrib["length"] + | |||
| " :offset " + n2.attrib["start"] + | |||
| " :sequence " + SequenceID + "\n") | |||
| else: | |||
| print "\tSkipping inactive playlist" | |||
| print "Done. You've been freed. Go make music!" | |||