| @@ -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' ) | |||