Assists music production by grouping standalone programs into sessions. Community version of "Non Session Manager".
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

144 lines
6.0KB

  1. #!/usr/bin/env python
  2. # Copyright (C) 2013 Jonathan Moore Liles #
  3. # #
  4. # This program is free software; you can redistribute it and/or modify it #
  5. # under the terms of the GNU General Public License as published by the #
  6. # Free Software Foundation; either version 2 of the License, or (at your #
  7. # option) any later version. #
  8. # #
  9. # This program is distributed in the hope that it will be useful, but WITHOUT #
  10. # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
  11. # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
  12. # more details. #
  13. # #
  14. # You should have received a copy of the GNU General Public License along #
  15. # with This program; see the file COPYING. If not,write to the Free Software #
  16. # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #
  17. import xml.etree.ElementTree as et
  18. import random
  19. import sys
  20. import os
  21. from datetime import date
  22. import shutil
  23. if len(sys.argv) != 3:
  24. print "Usage: import-ardour-session [PATH_TO_ARDOUR_FILE] [NAME_OF_NON_TIMELINE_PROJECT]"
  25. sys.exit( 1 )
  26. ArdourFilePath = sys.argv[1];
  27. NonTimelineProjectPath = sys.argv[2];
  28. try:
  29. os.makedirs( NonTimelineProjectPath );
  30. os.makedirs( NonTimelineProjectPath + "/sources");
  31. except:
  32. print "Output path already exists"
  33. sys.exit( 1 )
  34. History = open( NonTimelineProjectPath + "/history", 'w' );
  35. try:
  36. tree = et.parse( ArdourFilePath );
  37. except:
  38. print "Invalid XML input"
  39. sys.exit( 1 )
  40. root = tree.getroot();
  41. Sources = {}
  42. DiskStreams = {}
  43. print "Gathering session info"
  44. if root.tag != "Session":
  45. print "Not an Ardour session?"
  46. sys.exit(1)
  47. if root.attrib["version"][0] != "2":
  48. print "Only known to work with version 2 projects..."
  49. sys.exit(1)
  50. ProjectName = root.attrib["name"]
  51. print "Converting Ardour session \"" + ProjectName + "\" to Non Timeline format. Please be patient."
  52. Info = open( NonTimelineProjectPath + "/info", 'w' )
  53. 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" )
  54. print "Gathering sources."
  55. for node in root.findall( "./Sources/Source" ):
  56. Sources[node.attrib["id"]] = node;
  57. # print "\tFound source " + node.attrib["name"]
  58. print "Gathering diskstreams."
  59. for node in root.findall( "./DiskStreams/AudioDiskstream" ):
  60. DiskStreams[node.attrib["id"]] = node;
  61. # print "\tFound diskstream " + node.attrib["name"];
  62. LoggableID = 1;
  63. def NewID():
  64. global LoggableID
  65. ID="0x%x" % LoggableID
  66. LoggableID = LoggableID + 1
  67. return ID
  68. print "Processing tempo."
  69. for node in root.findall("./TempoMap/Tempo"):
  70. TempoID = NewID()
  71. History.write( "Tempo_Point " + TempoID + " create :start 0 :tempo " + node.attrib["beats-per-minute"] + "\n")
  72. for node in root.findall("./TempoMap/Meter"):
  73. TimeID = NewID()
  74. History.write( "Time_Point " + TimeID + " create :start 0 :beats_per_bar " + node.attrib["beats-per-bar"] + " :beat_type " + node.attrib["note-type"] + "\n")
  75. print "Processing playlists."
  76. for node in root.findall( "./Playlists/Playlist" ):
  77. try:
  78. Track = DiskStreams[node.attrib["orig_diskstream_id"]]
  79. except:
  80. print "\tSkipping playlist " + node.attrib["name"] + " for unknown diskstream"
  81. continue
  82. if node.attrib["name"] == Track.attrib["playlist"]:
  83. print "\tFound playlist " + node.attrib["name"]
  84. for chan in range(0, int( Track.attrib["channels"] )):
  85. TrackID = NewID()
  86. SequenceID = NewID()
  87. if int(Track.attrib["channels"]) > 1:
  88. TrackName = Track.attrib["name"] + "-" + ( "%i" % chan )
  89. else:
  90. TrackName = Track.attrib["name"]
  91. History.write( "Track " + TrackID + " create :name \"" + TrackName + "\"" + ( " :sequence " + SequenceID ) + " :color " + ( "%i" % random.randint(256,123123123)) + " :inputs 1 :outputs 1\n" )
  92. History.write( "Audio_Sequence " + SequenceID + " create :track " + TrackID + " :name \"" + node.attrib["name"] + "\"\n" )
  93. for n2 in node.findall("./Region"):
  94. RegionID = NewID();
  95. SourceName = Sources[n2.attrib["source-" + ( "%i" % chan )]].attrib["name"];
  96. if not os.path.exists( NonTimelineProjectPath + "/sources/" + SourceName ):
  97. print "\t\tCopying source: " + SourceName;
  98. shutil.copy( os.path.dirname(ArdourFilePath) + "/interchange/" + ProjectName + "/audiofiles/" + SourceName,
  99. NonTimelineProjectPath + "/sources/" )
  100. History.write ("Audio_Region " + RegionID +
  101. " create :source \"" + Sources[n2.attrib["source-" + ( "%i" % chan )]].attrib["name"] +
  102. "\" :start " + n2.attrib["position"] +
  103. " :length " + n2.attrib["length"] +
  104. " :offset " + n2.attrib["start"] +
  105. " :sequence " + SequenceID + "\n")
  106. else:
  107. print "\tSkipping inactive playlist"
  108. print "Done. You've been freed. Go make music!"