summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSampo Savolainen <v2@iki.fi>2007-04-15 20:47:21 +0000
committerSampo Savolainen <v2@iki.fi>2007-04-15 20:47:21 +0000
commitfbdd0ab815e7829db93bc27f8c6e508b7da94921 (patch)
tree06aab11aadecdf01e29070ca5166e882ec134e29
parent0e8e5ddd90a38f58328edf1cf07613917f406300 (diff)
Added the session resampler which now should work for 2.0 sessions and
almost work for 0.99 originated session (automation is not handled yet). Stopped the creation on the automation/ directory in new sessions as it's not used anymore git-svn-id: svn://localhost/ardour2/trunk@1725 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--libs/ardour/session_state.cc7
-rw-r--r--tools/ARDOUR/AutomationSRConverter.pm61
-rw-r--r--tools/ARDOUR/SessionSRHandler.pm120
-rwxr-xr-xtools/resample_session.pl201
4 files changed, 382 insertions, 7 deletions
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index 119d2c858d..d3bf70a2dd 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -487,13 +487,6 @@ Session::create (bool& new_session, string* mix_template, nframes_t initial_leng
return -1;
}
- dir = automation_dir ();
-
- if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
- error << string_compose(_("Session: cannot create session automation dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
- return -1;
- }
-
dir = export_dir ();
if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
diff --git a/tools/ARDOUR/AutomationSRConverter.pm b/tools/ARDOUR/AutomationSRConverter.pm
new file mode 100644
index 0000000000..afd8f6c702
--- /dev/null
+++ b/tools/ARDOUR/AutomationSRConverter.pm
@@ -0,0 +1,61 @@
+package ARDOUR::AutomationSRConverter;
+
+sub new {
+ my ($type, $input, $output, $inputSR, $outputSR) = @_;
+
+ my $self = bless {}, $type;
+
+ $self->{Input} = $input;
+ $self->{Output} = $output;
+ $self->{Ratio} = ($outputSR+0) / ($inputSR+0);
+
+ return $self;
+}
+
+sub readline {
+ my ($self) = @_;
+
+ my $buf;
+ my $c='';
+
+ do {
+ $buf.=$c;
+ $c=$self->{Input}->getc;
+ } while ($c ne '' && $c ne "\n");
+
+ return $buf;
+}
+
+sub writeline {
+ my ($self, $line) = @_;
+
+ $self->{Output}->print($line."\n");
+}
+
+sub convert {
+ my ($self) = @_;
+
+ my $version=$self->readline;
+
+ if ($version ne "version 1") {
+ die ("Unsupported automation version $version");
+ }
+
+ $self->writeline($version);
+
+ my $buf = $self->readline;
+ while ( $buf ne "" ) {
+ if ( $buf eq "begin" ||
+ $buf eq "end") {
+ $self->writeline($buf);
+ } else {
+ my ($type, $position, $value) = split(' ', $buf);
+
+ $self->writeline($type." ".sprintf("%.0f",$position*$self->{Ratio})." ".$value);
+ }
+
+ $buf = $self->readline;
+ }
+}
+
+1;
diff --git a/tools/ARDOUR/SessionSRHandler.pm b/tools/ARDOUR/SessionSRHandler.pm
new file mode 100644
index 0000000000..8bfe665aca
--- /dev/null
+++ b/tools/ARDOUR/SessionSRHandler.pm
@@ -0,0 +1,120 @@
+package ARDOUR::SessionSRHandler;
+
+
+use XML::Handler::XMLWriter;
+use POSIX qw(floor);
+
+@ISA = qw( XML::Handler::XMLWriter );
+
+$VERSION = 0.1;
+
+# This table maps the "names of XML elements" to lists of "names of attributes" which should
+# be converted according to the SR change.
+# TODO: The table is a bit dirty, i have to figure out how to do it cleanly
+my $conversion_table = {
+ "Location" => { "end" => 0, "start" => 0 },
+ "Region" => { "length" => 0, "start" => 0, "position" => 0, "sync-position" => 0 },
+ "Crossfade" => { "left" => 0, "right" => 0 }
+ };
+
+
+sub new {
+ my ($type, $original_sr, $new_sr, $output) = @_;
+
+ #my $self = XML::Handler::XMLWriter->new( { Output => $output } );
+
+ my $self = $type->SUPER::new( Output => $output );
+
+ $self->{Debug} = 0;
+ $self->{Ratio} = ($new_sr+0)/($original_sr+0);
+ $self->{OriginalSR} = $original_sr;
+ $self->{TargetSR} = $new_sr;
+ $self->{Output} = $output;
+
+ $self->{InEvents} = 0;
+
+ return $self;
+}
+
+sub start_element {
+ my $self = shift;
+ my $element = shift;
+
+ my $debug = $self->{Debug};
+
+ my $atts = $element->{Attributes};
+
+ my $convert_attributes = $conversion_table->{$element->{Name}};
+
+ foreach my $cAtt (keys %$convert_attributes) {
+ $atts->{$cAtt} = sprintf("%.0f", $atts->{$cAtt} * $self->{Ratio});
+ $debug = 0;
+ }
+
+ if ($debug eq 0) {
+ $self->SUPER::start_element($element, @_);
+ }
+
+ if ($element->{Name} eq "events") {
+ $self->{InEvents} = 1;
+ }
+}
+
+sub end_element {
+ my $self = shift;
+ my $element = shift;
+
+ if ($self->{Debug} eq 0) {
+ $self->SUPER::end_element($element,@_);
+ }
+
+ if ($element->{Name} eq "events") {
+ $self->{InEvents} = 0;
+ }
+}
+
+sub start_document {
+ my $self = shift;
+
+ $self->SUPER::start_document(@_);
+
+ $self->{Output}->print("<!-- Sample rate converted from $self->{OriginalSR}hz to $self->{TargetSR}hz -->\n");
+}
+
+sub end_document {
+ my $self = shift;
+
+ $self->SUPER::end_document(@_);
+}
+
+sub characters {
+ my $self = shift;
+ my $c = shift;
+
+ if ($self->{InEvents} > 0) {
+ my $converted = "";
+
+ foreach my $foo (split(' ',$c->{Data})) {
+ if ($self->{InEvents} eq 1) {
+ $converted .= floor($foo * $self->{Ratio})." ";
+ $self->{InEvents} = 2;
+ } else {
+ $converted .= $foo." ";
+ $self->{InEvents} = 1;
+ }
+ }
+
+ $c->{Data} = $converted;
+ }
+
+
+ if ($self->{Debug} eq 0) {
+ $self->SUPER::characters($c, @_);
+ }
+
+}
+
+1;
+
+
+
diff --git a/tools/resample_session.pl b/tools/resample_session.pl
new file mode 100755
index 0000000000..c6a390f480
--- /dev/null
+++ b/tools/resample_session.pl
@@ -0,0 +1,201 @@
+#!/usr/bin/env perl
+# Ardour session resampler, version 0.1
+# (c)Sampo Savolainen 2005-2007
+#
+# Licensed under the GPL
+#
+# Copies the session to another directory and changes it's sampling rate in all respects.
+# The frames in .ardour and .automation files are converted according to the conversion ration.
+# The peakfiles and dead_sounds aren't copied. Only "identified" files are copied, instant.xml's
+# or .bak's aren't copied either.
+
+use XML::Parser::PerlSAX;
+use XML::Handler::XMLWriter;
+use IO::Handle;
+
+use File::Basename;
+
+use ARDOUR::SessionSRHandler;
+# Let's hope this is never needed
+#use ARDOUR::AutomationSRConverter;
+
+
+if ( ! -f "/usr/bin/sndfile-resample" &&
+ ! -f "/usr/local/bin/sndfile-resample") {
+ print "You don't have sndfile-resample installed. This script will not work without it, please install it and try again\n";
+ exit;
+}
+
+my ($sourceDirectory, $destDirectory, $sourceSR, $destSR) = @ARGV;
+
+if ((@ARGV+0) ne 4 ||
+ ($sourceSR+0) eq 0 ||
+ ($destSR+0) eq 0) {
+ print "usage: ardour_sr.pl [ardour session directory] [destination directory] [original samplerate] [new samplerate]\n";
+ exit;
+}
+
+if ( ! -d $sourceDirectory) {
+ print $sourceDirectory.": directory does not exist!\n";
+ exit;
+}
+
+if ( -d $destDirectory) {
+ print $destDirectory.": directory exists!\n";
+ exit;
+}
+
+print "Checking source and destination directories\n";
+
+my @sounds;
+my @dead_sounds;
+my @dot_ardour;
+my @automation;
+
+
+my $version_099x = 0;
+
+# Read the names of all audio files in /sounds/
+if ( -d $sourceDirectory."/sounds/") {
+ $version_099x = 1;
+
+ opendir(SOUNDS,$sourceDirectory."/sounds/") || die ($sourceDirectory.": not a valid session, no sounds/ directory");
+ while ( my $file=readdir(SOUNDS) ) {
+ if ( -f $sourceDirectory."/sounds/".$file ) {
+ push(@sounds,$file);
+ }
+ }
+
+} else {
+ my $dirname = $sourceDirectory."/interchange/".basename($sourceDirectory)."/audiofiles/";
+ opendir(SOUNDS,$dirname) || die ($sourceDirectory.": not a valid session, no sounds/ directory");
+ while ( my $file=readdir(SOUNDS) ) {
+ if ( -f $dirname.$file ) {
+ push(@sounds,$file);
+ }
+ }
+
+}
+close(SOUNDS);
+
+# Read the names of all audio files in /dead_sounds/
+opendir(DEAD_SOUNDS,$sourceDirectory."/dead_sounds/") || die ($sourceDirectory.": not a valid session, no dead_sounds/ directory");
+while ( my $file=readdir(DEAD_SOUNDS) ) {
+ if ( -f $sourceDirectory."/dead_sounds/".$file ) {
+ push(@dead_sounds,$file);
+ }
+}
+close(DEAD_SOUNDS);
+
+# Read the names of all .ardour files in /
+opendir(DOT_ARDOUR,$sourceDirectory) || die ($sourceDirectory.": could not open!");
+while ( my $file=readdir(DOT_ARDOUR) ) {
+ if ( -f $sourceDirectory."/".$file &&
+ index($file,".ardour") eq (length($file)-7)) {
+ push(@dot_ardour,$file);
+ }
+}
+close(DOT_ARDOUR);
+
+# Read the names of all automation files in /automation/
+opendir(AUTOMATION,$sourceDirectory."/automation/") || die ($sourceDirectory."/automation: could not open!");
+while ( my $file=readdir(AUTOMATION) ) {
+ if ( -f $sourceDirectory."/automation/".$file &&
+ index($file,".automation") eq (length($file)-11)) {
+ push(@automation,$file);
+ }
+}
+close(AUTOMATION);
+
+# Check for /peaks/
+if ( ! -d $sourceDirectory."/peaks" ) {
+ print $sourceDirectory.": not a valid session, no peaks/ directory\n";
+ exit;
+}
+
+##########################################
+# Checks are done, let's go!
+
+print "Converting session\n";
+mkdir $destDirectory;
+
+
+# Run all .ardour files through the SAX parser and write the results in the destination
+# directory.
+
+foreach my $xml (@dot_ardour) {
+ print "Doing samplerate conversion to ".$xml."...";
+ open(OUTFILE,">".$destDirectory."/".$xml);
+ my $output = new IO::Handle;
+ $output->fdopen(fileno(OUTFILE),"w");
+
+ my $handler = ARDOUR::SessionSRHandler->new($sourceSR,$destSR,$output);
+
+ my $parser = XML::Parser::PerlSAX->new( Handler => $handler );
+
+ $parser->parse(Source => { SystemId => $sourceDirectory."/".$xml });
+
+ $output->close();
+ close(OUTFILE);
+ print " done\n";
+}
+
+# This code is needed for 0.99.x sessions, thus the code is still here.
+#
+#mkdir $destDirectory."/automation";
+#
+#foreach my $file (@automation) {
+# print "Converting automation file ".$file."...";
+# open(INFILE,$sourceDirectory."/automation/".$file) || die "could not open source automation file $file!";
+# open(OUTFILE,">".$destDirectory."/automation/".$file) || die "could not open destination automation file $file!";
+# my $input=new IO::Handle;
+# my $output=new IO::Handle;
+#
+# $input->fdopen(fileno(INFILE),"r");
+# $output->fdopen(fileno(OUTFILE),"w");
+#
+# my $converter = ARDOUR::AutomationSRConverter->new($input,$output,$sourceSR,$destSR);
+# $converter->convert;
+#
+# $input->close;
+# $output->close;
+# close(INFILE);
+# close(OUTFILE);
+# print " done\n";
+#}
+
+
+if ($version_099x eq 1) {
+ mkdir $destDirectory."/sounds";
+ foreach my $sound (@sounds) {
+ my @params=("-to", $destSR,
+ "-c", "0",
+ $sourceDirectory."/sounds/".$sound,
+ $destDirectory."/sounds/".$sound);
+ system("sndfile-resample",@params);
+ }
+} else {
+ my $srcSndDir = $sourceDirectory."/interchange/".basename($sourceDirectory)."/audiofiles/";
+
+ my $dstSndDir = $destDirectory."/interchange/";
+ mkdir $dstSndDir;
+
+ $dstSndDir .= basename($sourceDirectory)."/";
+ mkdir $dstSndDir;
+
+ $dstSndDir .= "audiofiles/";
+ mkdir $dstSndDir;
+
+ foreach my $sound (@sounds) {
+ my @params=("-to", $destSR,
+ "-c", "0",
+ $srcSndDir."/".$sound,
+ $dstSndDir."/".$sound);
+ system("sndfile-resample",@params);
+ }
+}
+
+mkdir $destDirectory."/dead_sounds";
+mkdir $destDirectory."/peaks";
+
+