Added the session resampler which now should work for 2.0 sessions and
[ardour.git] / tools / resample_session.pl
1 #!/usr/bin/env perl
2 # Ardour session resampler, version 0.1
3 # (c)Sampo Savolainen 2005-2007
4 #
5 # Licensed under the GPL 
6 #
7 # Copies the session to another directory and changes it's sampling rate in all respects.
8 # The frames in .ardour and .automation files are converted according to the conversion ration.
9 # The peakfiles and dead_sounds aren't copied. Only "identified" files are copied, instant.xml's
10 # or .bak's aren't copied either.
11
12 use XML::Parser::PerlSAX;
13 use XML::Handler::XMLWriter;
14 use IO::Handle;
15
16 use File::Basename;
17
18 use ARDOUR::SessionSRHandler;
19 # Let's hope this is never needed
20 #use ARDOUR::AutomationSRConverter;
21
22
23 if ( ! -f "/usr/bin/sndfile-resample" &&
24      ! -f "/usr/local/bin/sndfile-resample") {
25         print "You don't have sndfile-resample installed. This script will not work without it, please install it and try again\n";
26         exit;
27 }
28
29 my ($sourceDirectory, $destDirectory, $sourceSR, $destSR) = @ARGV;
30
31 if ((@ARGV+0) ne 4 ||
32     ($sourceSR+0) eq 0 ||
33         ($destSR+0)   eq 0) {
34         print "usage: ardour_sr.pl [ardour session directory] [destination directory] [original samplerate] [new samplerate]\n";
35         exit;
36 }
37
38 if ( ! -d $sourceDirectory) {
39         print $sourceDirectory.": directory does not exist!\n";
40         exit;
41 }
42
43 if ( -d $destDirectory) {
44         print $destDirectory.": directory exists!\n";
45         exit;
46 }
47
48 print "Checking source and destination directories\n";
49
50 my @sounds;
51 my @dead_sounds;
52 my @dot_ardour;
53 my @automation;
54
55
56 my $version_099x = 0;
57
58 # Read the names of all audio files in /sounds/
59 if ( -d $sourceDirectory."/sounds/") {
60         $version_099x = 1;
61
62         opendir(SOUNDS,$sourceDirectory."/sounds/") || die ($sourceDirectory.": not a valid session, no sounds/ directory");
63         while ( my $file=readdir(SOUNDS) ) {
64                 if ( -f $sourceDirectory."/sounds/".$file ) {
65                         push(@sounds,$file);
66                 }
67         }
68
69 } else {
70         my $dirname = $sourceDirectory."/interchange/".basename($sourceDirectory)."/audiofiles/";
71         opendir(SOUNDS,$dirname) || die ($sourceDirectory.": not a valid session, no sounds/ directory");
72         while ( my $file=readdir(SOUNDS) ) {
73                 if ( -f $dirname.$file ) {
74                         push(@sounds,$file);
75                 }
76         }
77
78 }
79 close(SOUNDS);
80
81 # Read the names of all audio files in /dead_sounds/
82 opendir(DEAD_SOUNDS,$sourceDirectory."/dead_sounds/") || die ($sourceDirectory.": not a valid session, no dead_sounds/ directory");
83 while ( my $file=readdir(DEAD_SOUNDS) ) {
84         if ( -f $sourceDirectory."/dead_sounds/".$file ) {
85                 push(@dead_sounds,$file);
86         }
87 }
88 close(DEAD_SOUNDS);
89
90 # Read the names of all .ardour files in /
91 opendir(DOT_ARDOUR,$sourceDirectory) || die ($sourceDirectory.": could not open!");
92 while ( my $file=readdir(DOT_ARDOUR) ) {
93         if ( -f $sourceDirectory."/".$file && 
94              index($file,".ardour") eq (length($file)-7)) {
95                 push(@dot_ardour,$file);
96         }
97 }
98 close(DOT_ARDOUR);
99
100 # Read the names of all automation files in /automation/
101 opendir(AUTOMATION,$sourceDirectory."/automation/") || die ($sourceDirectory."/automation: could not open!");
102 while ( my $file=readdir(AUTOMATION) ) {
103         if ( -f $sourceDirectory."/automation/".$file && 
104              index($file,".automation") eq (length($file)-11)) {
105                 push(@automation,$file);
106         }
107 }
108 close(AUTOMATION);
109
110 # Check for /peaks/
111 if ( ! -d $sourceDirectory."/peaks" ) {
112         print $sourceDirectory.": not a valid session, no peaks/ directory\n";
113         exit;
114 }
115
116 ##########################################
117 # Checks are done, let's go!
118
119 print "Converting session\n";
120 mkdir $destDirectory;
121
122
123 # Run all .ardour files through the SAX parser and write the results in the destination
124 # directory.
125
126 foreach my $xml (@dot_ardour) {
127         print "Doing samplerate conversion to ".$xml."...";
128         open(OUTFILE,">".$destDirectory."/".$xml);
129         my $output = new IO::Handle;
130         $output->fdopen(fileno(OUTFILE),"w");
131         
132         my $handler = ARDOUR::SessionSRHandler->new($sourceSR,$destSR,$output);
133
134         my $parser = XML::Parser::PerlSAX->new( Handler => $handler );
135
136     $parser->parse(Source => { SystemId => $sourceDirectory."/".$xml });
137
138         $output->close();
139         close(OUTFILE);
140         print " done\n";
141 }
142
143 # This code is needed for 0.99.x sessions, thus the code is still here.
144 #
145 #mkdir $destDirectory."/automation";
146 #
147 #foreach my $file (@automation) {
148 #       print "Converting automation file ".$file."...";
149 #       open(INFILE,$sourceDirectory."/automation/".$file) || die "could not open source automation file $file!";
150 #       open(OUTFILE,">".$destDirectory."/automation/".$file) || die "could not open destination automation file $file!";
151 #       my $input=new IO::Handle;
152 #       my $output=new IO::Handle;
153 #
154 #       $input->fdopen(fileno(INFILE),"r");
155 #       $output->fdopen(fileno(OUTFILE),"w");
156 #
157 #       my $converter = ARDOUR::AutomationSRConverter->new($input,$output,$sourceSR,$destSR);
158 #       $converter->convert;
159 #
160 #       $input->close;
161 #       $output->close;
162 #       close(INFILE);
163 #       close(OUTFILE);
164 #       print " done\n";
165 #}
166
167
168 if ($version_099x eq 1) {
169         mkdir $destDirectory."/sounds";
170         foreach my $sound (@sounds) {
171                 my @params=("-to", $destSR,
172                             "-c",  "0",
173                             $sourceDirectory."/sounds/".$sound,
174                             $destDirectory."/sounds/".$sound);
175                 system("sndfile-resample",@params);
176         }
177 } else {
178         my $srcSndDir = $sourceDirectory."/interchange/".basename($sourceDirectory)."/audiofiles/";
179         
180         my $dstSndDir = $destDirectory."/interchange/";
181         mkdir $dstSndDir;
182
183         $dstSndDir .= basename($sourceDirectory)."/";
184         mkdir $dstSndDir;
185
186         $dstSndDir .= "audiofiles/";
187         mkdir $dstSndDir;
188         
189         foreach my $sound (@sounds) {
190                 my @params=("-to", $destSR,
191                             "-c",  "0",
192                             $srcSndDir."/".$sound,
193                             $dstSndDir."/".$sound);
194                 system("sndfile-resample",@params);
195         }
196 }
197
198 mkdir $destDirectory."/dead_sounds";
199 mkdir $destDirectory."/peaks";
200
201