@@ -23,21 +23,30 @@ import os | |||
from datetime import date | |||
import shutil | |||
if len(sys.argv) != 3: | |||
if len(sys.argv) == 1: | |||
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]; | |||
Overwrite=False | |||
i = 1; | |||
if ( sys.argv[i] == "--overwrite" ): | |||
Overwrite = True | |||
i = i + 1 | |||
ArdourFilePath = sys.argv[i] | |||
i = i + 1 | |||
NonTimelineProjectPath = sys.argv[i] | |||
i = i + 1 | |||
try: | |||
os.makedirs( NonTimelineProjectPath ); | |||
os.makedirs( NonTimelineProjectPath + "/sources"); | |||
except: | |||
print "Output path already exists" | |||
sys.exit( 1 ) | |||
History = open( NonTimelineProjectPath + "/history", 'w' ); | |||
if not Overwrite: | |||
print "Output path already exists!" | |||
sys.exit( 1 ) | |||
try: | |||
tree = et.parse( ArdourFilePath ); | |||
@@ -62,15 +71,6 @@ ProjectName = root.attrib["name"] | |||
print "Converting Ardour session \"" + ProjectName + "\" to Non Timeline format. Please be patient." | |||
Info = open( NonTimelineProjectPath + "/info", 'w' ) | |||
try: | |||
SampleRate = root.attrib["sample-rate"] | |||
except: | |||
print "Couldn't find sample rate... Using default." | |||
SampleRate = "48000" | |||
Info.write( "created by\n\tNon-Timeline 1.2.0\ncreated on\n\t" + date.today().ctime() + "\nversion\n\t2\nsample rate\n\t" + SampleRate + "\n" ) | |||
print "Gathering sources." | |||
for node in root.findall( "./Sources/Source" ): | |||
@@ -102,11 +102,13 @@ def NewID(): | |||
return ID | |||
History = "{\n" | |||
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") | |||
History += ( "\tTempo_Point " + TempoID + " create :start 0 :tempo " + node.attrib["beats-per-minute"] + "\n") | |||
for node in root.findall("./TempoMap/Meter"): | |||
TimeID = NewID() | |||
@@ -115,7 +117,7 @@ for node in root.findall("./TempoMap/Meter"): | |||
except: | |||
BPB = node.attrib["divisions-per-bar"] | |||
History.write( "Time_Point " + TimeID + " create :start 0 :beats_per_bar " + BPB + " :beat_type " + node.attrib["note-type"] + "\n") | |||
History += ( "\tTime_Point " + TimeID + " create :start 0 :beats_per_bar " + BPB + " :beat_type " + node.attrib["note-type"] + "\n") | |||
print "Processing playlists." | |||
@@ -143,8 +145,8 @@ for node in root.findall( "./Playlists/Playlist" ): | |||
TrackName = Track.attrib["name"] | |||
Channels = int(Track.attrib["channels"]) | |||
History.write( "Track " + TrackID + " create :name \"" + TrackName + "\"" + ( " :sequence " + SequenceID ) + " :color " + ( "%i" % random.randint(256,123123123)) + ( " :inputs %i :outputs %i\n" % ( Channels, Channels ) ) ) | |||
History.write( "Audio_Sequence " + SequenceID + " create :track " + TrackID + " :name \"" + node.attrib["name"] + "\"\n" ) | |||
History += ( "\tTrack " + TrackID + " create :name \"" + TrackName + "\"" + ( " :sequence " + SequenceID ) + " :color " + ( "%i" % random.randint(256,123123123)) + ( " :inputs %i :outputs %i\n" % ( Channels, Channels ) ) ) | |||
History += ( "\tAudio_Sequence " + SequenceID + " create :track " + TrackID + " :name \"" + node.attrib["name"] + "\"\n" ) | |||
for n2 in node.findall("./Region"): | |||
RegionID = NewID(); | |||
@@ -188,7 +190,7 @@ for node in root.findall( "./Playlists/Playlist" ): | |||
NonTimelineProjectPath + "/sources/" ) | |||
History.write ("Audio_Region " + RegionID + | |||
History += ("\tAudio_Region " + RegionID + | |||
" create :source \"" + SourceName + | |||
"\" :start " + n2.attrib["position"] + | |||
" :length " + n2.attrib["length"] + | |||
@@ -196,7 +198,22 @@ for node in root.findall( "./Playlists/Playlist" ): | |||
" :sequence " + SequenceID + "\n") | |||
else: | |||
print "\tSkipping inactive playlist" | |||
History += ("}\n") | |||
print "Comitting to disk." | |||
with open( NonTimelineProjectPath + "/info", 'w' ) as InfoFile: | |||
try: | |||
SampleRate = root.attrib["sample-rate"] | |||
except: | |||
print "Couldn't find sample rate... Using default." | |||
SampleRate = "48000" | |||
InfoFile.write( "created by\n\tNon-Timeline 1.2.0\ncreated on\n\t" + date.today().ctime() + "\nversion\n\t2\nsample rate\n\t" + SampleRate + "\n" ) | |||
with open( NonTimelineProjectPath + "/history", 'w' ) as HistoryFile: | |||
HistoryFile.write( History ) | |||
print "Done. You've been freed. Go make music!" | |||
@@ -0,0 +1,103 @@ | |||
# data file for the Fltk User Interface Designer (fluid) | |||
version 1.0300 | |||
header_name {.h} | |||
code_name {.cxx} | |||
decl {\#include <FL/Fl_File_Chooser.H>} {private local | |||
} | |||
decl {\#include <FL/Fl.H>} {private local | |||
} | |||
decl {\#include <FL/x.H>} {private local | |||
} | |||
decl {\#include <unistd.h>} {private local | |||
} | |||
decl {\#include <sys/types.h>} {private local | |||
} | |||
decl {\#include <sys/wait.h>} {private local | |||
} | |||
Function {} {open | |||
} { | |||
code {UserInterface *ui = new UserInterface(); | |||
Fl_Double_Window *w = ui->make_window(); | |||
w->show(); | |||
Fl::run(); | |||
return 0;} {} | |||
} | |||
class UserInterface {open | |||
} { | |||
Function {make_window()} {open | |||
} { | |||
Fl_Window main_window { | |||
label {Import Ardour Session} open | |||
xywh {610 468 395 310} type Double xclass {Non-Timeline} visible | |||
} { | |||
Fl_Box {} { | |||
label {Non Timeline : Ardour Session Importer} | |||
xywh {5 6 385 54} box ROUND_UP_BOX color 90 labelfont 1 labelsize 16 | |||
} | |||
Fl_Box {} { | |||
label {This program will non-descrutively examine an existing Ardour 1, 2 or 3 format session file and replace the current Non Timeline project with the Tracks and Regions it finds. This program will only operate on a new (empty) Non Timeline project.} | |||
xywh {5 66 385 128} box ROUND_UP_BOX align 128 | |||
} | |||
Fl_Return_Button {} { | |||
label Import | |||
callback {pid_t pid; | |||
if ( ! (pid = fork()) ) | |||
{ | |||
char *s; | |||
// asprintf( &s, "xterm -into 0x%lx -e import-ardour-session --overwrite '%s' '%s'", fl_xid( main_window ), file_input->value(), getenv("PWD" )); | |||
asprintf( &s, "import-ardour-session --overwrite '%s' '%s'", file_input->value(), getenv("PWD" )); | |||
exit( system( s ) ); | |||
} | |||
int status; | |||
while ( 0 == waitpid( pid, &status, WNOHANG ) ) | |||
{ | |||
Fl::wait(0.01); | |||
if ( progress->value() >= 100 ) | |||
progress->value( 0 ); | |||
else | |||
progress->value( progress->value() + 5 ); | |||
progress->redraw(); | |||
} | |||
if ( 0 == status ) | |||
fl_message( "Import succesful. You've been freed. Go make music!" ); | |||
else | |||
fl_alert( "There was an error importing this session!" ); | |||
exit(0);} selected | |||
xywh {270 270 115 30} | |||
} | |||
Fl_File_Input file_input { | |||
label {Path to .ardour File:} | |||
xywh {10 226 285 34} align 1 | |||
} | |||
Fl_Button {} { | |||
label Browse | |||
callback {file_input->value( fl_file_chooser( ".ardour file", "*.ardour", NULL, 0 ) );} | |||
xywh {300 231 85 30} | |||
} | |||
Fl_Slider progress { | |||
label {slider:} | |||
xywh {15 272 245 27} type Horizontal color 48 selection_color 63 labeltype NO_LABEL align 18 maximum 100 deactivate | |||
} | |||
} | |||
} | |||
} |
@@ -28,6 +28,15 @@ decl {const float STATUS_UPDATE_FREQ = 0.5f;} {private local | |||
decl {class Fl_Flowpack;} {public global | |||
} | |||
decl {\#include <unistd.h>} {private local | |||
} | |||
decl {\#include <sys/types.h>} {private local | |||
} | |||
decl {\#include <sys/wait.h>} {private local | |||
} | |||
decl {\#include <FL/Fl_Overlay_Window.H>} {private local | |||
} | |||
@@ -100,7 +109,7 @@ decl {extern nsm_client_t *nsm;} {private global | |||
decl {extern char *user_config_dir;} {private global | |||
} | |||
decl {extern char *APP_NAME;} {selected private global | |||
decl {extern char *APP_NAME;} {private global | |||
} | |||
class TLE_Window {open : {public Fl_Overlay_Window} | |||
@@ -252,7 +261,7 @@ Loggable::progress_callback( &TLE::progress_cb, this );} {} | |||
label {Non Timeline} | |||
callback {if ( Fl::event_key() != FL_Escape ) | |||
timeline->command_quit();} open | |||
xywh {520 266 1025 770} type Double resizable | |||
xywh {200 266 1025 770} type Double resizable | |||
code0 {o->xclass( APP_NAME );} | |||
class TLE_Window size_range {900 300 0 0} visible | |||
} { | |||
@@ -375,9 +384,44 @@ if ( n != 2 ) | |||
Project::compact();} | |||
xywh {25 25 40 25} | |||
} | |||
Submenu {} { | |||
label {I&mport} open | |||
xywh {20 20 74 25} | |||
} { | |||
MenuItem {} { | |||
label {Import Ardour Session} | |||
callback {if ( timeline->ntracks() ) | |||
{ | |||
fl_alert( "You can only import into an empty session!" ); | |||
return; | |||
} | |||
pid_t pid; | |||
if ( ! (pid = fork()) ) | |||
{ | |||
exit( system( "import-ardour-session_gui" ) ); | |||
} | |||
char *path = strdup( Project::path() ); | |||
Project::close(); | |||
int status; | |||
while ( 0 == waitpid( pid, &status, WNOHANG ) ) | |||
{ | |||
Fl::wait(0.2); | |||
} | |||
Project::open(path); | |||
free(path);} | |||
xywh {20 20 40 25} | |||
} | |||
} | |||
Submenu {} { | |||
label {&Export} open | |||
xywh {5 5 74 25} deactivate | |||
xywh {5 5 74 25} hide deactivate | |||
} { | |||
MenuItem {} { | |||
label Project | |||
@@ -779,7 +823,7 @@ ab.run();} | |||
} | |||
} | |||
Fl_Box {} { | |||
label {<Timeline>} | |||
label {<Timeline>} selected | |||
xywh {0 75 1025 692} box FLAT_BOX color 47 labeltype NO_LABEL labelsize 100 resizable | |||
code0 {timeline = o;} | |||
class Timeline | |||
@@ -1004,8 +1048,7 @@ if ( logo_box->image() ) | |||
((Fl_Shared_Image*)logo_box->image())->release(); | |||
logo_box->image( NULL ); | |||
}} open | |||
private xywh {1189 128 520 775} type Double | |||
modal visible | |||
private xywh {1193 174 520 775} type Double hide modal | |||
} { | |||
Fl_Value_Output {} { | |||
label {Sample Rate} | |||
@@ -95,6 +95,17 @@ src/main.C | |||
use = [ 'fl_widgets', 'nonlib'], | |||
install_path = '${BINDIR}') | |||
obj = bld(features = 'cxx cxxprogram', | |||
source='bin/import-ardour-session_gui.fl', | |||
target = 'import-ardour-session_gui', | |||
includes = ['.', 'src', '..', '../nonlib'], | |||
uselib = [ 'NTK', 'NTK_IMAGES', 'PTHREAD'], | |||
## use = [ 'fl_widgets', 'nonlib'], | |||
install_path = '${BINDIR}') | |||
bld.install_files('${BINDIR}', 'import-ardour-session', chmod=0555, | |||
cwd=bld.path.find_dir('bin'), relative_trick=True) | |||
bld( features = 'subst', | |||
source = 'non-timeline.desktop.in', | |||
target = 'non-timeline.desktop', | |||
@@ -102,6 +113,7 @@ src/main.C | |||
install_path = "${DATADIR}" + '/applications', | |||
BIN_PATH = bld.env.BINDIR ) | |||
bld.symlink_as( '${BINDIR}/' + 'non-daw', APPNAME ) | |||
start_dir = bld.path.find_dir( 'icons/hicolor' ) | |||