From 875ef1757530eb97e232874e68fbafe8083a5508 Mon Sep 17 00:00:00 2001 From: Jonathan Moore Liles Date: Tue, 30 Apr 2013 22:38:49 -0700 Subject: [PATCH] TImeline: Add GUI for Ardour session import and corresponding menu entry. --- timeline/bin/import-ardour-session | 61 ++++++++----- timeline/bin/import-ardour-session_gui.fl | 103 ++++++++++++++++++++++ timeline/src/TLE.fl | 55 ++++++++++-- timeline/wscript | 12 +++ 4 files changed, 203 insertions(+), 28 deletions(-) create mode 100644 timeline/bin/import-ardour-session_gui.fl diff --git a/timeline/bin/import-ardour-session b/timeline/bin/import-ardour-session index 6912713..b2813b6 100755 --- a/timeline/bin/import-ardour-session +++ b/timeline/bin/import-ardour-session @@ -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!" diff --git a/timeline/bin/import-ardour-session_gui.fl b/timeline/bin/import-ardour-session_gui.fl new file mode 100644 index 0000000..ad24c98 --- /dev/null +++ b/timeline/bin/import-ardour-session_gui.fl @@ -0,0 +1,103 @@ +# data file for the Fltk User Interface Designer (fluid) +version 1.0300 +header_name {.h} +code_name {.cxx} +decl {\#include } {private local +} + +decl {\#include } {private local +} + +decl {\#include } {private local +} + +decl {\#include } {private local +} + +decl {\#include } {private local +} + +decl {\#include } {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 + } + } + } +} diff --git a/timeline/src/TLE.fl b/timeline/src/TLE.fl index 06f4c3c..220ba7b 100644 --- a/timeline/src/TLE.fl +++ b/timeline/src/TLE.fl @@ -28,6 +28,15 @@ decl {const float STATUS_UPDATE_FREQ = 0.5f;} {private local decl {class Fl_Flowpack;} {public global } +decl {\#include } {private local +} + +decl {\#include } {private local +} + +decl {\#include } {private local +} + decl {\#include } {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 {} + label {} 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} diff --git a/timeline/wscript b/timeline/wscript index d64812a..3fecd55 100644 --- a/timeline/wscript +++ b/timeline/wscript @@ -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' )