@@ -23,21 +23,30 @@ import os | |||||
from datetime import date | from datetime import date | ||||
import shutil | 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]" | print "Usage: import-ardour-session [PATH_TO_ARDOUR_FILE] [NAME_OF_NON_TIMELINE_PROJECT]" | ||||
sys.exit( 1 ) | 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: | try: | ||||
os.makedirs( NonTimelineProjectPath ); | os.makedirs( NonTimelineProjectPath ); | ||||
os.makedirs( NonTimelineProjectPath + "/sources"); | os.makedirs( NonTimelineProjectPath + "/sources"); | ||||
except: | 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: | try: | ||||
tree = et.parse( ArdourFilePath ); | tree = et.parse( ArdourFilePath ); | ||||
@@ -62,15 +71,6 @@ ProjectName = root.attrib["name"] | |||||
print "Converting Ardour session \"" + ProjectName + "\" to Non Timeline format. Please be patient." | 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." | print "Gathering sources." | ||||
for node in root.findall( "./Sources/Source" ): | for node in root.findall( "./Sources/Source" ): | ||||
@@ -102,11 +102,13 @@ def NewID(): | |||||
return ID | return ID | ||||
History = "{\n" | |||||
print "Processing tempo." | print "Processing tempo." | ||||
for node in root.findall("./TempoMap/Tempo"): | for node in root.findall("./TempoMap/Tempo"): | ||||
TempoID = NewID() | 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"): | for node in root.findall("./TempoMap/Meter"): | ||||
TimeID = NewID() | TimeID = NewID() | ||||
@@ -115,7 +117,7 @@ for node in root.findall("./TempoMap/Meter"): | |||||
except: | except: | ||||
BPB = node.attrib["divisions-per-bar"] | 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." | print "Processing playlists." | ||||
@@ -143,8 +145,8 @@ for node in root.findall( "./Playlists/Playlist" ): | |||||
TrackName = Track.attrib["name"] | TrackName = Track.attrib["name"] | ||||
Channels = int(Track.attrib["channels"]) | 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"): | for n2 in node.findall("./Region"): | ||||
RegionID = NewID(); | RegionID = NewID(); | ||||
@@ -188,7 +190,7 @@ for node in root.findall( "./Playlists/Playlist" ): | |||||
NonTimelineProjectPath + "/sources/" ) | NonTimelineProjectPath + "/sources/" ) | ||||
History.write ("Audio_Region " + RegionID + | |||||
History += ("\tAudio_Region " + RegionID + | |||||
" create :source \"" + SourceName + | " create :source \"" + SourceName + | ||||
"\" :start " + n2.attrib["position"] + | "\" :start " + n2.attrib["position"] + | ||||
" :length " + n2.attrib["length"] + | " :length " + n2.attrib["length"] + | ||||
@@ -196,7 +198,22 @@ for node in root.findall( "./Playlists/Playlist" ): | |||||
" :sequence " + SequenceID + "\n") | " :sequence " + SequenceID + "\n") | ||||
else: | else: | ||||
print "\tSkipping inactive playlist" | 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!" | 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 {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 | 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 *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} | class TLE_Window {open : {public Fl_Overlay_Window} | ||||
@@ -252,7 +261,7 @@ Loggable::progress_callback( &TLE::progress_cb, this );} {} | |||||
label {Non Timeline} | label {Non Timeline} | ||||
callback {if ( Fl::event_key() != FL_Escape ) | callback {if ( Fl::event_key() != FL_Escape ) | ||||
timeline->command_quit();} open | 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 );} | code0 {o->xclass( APP_NAME );} | ||||
class TLE_Window size_range {900 300 0 0} visible | class TLE_Window size_range {900 300 0 0} visible | ||||
} { | } { | ||||
@@ -375,9 +384,44 @@ if ( n != 2 ) | |||||
Project::compact();} | Project::compact();} | ||||
xywh {25 25 40 25} | 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 {} { | Submenu {} { | ||||
label {&Export} open | label {&Export} open | ||||
xywh {5 5 74 25} deactivate | |||||
xywh {5 5 74 25} hide deactivate | |||||
} { | } { | ||||
MenuItem {} { | MenuItem {} { | ||||
label Project | label Project | ||||
@@ -779,7 +823,7 @@ ab.run();} | |||||
} | } | ||||
} | } | ||||
Fl_Box {} { | Fl_Box {} { | ||||
label {<Timeline>} | |||||
label {<Timeline>} selected | |||||
xywh {0 75 1025 692} box FLAT_BOX color 47 labeltype NO_LABEL labelsize 100 resizable | xywh {0 75 1025 692} box FLAT_BOX color 47 labeltype NO_LABEL labelsize 100 resizable | ||||
code0 {timeline = o;} | code0 {timeline = o;} | ||||
class Timeline | class Timeline | ||||
@@ -1004,8 +1048,7 @@ if ( logo_box->image() ) | |||||
((Fl_Shared_Image*)logo_box->image())->release(); | ((Fl_Shared_Image*)logo_box->image())->release(); | ||||
logo_box->image( NULL ); | logo_box->image( NULL ); | ||||
}} open | }} open | ||||
private xywh {1189 128 520 775} type Double | |||||
modal visible | |||||
private xywh {1193 174 520 775} type Double hide modal | |||||
} { | } { | ||||
Fl_Value_Output {} { | Fl_Value_Output {} { | ||||
label {Sample Rate} | label {Sample Rate} | ||||
@@ -95,6 +95,17 @@ src/main.C | |||||
use = [ 'fl_widgets', 'nonlib'], | use = [ 'fl_widgets', 'nonlib'], | ||||
install_path = '${BINDIR}') | 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', | bld( features = 'subst', | ||||
source = 'non-timeline.desktop.in', | source = 'non-timeline.desktop.in', | ||||
target = 'non-timeline.desktop', | target = 'non-timeline.desktop', | ||||
@@ -102,6 +113,7 @@ src/main.C | |||||
install_path = "${DATADIR}" + '/applications', | install_path = "${DATADIR}" + '/applications', | ||||
BIN_PATH = bld.env.BINDIR ) | BIN_PATH = bld.env.BINDIR ) | ||||
bld.symlink_as( '${BINDIR}/' + 'non-daw', APPNAME ) | bld.symlink_as( '${BINDIR}/' + 'non-daw', APPNAME ) | ||||
start_dir = bld.path.find_dir( 'icons/hicolor' ) | start_dir = bld.path.find_dir( 'icons/hicolor' ) | ||||